マネジメントコンソールを使うと、色々と自動でやってくれるので便利ではあるのですが、CLIで一つ一つ作成することで理解が深まると思います。
事前知識
シェルコマンドの実行結果を変数に代入する
変数=`コマンド`
実行例
[cloudshell-user@ip-10-0-113-58 ~]$ echo "Hello, World"
Hello, World
[cloudshell-user@ip-10-0-113-58 ~]$ message=`echo "Hello, World"`
[cloudshell-user@ip-10-0-113-58 ~]$ echo ${message}
Hello, World
[cloudshell-user@ip-10-0-113-58 ~]$
AWS CLIの--query
の使い方
--query
なし
aws ec2 describe-regions
出力例
{
"Regions": [
{
"Endpoint": "ec2.eu-north-1.amazonaws.com",
"RegionName": "eu-north-1",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.ap-south-1.amazonaws.com",
"RegionName": "ap-south-1",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.eu-west-3.amazonaws.com",
"RegionName": "eu-west-3",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.eu-west-2.amazonaws.com",
"RegionName": "eu-west-2",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.eu-west-1.amazonaws.com",
"RegionName": "eu-west-1",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.ap-northeast-3.amazonaws.com",
"RegionName": "ap-northeast-3",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.ap-northeast-2.amazonaws.com",
"RegionName": "ap-northeast-2",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.ap-northeast-1.amazonaws.com",
"RegionName": "ap-northeast-1",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.sa-east-1.amazonaws.com",
"RegionName": "sa-east-1",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.ca-central-1.amazonaws.com",
"RegionName": "ca-central-1",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.ap-southeast-1.amazonaws.com",
"RegionName": "ap-southeast-1",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.ap-southeast-2.amazonaws.com",
"RegionName": "ap-southeast-2",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.eu-central-1.amazonaws.com",
"RegionName": "eu-central-1",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.us-east-1.amazonaws.com",
"RegionName": "us-east-1",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.us-east-2.amazonaws.com",
"RegionName": "us-east-2",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.us-west-1.amazonaws.com",
"RegionName": "us-west-1",
"OptInStatus": "opt-in-not-required"
},
{
"Endpoint": "ec2.us-west-2.amazonaws.com",
"RegionName": "us-west-2",
"OptInStatus": "opt-in-not-required"
}
]
}
RegionName
がap-northeast-1
のものだけに限定
aws ec2 describe-regions \
--query "Regions[?RegionName == 'ap-northeast-1']"
出力例
[
{
"Endpoint": "ec2.ap-northeast-1.amazonaws.com",
"RegionName": "ap-northeast-1",
"OptInStatus": "opt-in-not-required"
}
]
RegionName
がap-northeast-1
のEndpoint
だけを取得
aws ec2 describe-regions \
--query "Regions[?RegionName == 'ap-northeast-1'].Endpoint | [0]" \
--output text
出力例
--output text
によってダブルクオートを外します。
ec2.ap-northeast-1.amazonaws.com
VPC
VPCを作成
VPCを作成します。
vpc_id=`aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=vpc}, {Key=test-id,Value=test}]' \
--query Vpc.VpcId \
--output text`
プライベートサブネットを作成
サブネットを作るとプライベートサブネットとして作成されます。
private_subnet_id=`aws ec2 create-subnet \
--vpc-id ${vpc_id} \
--cidr-block 10.0.1.0/24 \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-subnet}, {Key=test-id,Value=test}]' \
--query Subnet.SubnetId \
--output text`
後続の手順上、必須ではありませんが作成してみました。
パブリックサブネットを作成
サブネットを作っただけではパブリックサブネットにはなりませんので、いくつか対応が必要です。
- サブネットを作成
- インターネットゲートウェイを作成
- VPCにインターネットゲートウェイをアタッチ
- カスタムルートテーブルを作成
- カスタムルートを追加
- サブネットにカスタムルートを関連付け
- IPアドレスの自動割り当て有効化
サブネットを作成
プライベートサブネットと同じ要領で作成します。
public_subnet_id=`aws ec2 create-subnet \
--vpc-id ${vpc_id} \
--cidr-block 10.0.0.0/24 \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet}, {Key=test-id,Value=test}]' \
--query Subnet.SubnetId \
--output text`
インターネットゲートウェイを作成
インターネットゲートウェイを作成します。
internet_gateway_id=`aws ec2 create-internet-gateway \
--tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=igw}, {Key=test-id,Value=test}]' \
--query InternetGateway.InternetGatewayId \
--output text`
VPCにインターネットゲートウェイをアタッチ
aws ec2 attach-internet-gateway \
--vpc-id ${vpc_id} \
--internet-gateway-id ${internet_gateway_id}
インターネットゲートウェイはサブネットではなく VPC にアタッチします。
カスタムルートテーブルを作成
- メインルートテーブル
VPCを作成すると自動的にメインルートテーブルが作成され、カスタムルートテーブルを関連付けていないサブネットは、メインルートテーブルの設定に従ってルーティングされます。
ルートテーブルを確認します。
aws ec2 describe-route-tables \
--query "RouteTables[?VpcId == '${vpc_id}'].{RouteTableId: RouteTableId, Routes: Routes, Associations: Associations}" \
--output table
出力例
-----------------------------------------------------------------------
| DescribeRouteTables |
+---------------------------------------------------------------------+
| RouteTableId |
+---------------------------------------------------------------------+
| rtb-003ca71ad31ef5905 |
+---------------------------------------------------------------------+
|| AssociationsMain ||
|+-------------------------------------------------------------------+|
|| True ||
|+-------------------------------------------------------------------+|
|| Routes ||
|+-----------------------+------------+--------------------+---------+|
|| DestinationCidrBlock | GatewayId | Origin | State ||
|+-----------------------+------------+--------------------+---------+|
|| 10.0.0.0/16 | local | CreateRouteTable | active ||
|+-----------------------+------------+--------------------+---------+|
カスタムルートテーブルを作成します。
public_route_table_id=`aws ec2 create-route-table \
--vpc-id ${vpc_id} \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=rtb-public}, {Key=test-id,Value=test}]' \
--query RouteTable.RouteTableId \
--output text`
カスタムルートを作成
aws ec2 create-route \
--route-table-id ${public_route_table_id} \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id ${internet_gateway_id}
サブネットにカスタムルートを関連付け
aws ec2 associate-route-table \
--subnet-id ${public_subnet_id} \
--route-table-id ${public_route_table_id}
再度ルートテーブルを確認します。
aws ec2 describe-route-tables \
--query "RouteTables[?VpcId == '${vpc_id}'].{RouteTableId: RouteTableId, Routes: Routes, Associations: Associations}" \
--output table
出力例
------------------------------------------------------------------------------------------------
| DescribeRouteTables |
+----------------------------------------------------------------------------------------------+
| RouteTableId |
+----------------------------------------------------------------------------------------------+
| rtb-0592de70117fb7b99 |
+----------------------------------------------------------------------------------------------+
|| Associations ||
|+----------+--------------------------------------------+------------------------------------+|
|| Main | RouteTableAssociationId | RouteTableId ||
|+----------+--------------------------------------------+------------------------------------+|
|| True | rtbassoc-0e722bbcdf502afc3 | rtb-0592de70117fb7b99 ||
|+----------+--------------------------------------------+------------------------------------+|
||| AssociationState |||
||+----------------------------------+-------------------------------------------------------+||
||| State | associated |||
||+----------------------------------+-------------------------------------------------------+||
|| Routes ||
|+--------------------------------+-----------------+---------------------------+-------------+|
|| DestinationCidrBlock | GatewayId | Origin | State ||
|+--------------------------------+-----------------+---------------------------+-------------+|
|| 10.0.0.0/16 | local | CreateRouteTable | active ||
|+--------------------------------+-----------------+---------------------------+-------------+|
| DescribeRouteTables |
+----------------------------------------------------------------------------------------------+
| RouteTableId |
+----------------------------------------------------------------------------------------------+
| rtb-0723db61642f2892b |
+----------------------------------------------------------------------------------------------+
|| Associations ||
|+------+------------------------------+-------------------------+----------------------------+|
|| Main | RouteTableAssociationId | RouteTableId | SubnetId ||
|+------+------------------------------+-------------------------+----------------------------+|
||False | rtbassoc-0cee35b9612d14061 | rtb-0723db61642f2892b | subnet-0c575916b8ff55ec5 ||
|+------+------------------------------+-------------------------+----------------------------+|
||| AssociationState |||
||+----------------------------------+-------------------------------------------------------+||
||| State | associated |||
||+----------------------------------+-------------------------------------------------------+||
|| Routes ||
|+--------------------------+-----------------------------+-----------------------+-----------+|
|| DestinationCidrBlock | GatewayId | Origin | State ||
|+--------------------------+-----------------------------+-----------------------+-----------+|
|| 10.0.0.0/16 | local | CreateRouteTable | active ||
|| 0.0.0.0/0 | igw-01f367841e3ef93b9 | CreateRoute | active ||
|+--------------------------+-----------------------------+-----------------------+-----------+|
インターネットゲートウェイへのルートのあるルートテーブルが、パブリックサブネットに関連づいていることが確認できます。
少し手順が多いですが、これでパブリックサブネットが作成できました。
(オプション)IPアドレスの自動割り当て有効化
自動でパブリックIPを割り当てる設定を有効化します。
aws ec2 modify-subnet-attribute \
--subnet-id ${public_subnet_id} \
--map-public-ip-on-launch
サブネット単位での設定なので、プライベートサブネットには影響しません。
EC2
セキュリティグループを作成
セキュリティグループを作成します。
security_group_id=`aws ec2 create-security-group \
--group-name security-group --description "Security group" \
--vpc-id ${vpc_id} \
--query GroupId \
--output text`
セッションマネージャで接続する場合は、インバウンドールールは不要です。
(オプション)セキュリティグループのインバウンドルールを追加
今回の手順では必須ではありませんが、方法だけ紹介です。
セキュリティ的に良くない例となっていますのでご注意ください。
aws ec2 authorize-security-group-ingress \
--group-id ${security_group_id} \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0
インスタンスプロファイルを作成
EC2にロールを付与するためのインスタンスプロファイルを作成します。 Systems Managerのセッションマネージャの機能を使いたいので、以下の2つのポリシーを付与します。
- AmazonSSMManagedInstanceCore
- AmazonSSMPatchAssociation
IAMロールの作成
信頼関係のポリシードキュメントを作成します。
- role-trust-policy-for-ec2.json
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}
}
参考情報:ヒアドキュメントを使ったファイルの作成方法
cat <<EOF > role-trust-policy-for-ec2.json
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}
}
EOF
IAMロールを作成します。
aws iam create-role \
--role-name ec2-ssm-role \
--assume-role-policy-document file://role-trust-policy-for-ec2.json
IAMロールにポリシーをアタッチ
ロールにAWS管理ポリシーをアタッチします。
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore --role-name ec2-ssm-role
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonSSMPatchAssociation --role-name ec2-ssm-role
インスタンスプロファイルの作成
インスタンスプロファイルを作成します。
aws iam create-instance-profile \
--instance-profile-name ec2-ssm-instance-profile
インスタンスプロファイルにIAMロールを付与
aws iam add-role-to-instance-profile \
--instance-profile-name ec2-ssm-instance-profile \
--role-name ec2-ssm-role
インスタンスプロファイルを使用することで、EC2に対しての権限管理を行うことができます。EC2内にIAMユーザーの認証情報を保持する必要はありません。
EC2を起動する
いよいよEC2を起動します。
Amazon Linux2のAMI IDを検索
起動するAmazon LinuxのAMI IDを検索します。Systems Managerのパラメータストアに格納されているようです。
aws ssm get-parameters-by-path --path /aws/service/ami-amazon-linux-latest --query "Parameters[].Name"
出力例
[
"/aws/service/ami-amazon-linux-latest/al2022-ami-kernel-default-x86_64",
"/aws/service/ami-amazon-linux-latest/al2022-ami-minimal-kernel-5.15-x86_64",
"/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-ebs",
"/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-gp2",
"/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-s3",
"/aws/service/ami-amazon-linux-latest/amzn-ami-minimal-hvm-x86_64-s3",
"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-arm64-gp2",
"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs",
"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
"/aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-x86_64-ebs",
"/aws/service/ami-amazon-linux-latest/al2022-ami-kernel-5.15-x86_64",
"/aws/service/ami-amazon-linux-latest/al2022-ami-minimal-kernel-5.15-arm64",
"/aws/service/ami-amazon-linux-latest/al2022-ami-minimal-kernel-default-x86_64",
"/aws/service/ami-amazon-linux-latest/amzn-ami-minimal-hvm-x86_64-ebs",
"/aws/service/ami-amazon-linux-latest/amzn-ami-minimal-pv-x86_64-ebs",
"/aws/service/ami-amazon-linux-latest/amzn-ami-minimal-pv-x86_64-s3",
"/aws/service/ami-amazon-linux-latest/amzn-ami-pv-x86_64-s3",
"/aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-arm64-gp2",
"/aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-x86_64-gp2",
"/aws/service/ami-amazon-linux-latest/amzn2-ami-minimal-hvm-arm64-ebs",
"/aws/service/ami-amazon-linux-latest/al2022-ami-kernel-5.15-arm64",
"/aws/service/ami-amazon-linux-latest/al2022-ami-kernel-default-arm64",
"/aws/service/ami-amazon-linux-latest/al2022-ami-minimal-kernel-default-arm64",
"/aws/service/ami-amazon-linux-latest/amzn-ami-pv-x86_64-ebs",
"/aws/service/ami-amazon-linux-latest/amzn2-ami-minimal-hvm-x86_64-ebs"
]
マネジメントコンソールで新規作成する場合にデフォルトで選択されるAMIは/aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-x86_64-gp2
のようですのでこれを使用します。
EC2の起動
いよいよEC2の起動です。(作成と同時に起動します。)
- AMI:Amazon linux 2
- インスタンスタイプ:t2.micro
- EBS:20GB
instance_id=`aws ec2 run-instances \
--image-id resolve:ssm:/aws/service/ami-amazon-linux-latest/amzn2-ami-kernel-5.10-hvm-x86_64-gp2 \
--count 1 \
--instance-type t2.micro \
--security-group-ids ${securyty_group_id} \
--subnet-id ${public_subnet_id} \
--block-device-mappings "[{\"DeviceName\":\"/dev/xvda\",\"Ebs\":{\"VolumeSize\":20}}]" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=test}, {Key=test-id,Value=test}]' \
--iam-instance-profile Name=ec2-ssm-instance-profile \
--query "Instances[].InstanceId" \
--output text`
インスタンス起動後、マネジメントコンソールからセッションマネージャで接続できます。
EC2にセッションマネージャでアクセスできました!
プライベートサブネットでEC2を起動した場合はNATゲートウェイを配置するかVPCエンドポイントの作成が必要です。
EC2を操作するコマンド
- インスタンス停止
aws ec2 stop-instances --instance-ids ${instance_id}
- インスタンス起動
aws ec2 start-instances --instance-ids ${instance_id}
- インスタンス再起動
aws ec2 reboot-instances --instance-ids ${instance_id}
- インスタンス終了(インスタンスが削除されます)
aws ec2 terminate-instances --instance-ids ${instance_id}
参考サイト
https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-subnets-commands-example.html