AWS CLI勉強会資料~初心者向け、基礎のキ!~

記事タイトルとURLをコピーする

こんにちは、技術4課の城です。
今回は社内勉強会にてAWS CLIの初心者向けハンズオンをやってみようと思い、このブログを書いています。

さっそくですが、AWS CLIとはコマンドラインを使ってAWSサービスを操作できるツールです。
初心者向けの内容になっていますので、普段マネジメントコンソールでしか触ったことないという方も気軽にやってみましょう!!

前提条件

下記を前提にハンズオンを進めます。

  • AWSアカウントを利用可能(Administrator権限)
  • デフォルトVPC(172.31.0.0/16)及び、デフォルトサブネット(172.31.0.0/20)が存在する
  • bash環境
  • AWS CLIがインストール済み
  • 黒画面を恐れない心

AWS CLIのインストールについては下記URLをご参照ください。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/installing.html
AmazonLinux2を利用すると、デフォルトでインストールされているのでお勧めです。

概要

今回は基礎のキ!ということで、ボリュームは少なめです。
①スイッチロール用IAMユーザーの作成(マネジメントコンソール)
②構築用IAMロールの作成(マネジメントコンソール)
③AWS CLIの設定
④EC2インスタンスの作成(AWS CLI)

スイッチロール用IAMユーザーの作成、及び、構築用IAMロールの作成(マネジメントコンソール)

本項については、こちらのブログの次の内容をご参照ください。

1.IAMユーザーを作る
2.IAMユーザーにSwich Roleの権限だけを与える
3.実際の作業をする時の権限を持ったIAM Roleを作る

これを下記の設定内容で実施します。

  • IAMユーザー名:handson-user
  • IAMユーザーにアタッチするポリシー
{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam::【アカウントID】:role/handson-admin"
    }
}
  • IAMロール名:handson-admin
  • IAMロールのアクセス権限:AdministratorAccess

AWS CLIの設定

名前付きプロファイルを利用して、IAMユーザーの認証情報の登録、及び、スイッチロールの設定を行います。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-getting-started.html

名前付きプロファイルとは

名前付きプロファイルを利用することで複数の認証情報を登録することが可能になります。
異なるアカウントの認証情報や異なる権限の認証情報を各プロファイルに登録することができます。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-multiple-profiles.html

今回はIAMユーザー用のプロファイル、IAMロール用のプロファイルを利用します。

IAMユーザーの認証情報の登録

aws configureコマンドを利用してIAMユーザーの認証情報を登録します。
今回は --profileオプションを利用して名前付きプロファイルを作成します。
東京リージョンを利用するので Default region nameap-northeast-1とします。
Default output formatjsonとします。

aws configure --profile handson-user

AWS Access Key ID [None]: 【作成したIAMユーザーのアクセスキー】
AWS Secret Access Key [None]: 【作成したIAMユーザーのシークレットアクセスキー】
Default region name [None]: ap-northeast-1
Default output format [None]: json

スイッチロールの設定

スイッチロールの設定として、名前付きプロファイル handson-adminを作成します。
こちらは ~/.aws/configに設定を記載します。

cat << ETX >> ~/.aws/config
[profile handson-admin]
output = json
region = ap-northeast-1
role_arn = arn:aws:iam::【アカウントID】:role/handson-admin
source_profile = handson-user
ETX

確認

プロファイルを正しく設定できているか確認します。

プロファイル handson-userだと参照できない状態が正となります。
【コマンド】

aws iam get-role --role-name handson-admin --profile handson-user

【結果】

An error occurred (AccessDenied) when calling the GetUser operation: User: arn:aws:iam::【アカウントID】:user/handson-user is not authorized to perform: iam:GetUser on resource: user handson-user

プロファイル handson-adminだと参照可能です。
【コマンド】

aws iam get-role --role-name handson-admin --profile handson-admin

【結果】

{
    "Role": {
        "MaxSessionDuration": 3600,
        "RoleId": "AROAJNGSFFVUET3HF2QEK",
        "CreateDate": "2018-07-14T14:02:09Z",
        "Arn": "arn:aws:iam::【アカウントID】:role/handson-admin",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Condition": {},
                    "Principal": {
                        "AWS": "arn:aws:iam::【アカウントID】:root"
                    },
                    "Effect": "Allow"
                }
            ]
        },
        "Path": "/",
        "RoleName": "handson-admin"
    }
}

EC2インスタンスの作成(AWS CLI)

今回はデフォルトVPCにEC2インスタンス(webサーバー)を1台構築してみます。

プロファイルの変更

環境変数に設定することで対象のプロファイルをデフォルト設定として利用することができ、 --profileオプションを省略することが可能です。

export AWS_DEFAULT_PROFILE='handson-admin'

VPCの指定

既存のVPCに割り当てられているCIDRブロックを確認

デフォルトVPC(172.31.0.0/16)が存在することを確認します。 【コマンド】

aws ec2 describe-vpcs \
  --query 'Vpcs[].CidrBlock'

【結果例】

[
    "172.31.0.0/16",
    "***.***.***.***/**"
]

変数の設定

デフォルトVPCのIPセグメント(172.31.0.0/16)を設定

【コマンド】

VPC_CIDR='172.31.0.0/16'

VPC IDの取得

【コマンド】

VPC_ID=$( \
  aws ec2 describe-vpcs \
    --filters Name=cidr,Values=${VPC_CIDR} \
    --query 'Vpcs[].VpcId' \
    --output text \
) \
&& echo ${VPC_ID}

【結果例】

vpc-********

Security Groupの作成

Security Group名の指定

【コマンド】

VPC_SG_NAME='handson-sg'

Security Groupの説明の指定

【コマンド】

VPC_SG_DESC='security group for web server'

Security Groupの不存在確認

【コマンド】

aws ec2 describe-security-groups \
  --filters "Name=group-name,Values=${VPC_SG_NAME}"

【結果例】

{
    "SecurityGroups": []
}

変数の確認

【コマンド】

cat << ETX

  VPC_SG_NAME:  ${VPC_SG_NAME}
  VPC_SG_DESC: "${VPC_SG_DESC}"
  VPC_ID:       ${VPC_ID}

ETX

【結果例】

  VPC_SG_NAME:  handson-sg
  VPC_SG_DESC: "security group for web server"
  VPC_ID:       vpc-********

Security Groupの作成

【コマンド】

aws ec2 create-security-group \
  --group-name ${VPC_SG_NAME} \
  --description "${VPC_SG_DESC}" \
  --vpc-id ${VPC_ID}

【結果例】

{
    "GroupId": "sg-*******"
}

Security Group IDの取得

【コマンド】

VPC_SG_ID=$( \
  aws ec2 describe-security-groups \
    --filter Name=group-name,Values=${VPC_SG_NAME} \
    --query "SecurityGroups[].GroupId" \
    --output text \
) \
&& echo ${VPC_SG_ID}

【結果例】

sg-********

確認

【コマンド】

aws ec2 describe-security-groups \
  --group-ids ${VPC_SG_ID}

【結果例】

{
    "SecurityGroups": [
  {
      "IpPermissionsEgress": [
    {
        "IpProtocol": "-1",
        "PrefixListIds": [],
        "IpRanges": [
      {
          "CidrIp": "0.0.0.0/0"
      }
        ],
        "UserIdGroupPairs": [],
        "Ipv6Ranges": []
    }
      ],
      "Description": "security group for web server",
      "IpPermissions": [],
      "GroupName": "handson-sg",
      "VpcId": "vpc-********",
      "OwnerId": "************",
      "GroupId": "sg-********"
  }
    ]
}

外部からのHTTP接続のためのルールをセキュリティグループに追加

【コマンド】

aws ec2 authorize-security-group-ingress \
  --group-id ${VPC_SG_ID} \
  --protocol 'tcp' \
  --port 80 \
  --cidr 0.0.0.0/0

【結果例】

戻り値なし

確認

【コマンド】

aws ec2 describe-security-groups \
  --group-ids ${VPC_SG_ID} \
  --query "SecurityGroups[].IpPermissions"

【結果例】

[
    [
  {
      "PrefixListIds": [],
      "FromPort": 80,
      "IpRanges": [
    {
        "CidrIp": "0.0.0.0/0"
    }
      ],
      "ToPort": 80,
      "IpProtocol": "tcp",
      "UserIdGroupPairs": [],
      "Ipv6Ranges": []
  }
    ]
]

サブネットの指定

サブネットCIDRの指定

【コマンド】

VPC_SUBNET_CIDR='172.31.0.0/20'

サブネットIDの取得

【コマンド】

VPC_SUBNET_ID=$( \
  aws ec2 describe-subnets \
    --filters Name=cidrBlock,Values=${VPC_SUBNET_CIDR} \
    --query 'Subnets[].SubnetId' \
    --output text \
) \
&& echo ${VPC_SUBNET_ID}

【結果例】

subnet-********

ユーザーデータの作成

ユーザデータ用ファイル格納ディレクトリ作成

【コマンド】

mkdir userdata

ユーザデータ用ファイル名の指定

【コマンド】

FILE_INPUT="userdata/handson_ec2.bash"

ユーザデータ用ファイルの作成

【コマンド】

cat << ETX > ${FILE_INPUT}
#!/bin/bash
yum -y update
yum -y install httpd
systemctl start httpd.service
systemctl enable httpd.service
echo 'Hello World!!' > /var/www/html/index.html

ETX

ユーザデータ用ファイルの確認

【コマンド】

cat ${FILE_INPUT}

【結果例】

##!/bin/bash
yum -y update
yum -y install httpd24
systemctl start httpd.service
systemctl enable httpd.service
echo 'Hello World!!' > /var/www/html/index.html

キーペアの作成

キーペア名を指定

【コマンド】

EC2_KEY_PAIR_NAME='handson_awscli'

同名のキーペアの不存在の確認

【コマンド】

aws ec2 describe-key-pairs \
  --key-names ${EC2_KEY_PAIR_NAME}

【結果例】

An error occurred (InvalidKeyPair.NotFound) when calling the DescribeKeyPairs operation: The key pair 'handson_awscli' does not exist

Keyファイル名の設定

【コマンド】

FILE_SSH_KEY="${HOME}/.ssh/${EC2_KEY_PAIR_NAME}.pem"

【結果例】

/home/****/.ssh/handson_awscli.pem

Keyファイルの不存在確認

同名のファイルが存在しないことを確認します。
【コマンド】

ls ${FILE_SSH_KEY}

変数の確認

【コマンド】

cat << ETX

  EC2_KEY_PAIR_NAME: ${EC2_KEY_PAIR_NAME}
  FILE_SSH_KEY:      ${FILE_SSH_KEY}

ETX

【結果例】

  EC2_KEY_PAIR_NAME: handson_awscli
  FILE_SSH_KEY:      /home/ec2-user/.ssh/handson_awscli.pem

キーペアの作成

【コマンド】

aws ec2 create-key-pair \
  --key-name ${EC2_KEY_PAIR_NAME} \
  --query 'KeyMaterial' \
  --output text \
  > ${FILE_SSH_KEY} \
&& cat ${FILE_SSH_KEY} \
&& chmod 400 ${FILE_SSH_KEY}

最新のAmazon Linux2のAMI IDを取得

【コマンド】

EC2_IMAGE_ID=$( \
  aws ssm get-parameters \
    --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 \
    --region ap-northeast-1 \
    --query 'Parameters[].Value' \
    --output text \
) \
&& echo ${EC2_IMAGE_ID}

【結果例】

ami-e99f4896

インスタンスタイプの指定

【コマンド】

EC2_INSTANCE_TYPE='t2.micro'

変数の確認

【コマンド】

cat << ETX

  EC2_IMAGE_ID:        ${EC2_IMAGE_ID}
  EC2_INSTANCE_TYPE:   ${EC2_INSTANCE_TYPE}
  EC2_KEY_PAIR_NAME:   ${EC2_KEY_PAIR_NAME}
  VPC_SG_ID:           ${VPC_SG_ID}
  VPC_SUBNET_ID        ${VPC_SUBNET_ID}
  FILE_INPUT:          ${FILE_INPUT}

ETX

【結果例】

  EC2_IMAGE_ID:        ami-e99f4896
  EC2_INSTANCE_TYPE:   t2.micro
  EC2_KEY_PAIR_NAME:   handson_awscli
  VPC_SG_ID:           sg-********
  VPC_SUBNET_ID        subnet-********
  FILE_INPUT:          userdata/handson_ec2.bash

インスタンスを起動

【コマンド】

aws ec2 run-instances \
  --image-id ${EC2_IMAGE_ID} \
  --instance-type ${EC2_INSTANCE_TYPE} \
  --security-group-ids ${VPC_SG_ID} \
  --key-name ${EC2_KEY_PAIR_NAME} \
  --subnet-id ${VPC_SUBNET_ID} \
  --associate-public-ip-address  \
  --user-data file://${FILE_INPUT}

【結果例】

長いので略

インスタンスIDの取得

【コマンド】

EC2_INSTANCE_ID=$( \
  aws ec2 describe-instances \
    --filter "Name=key-name,Values=${EC2_KEY_PAIR_NAME}" \
    --query 'Reservations[].Instances[].InstanceId' \
    --output text \
) \
&& echo ${EC2_INSTANCE_ID}

【結果】

i-*****************

ステータスの確認

【コマンド】

aws ec2 describe-instance-status \
  --instance-ids ${EC2_INSTANCE_ID} \
  --query 'InstanceStatuses[].InstanceState[].Name'

【結果】

[
    "running"
]

パブリックIPの取得

EC2_PUBLIC_IP=$( \
  aws ec2 describe-instances \
    --instance-ids ${EC2_INSTANCE_ID} \
    --query 'Reservations[].Instances[].PublicIpAddress' \
    --output text \
) \
&& echo ${EC2_PUBLIC_IP}

HTTPでアクセス確認

webサーバーとしてインスタンスが立ち上がっている事が確認できます。
【コマンド】

curl ${EC2_PUBLIC_IP}

【結果】

Hello World!!

最後に

いかがでしたでしょうか?
そもそもマネジメントコンソールで設定できない項目があったり、手順化が容易であったりと、使う方に応じたメリットがあるかと思います。
今までコマンドラインに触れる機会が少なかった方の、触っていただくきっかけにでもなれば幸いです。

城 航太 (記事一覧)

サイトリライアビリティエンジニアリング部・CSM課・課長

AWSへの移行、AWSアカウントセキュリティ、ネットワーク広く浅くといった感じです。最近はAmazon WorkSpacesやAmazon AppStream2.0が好きです。APN Ambassador 2019,2020