こんにちは、技術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 name
は ap-northeast-1
とします。
Default output format
は json
とします。
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!!
最後に
いかがでしたでしょうか?
そもそもマネジメントコンソールで設定できない項目があったり、手順化が容易であったりと、使う方に応じたメリットがあるかと思います。
今までコマンドラインに触れる機会が少なかった方の、触っていただくきっかけにでもなれば幸いです。
城 航太 (記事一覧)
営業部カスタマーサクセス課・課長
AWSへの移行、AWSアカウントセキュリティ、ネットワーク広く浅くといった感じです。最近はAmazon WorkSpacesやAmazon AppStream2.0が好きです。APN Ambassador 2019,2020