6/8(月)、JAWS-UG CLI専門支部 #156R EC2基礎(VPC)に参加しました。今回もハンズオンの感想と学んだコマンドについて書こうと思います。
目次
イベントページ
ハンズオンでやったこと
以下の通りです。事前準備として、Cloud9上にハンズオン環境を構築しました。 ハンズオンでは、Cloud9のターミナルでコマンド実行しました。
VPC(Virtual Private Cloud)とは
- EC2インスタンスを配置するための仮想ネットワーク
- VPCはリージョン単位のサービス
- 仮想データセンタというイメージ
- 1リージョンあたり5VPCまで作成可能
- 他の仮想ネットワークと完全に分離されている。そのため、VPC単体で使う分にはIPアドレスが重複しても問題ない。
- VPCどうしを接続したり、様々なネットワークと接続するケースが増えているので、その場合はアドレッシングを検討する必要はある。
サブネットはAZ単位のサービス
インターネットゲートウェイはインターネットの出入口
ルートテーブル
- サブネットのルーティングテーブル情報
- 1つのサブネットはルートテーブルを1つだけ関連付けることができる。
- マスタルートテーブルを使わずに、ルールごとにルートテーブルを作るのが一般的
セキュリティグループ
感想
コマンドを駆使してネットワーク構築をする感覚で面白かったです。VPCやEC2の構築をCLIで実施するケースは少ないかもしれませんが、どのような設定を入れて何がマネジメントコンソール裏で動いているのか確認できて良い経験になりました。
ハンズオンでやったこと
今回はボリュームが多いため、主要コマンドのみ触れていこうと思います。ハンズオン手順は、こちらを参照してください。
事前作業
1.VPCの構築
- VPCを作成するためには
create-vpc
コマンドを使います。--cidr-block
でCIDRを指定します。
aws ec2 create-vpc --cidr-block ${EC2_VPC_CIDR} \
aws ec2 create-tags \ --resources ${EC2_RESOURCE_ID} \ --tags "Key=${EC2_TAG_KEY},Value=${EC2_TAG_VALUE}"
- 作成したVPCの存在確認をするために、
describe-vpcs
コマンドを実行します。--filters
でタグキーとタグ値を指定します。--query
でVPCのタグ値を抜き出し、--output text
でテキスト表示します。
aws ec2 describe-vpcs \ --filters Name=tag:Name,Values=${EC2_VPC_TAG_NAME} \ --query 'Vpcs[].Tags[?Key == `Name`].Value' \ --output text
2.インターネットゲートウェイ(IGW)の作成
create-internet-gateway
コマンドでインターネットゲートウェイを作成します。
aws ec2 create-internet-gateway \
aws ec2 create-tags \ --resources ${EC2_RESOURCE_ID} \ --tags "Key=${EC2_TAG_KEY},Value=${EC2_TAG_VALUE}"
describe-internet-gateways
コマンドでIGWの存在確認をします。--filter
でタグキーとタグ値を指定します。- Tagの値を取得し、テキストで表示します。
aws ec2 describe-internet-gateways \ --filters Name=tag:Name,Values=${EC2_IGW_TAG_NAME} \ --query "InternetGateways[].Tags[].Value" \ --output text
3.IGWのアタッチ
EC2_VPC_ID=$( \ aws ec2 describe-vpcs \ --filters Name=tag:Name,Values=${EC2_VPC_TAG_NAME} \ --query 'Vpcs[].VpcId' \ --output text \ )
- IGW_IDを取得します。
descrive-internet-gateways
コマンドでIGW情報を取得し、InternetGatewayIdの値をテキスト表示します。
EC2_IGW_ID=$( \ aws ec2 describe-internet-gateways \ --filters Name=tag:Name,Values=${EC2_IGW_TAG_NAME} \ --query "InternetGateways[].InternetGatewayId" \ --output text \ )
- IGWをVPCにアタッチします。
aws ec2 attach-internet-gateway \ --internet-gateway-id ${EC2_IGW_ID} \ --vpc-id ${EC2_VPC_ID}
- VPCにIGWがアタッチされていることを確認します。
aws ec2 describe-internet-gateways \ --filters Name=tag:Name,Values=${EC2_IGW_TAG_NAME} \ --query "InternetGateways[].Attachments[?VpcId == \`${EC2_VPC_ID}\`].VpcId" \ --output text
4. ルートテーブルの作成
create-route-table
コマンドでルートテーブルを作成します。--vpc-id
でルートテーブルを作成するVPCを指定します。
aws ec2 create-route-table --vpc-id ${EC2_VPC_ID}
- 作成したルートテーブルにタグ付けをします。
--resources
でタグ付けするルートテーブルを指定します。--tags
でタグキーとその値を指定します。
aws ec2 create-tags --resources ${EC2_RESOURCE_ID} \ --tags "Key=${EC2_TAG_KEY},Value=${EC2_TAG_VALUE}"
describe-route-tables
コマンドでルートテーブルがVPC内に存在することを確認します。
aws ec2 describe-route-tables --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_ROUTE_TABLE_TAG_NAME} \ --query "RouteTables[].Tags[?Key == \`Name\`].Value" \ --output text
5. ルートの作成
create-route
コマンドでルートテーブルにルートを作成します。--route-table-id
でルートを作成するルートテーブルを指定します。--destination-cidr-block
で送信先CIDRを指定します。--gateway-id
でターゲットのIGWを指定します。
aws ec2 create-route \ --route-table-id ${EC2_ROUTE_TABLE_ID} \ --destination-cidr-block ${EC2_ROUTE_DEST_CIDR} \ --gateway-id ${EC2_IGW_ID}
describe-route-tables
コマンドを使って、ルートテーブルに指定したルートが存在することを確認します。--filter
でVPCとタグキー及びルートテーブルのタグ値を指定します。- 宛先CIDRが${EC2_ROUTE_DEST_CIDR}(ハンズオンでは、0.0.0.0/0)のルートがあるルートテーブルをテキストで出力します。
aws ec2 describe-route-tables \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_ROUTE_TABLE_TAG_NAME} \ --query "RouteTables[].Routes[?DestinationCidrBlock == \`${EC2_ROUTE_DEST_CIDR}\`].DestinationCidrBlock" \ --output text
- 送信先へのルートが指定のIGWに設定されていることを確認します。
aws ec2 describe-route-tables \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_ROUTE_TABLE_TAG_NAME} \ --query "RouteTables[].Routes[?DestinationCidrBlock == \`${EC2_ROUTE_DEST_CIDR}\`].GatewayId" \ --output text
6. サブネットの作成
create-subnet
コマンドでサブネットを作成します。--vpc-id
でサブネットを作成するVPCを指定します。--cidr-block
でサブネットのアドレスレンジを指定します。--availability-zone
でサブネットを作成するAZを指定します。
aws ec2 create-subnet \ --vpc-id ${EC2_VPC_ID} \ --cidr-block ${EC2_SUBNET_CIDR} \ --availability-zone ${EC2_AZ_NAME}
- サブネットのタグを作成するために
create-tags
コマンドを使います。- resources でEC2のリソースが必要だし、
aws ec2 create-tags \ --resources ${EC2_RESOURCE_ID} \ --tags "Key=${EC2_TAG_KEY},Value=${EC2_TAG_VALUE}"
⑥VPCに指定のサブネットが存在することを確認します。
describe-subnets
コマンドでサブネット情報を取得します。--filter
でVPCとタグキーとタグ値を指定します。
aws ec2 describe-subnets \ --filters Name=vpc-id,Values=${EC2_VPC_ID} \ Name=tag:Name,Values=${EC2_SUBNET_TAG_NAME} \ --query 'Subnets[].Tags[?Key == `Name`].Value' \ --output text
7. ルートテーブルとサブネットの関連付け
associate-route-table
コマンドを使ってルートテーブルとサブネットの関連付けをします。--subnet-id
で関連付けするサブネットを指定します。--route-table-id
で関連付けするルートテーブルを指定します。
aws ec2 associate-route-table \ --subnet-id ${EC2_SUBNET_ID} \ --route-table-id ${EC2_ROUTE_TABLE_ID}
- 指定のサブネットとルートテーブルが関連付いていることを確認します。
aws ec2 describe-route-tables \ --route-table-ids ${ARRAY_EC2_ROUTE_TABLE_IDS} \ --query "RouteTables[].Associations[?SubnetId == \`${EC2_SUBNET_ID}\`].RouteTableAssociationId" \ --output text
8. サブネット属性の有効化
modify-subnet-attribute
コマンドでサブネット属性の設定変更をします。--subnet--id
で設定変更するサブネットを指定します。--map-public-ip-on-launch
で「パブリック IPv4 アドレスの自動割り当て」を有効にします。
aws ec2 modify-subnet-attribute \ --subnet-id ${EC2_SUBNET_ID} \ --map-public-ip-on-launch
- サブネットのmap-public-ip-on-launch属性(パブリック IPv4 アドレスの自動割り当て)が有効(True)になっていることを確認します。
describe-subnets
コマンドを使います。--filter
でタグキーと値を指定します。- パブリック IPv4 アドレスの自動割り当てのステータスを取り出します。
EC2_SUBNET_ATTRIBUTE_MAP_PUBLIC_IP_ON_LAUNCH=$( \ aws ec2 describe-subnets \ --filters Name=tag:Name,Values=${EC2_SUBNET_TAG_NAME} \ --query 'Subnets[].MapPublicIpOnLaunch' \ --output text \ ) \ && echo ${EC2_SUBNET_ATTRIBUTE_MAP_PUBLIC_IP_ON_LAUNCH}
9. セキュリティグループの作成
create-security-group
コマンドでセキュリティグループを作成します。--group-name
でセキュリティグループ名を指定します。--description
でセキュリティグループの説明を指定します。--vpc-id
でセキュリティグループを作成するVPCを指定します。
aws ec2 create-security-group \ --group-name ${EC2_SECURITY_GROUP_NAME} \ --description "${EC2_SECURITY_GROUP_DESC}" \ --vpc-id ${EC2_VPC_ID}
describe-security-groups
コマンドで指定のVPCに指定のセキュリティグループ名のグループがある場合は、テキスト表示します。--filter
でVPC_IDとセキュリティグループ名を指定します。
aws ec2 describe-security-groups \ --filter Name=vpc-id,Values=${EC2_VPC_ID} \ Name=group-name,Values=${EC2_SECURITY_GROUP_NAME} \ --query 'SecurityGroups[].GroupName' \ --output text
10. セキュリティグループのIngressルール追加(TCP80の許可を追加)
authorize-security-groups-ingress
コマンドでルールを作成します。
aws ec2 authorize-security-group-ingress \ --group-id ${EC2_SECURITY_GROUP_ID} \ --protocol ${EC2_SECURITY_GROUP_PROTOCOL} \ --port ${EC2_SECURITY_GROUP_PORT} \ --cidr ${EC2_SECURITY_GROUP_CIDR}
aws ec2 describe-security-groups \ --filter Name=vpc-id,Values=${EC2_VPC_ID} \ Name=group-name,Values=${EC2_SECURITY_GROUP_NAME} \ Name=ip-permission.protocol,Values=${EC2_SECURITY_GROUP_PROTOCOL} \ Name=ip-permission.to-port,Values=${EC2_SECURITY_GROUP_PORT} \ Name=ip-permission.cidr,Values=${EC2_SECURITY_GROUP_CIDR} \ --query "SecurityGroups[].IpPermissions[?IpProtocol == \`${EC2_SECURITY_GROUP_PROTOCOL}\` \ && ToPort == \`${EC2_SECURITY_GROUP_PORT}\` \ && IpRanges[?CidrIp == \`${EC2_SECURITY_GROUP_CIDR}\`]].IpRanges[][].CidrIp" \ --output text
11.ユーザデータの作成
-ファイルのフルパスを変数[FILE_USER_DATA]に格納します。 - ${DIR_USER_DATA}にはユーザデータのディレクトリを事前に格納します。 - ${USER_DATA_NAME}にはユーザデータ名を事前に格納します。
FILE_USER_DATA="${DIR_USER_DATA}/${USER_DATA_NAME}.bash"
cat << EOF0 > ${FILE_USER_DATA} #!/bin/bash yum -y update EC2_METADATA_SECOND='600' EC2_METADATA_TOKEN=\$( \\ curl -s \\ -X PUT "http://169.254.169.254/latest/api/token" \\ -H "X-aws-ec2-metadata-token-ttl-seconds: \${EC2_METADATA_SECOND}" \\ ) EC2_METADATA_HEADER="X-aws-ec2-metadata-token: \${EC2_METADATA_TOKEN}" EC2_AZ_NAME=\$( \\ curl -s -H "\${EC2_METADATA_HEADER}" \\ http://169.254.169.254/latest/meta-data/placement/availability-zone \\ ) EC2_INSTANCE_ID=\$( \\ curl -s -H "\${EC2_METADATA_HEADER}" \\ http://169.254.169.254/latest/meta-data/instance-id \\ ) # setup httpd yum install -y httpd systemctl start httpd.service systemctl enable httpd.service # setup contents cat << EOF > /var/www/html/index.html <!DOCTYPE html> <title>AZ: \${EC2_AZ_NAME}</title> <h1>AZ: \${EC2_AZ_NAME}</h1> <p>ID: \${EC2_INSTANCE_ID}</p> EOF EOF0 cat ${FILE_USER_DATA}
12. EC2インスタンスの起動
run-instances
コマンドでEC2インスタンスを実行します。
aws ec2 run-instances \ --image-id ${EC2_IMAGE_ID} \ --instance-type ${EC2_INSTANCE_TYPE} \ --security-group-ids ${ARRAY_EC2_SECURITY_GROUP_IDS} \ --tag-specifications ${STRING_TAG_CONF} \ --subnet-id ${EC2_SUBNET_ID} \ --user-data file://${FILE_USER_DATA}
describe-instances
コマンドで、EC2インスタンスが存在することを確認します。
aws ec2 describe-instances \ --filters Name=tag-key,Values=Name \ Name=tag-value,Values=${EC2_INSTANCE_TAG_NAME} \ Name=instance-state-name,Values=running \ --query Reservations[].Instances[].Tags[].Value \ --output text
13.EC2インスタンスへのCLIブラウザアクセス
- EC2インスタンスのグローバルIPアドレスにcurlコマンドでアクセスします。
- ハンズオンでは${CURL_TARGET_URL}に事前にグローバルIPアドレスを格納しました。
curl ${CURL_TARGET_URL}
curl -LI -Ss -o /dev/null -w '%{http_code}\n' ${CURL_TARGET_URL}
14.EC2インスタンスの終了
aws ec2 terminate-instances \ --instance-ids ${ARRAY_EC2_INSTANCE_IDS}
describe-instances
コマンドで、ステータスが"running"のEC2インスタンスが存在しないことを確認します。
aws ec2 describe-instances \ --filters Name=tag-key,Values=Name \ Name=tag-value,Values=${EC2_INSTANCE_TAG_NAME} \ Name=instance-state-name,Values=running \ --query Reservations[].Instances[].Tags[].Value \ --output text
後始末
ハンズオン環境が不要になったら、ハンズオン手順の後始末1と2、Cloud9用ロールからのポリシーのデタッチを実施します。
- セキュリティグループのIngressルール削除
- セキュリティグループの削除
- ルートテーブルの更新
- サブネットの削除
- ルートテーブルの削除
- IGWのデタッチ
- IGWの削除
- VPCの破棄
- ハンズオン用ディレクトリの削除
- Cloud9用ロールからのポリシーのデタッチ
最後に
次回はEBS、その後はAMI、IAMに関するハンズオンが続きます。楽しみながらハンズオンと復習をしていこうと思います。
最後まで読んでいただきありがとうございました。