前回はCLIを利用してVPC・サブネットを構築しました。
今回は、作成したVPC・サブネット上に踏み台サーバー2台・WEBサーバー2台を構築していこうと思います。
構成の確認
まずは前回構築した部分を確認します。
前回は、172.31.0.0/21の範囲のVPC上に、パブリックサブネット・プライベートサブネットを2台ずつ構築しました。
VPCにはInternetGatewayを紐づけ、パブリックサブネット上にはNatGatewayを構築しています。
今回は、サブネットの上に踏み台サーバー(EC2)2台・WEBサーバー(EC2)2台を構築していきます。
踏み台サーバーには踏み台用の、WEBサーバーにはWEB用のセキュリティグループを紐づけます。
以前別記事にて、東京リージョン上にEC2を構築しました。東京リージョン状のEC2には、別記事でご紹介した手順を行いApacheをインストールし、テストページを配置しています。
今回は、東京リージョン上のWEBサーバー取得したAMIを元に、大阪リージョン上にWEBサーバーを作成します。
※AWSマネジメントコンソール上でのEC2の構築手順は、以前に別記事にて一連の流れをご紹介しています。
また、AWSCLIの使用方法についてはこちらの記事にまとめているため、今回は実行したコマンドを中心に手順を確認していきます。
構築
CloudShellの起動
CloudShellの起動
AWSコンソールにログイン後、コンソール左下の「CloudShell」のリンクを押下します。
ここからコマンドを実行していきます。
AMIの取得・コピー
東京リージョン上のEC2からAMIを取得
東京リージョン上で対象のEC2を検索する
・基本の構文
まずは、東京リージョン上でAMI取得対象のEC2を特定します。
aws ec2 describe-instances
参考:awscliコマンドリファレンス(create-vpc)
実行したコマンド
今回は「HTTS_DEMO_02」というタグをつけたEC2のAMIを取得するため、フィルターでNameタグの指定を入れています。
また、後続の作業をやりやすくするために、返り値から「InstanceID」の値を取り出してEC2_ID_apne1という変数に格納しています。
EC2_ID_apne1=$(aws --region ap-northeast-1 ec2 describe-instances --filters "Name=tag:Name,Values=HTTPS_DEMO_02" --query Reservations[].Instances[0].InstanceId --output text)
さらに、対象のEC2のNameタグを取得して、返り値を「AMI_NAME」という変数に格納します。
AMI_NAME=$(aws ec2 describe-images --filters "Name=tag:Name,Values=HTTPS_DEMO_02" --query Images[0].Tags[?key=='Name'].Value --output text)
下記コマンドを実行し、「EC2_ID_apne1」の中身を確認します。
echo $EC2_ID_apne1
下記コマンドを実行し、「AMI_NAME」を確認します。
echo $AMI_NAME
AMIの取得
先程指定したEC2に対してAMIを取得します。
基本の構文
aws ec2 create-image --instance-id <インスタンスID>
参考:awscliコマンドリファレンス(create-image)
実行したコマンド
先程検索したEC2のIDを指定してAMIを取得します。
後続の作業をやりやすくするために、返り値のImageIDを「WEB_AMI_ID_apne1」という変数に格納します。
WEB_AMI_ID_apne1=$(aws --region ap-northeast-1 ec2 create-image --instance-id $EC2_ID_apne1 --name $AMI_NAME --query ImageId --output text)
下記コマンドを実行し、「WEB_AMI_ID_apne1」を確認します。
echo $WEB_AMI_ID_apne1
AMIが取得できたことを確認する
先程取得したAMIが利用可能となったことを確認します。
基本の構文
aws ec2 describe-images --image-id <イメージID>
参考:awscliコマンドリファレンス(describe-images)
実行したコマンド
今回はAMIIDを指定して、AMI名・AMIの状態を取得します。
aws ec2 describe-images --region ap-northeast-1 --image-id $WEB_AMI_ID_apne1 --query 'Images[].{AMIName:Name,AMIState:State}' --output table
下記のような出力結果が帰ってきたら成功です。
-----------------------------------
| DescribeImages |
+-------------------+-------------+
| AMIName | AMIState |
+-------------------+-------------+
| HTTPS_DEMO_02 | available |
+-------------------+-------------+
東京リージョン上のAMIを大阪リージョンへコピーする
取得したAMIを大阪リージョンへコピーします。
基本の構文
ws ec2 copy-image --region <コピー先リージョン> --source-region <コピー元リージョン> --source-image-id <コピー元AMIのAMIID> --name <コピー先リージョンでのAMI名> --description <AMIの説明>
参考:awscliコマンドリファレンス(copy-image)
実行したコマンド
後続の作業をやりやすくするために、コマンドの返り値のImageIDを「WEB_AMI_ID_apne3」という変数に格納します。
WEB_AMI_ID_apne3=$(aws ec2 copy-image --region ap-northeast-3 --source-region ap-northeast-1 --source-image-id $WEB_AMI_ID_apne1 --name $AMI_NAME --description $AMI_NAME --query ImageId --output text)
下記コマンドを実行し、「WEB_AMI_ID_apne3」を確認します。
echo $WEB_AMI_ID_apne3
コピーしたAMIを確認する
作成したAMIが無事大阪リージョンへコピーされ、利用可能となっていることを確認します。
aws ec2 describe-images --region ap-northeast-3 --image-id $WEB_AMI_ID_apne3 --query 'Images[].{AMIName:Name,AMIState:State}' --output table
下記のような出力結果が返ってきたら成功です。
--------------------------------
| DescribeImages |
+----------------+-------------+
| AMIName | AMIState |
+----------------+-------------+
| HTTPS_DEMO_02 | available |
+----------------+-------------+
SecurityGroupを作成する
SecurityGroupの作成
EC2を作成する前に、EC2にアタッチするセキュリティグループを作成します。
今回は踏み台サーバー・WEBサーバー用に、2つのセキュリティグループを作成します。
基本の構文
aws ec2 create-security-group --group-name <SG名> --description "<説明>" --vpc-id <VPCのID>
参考:awscliコマンドリファレンス(create-security-group)
実行したコマンド
・踏み台用VPC
vpc-idには前回作成したVPCのIDを「VPC_ID」という変数に格納して指定しています。
また、後続の作業をやりやすくするために、返り値からSGのIDを取り出して「HTTPS_DEMO_BAT_SG」という変数に格納します。
HTTPS_DEMO_BAT_SG=$(aws ec2 create-security-group --group-name HTTPS_DEMO_BAT_SG --description "HTTPS_DEMO_BAT_SG" --vpc-id $VPC_ID --query GroupId --output text)
下記コマンドを実行し、SGのIDを確認します。
echo $HTTPS_DEMO_BAT_SG
・WEBサーバー用VPC
また、後続の作業をやりやすくするために、返り値からSGのIDを取り出して「HTTPS_DEMO_WEB_SG」という変数に格納します。
HTTPS_DEMO_WEB_SG=$(aws ec2 create-security-group --group-name HTTPS_DEMO_WEB_SG --description "HTTPS_DEMO_WEB_SG" --vpc-id $VPC_ID --query GroupId --output text)
SecurityGroupへのNameタグ追加
先程作成したSGへNameタグを追加します。
aws ec2 create-tags --resources $HTTPS_DEMO_BAT_SG --tags Key=Name,Value=HTTPS_DEMO_BAT_SG
aws ec2 create-tags --resources $HTTPS_DEMO_WEB_SG --tags Key=Name,Value=HTTPS_DEMO_WEB_SG
踏み台用SGへのインバウンドルール作成
踏み台サーバーへRDPやSSHを行えるよう、利用中の端末のグローバルIPをインバウンドルールで許可しておきます。
基本の構文
aws ec2 authorize-security-group-ingress \
--group-id <SGのID> \
--protocol <tcp/udp/icmp/icmpv6> \
--port <ポート番号> \
--cidr <許可したいIPアドレス>
参考:awscliコマンドリファレンス(authorize-security-group-ingress)
実行したコマンド
先程作成した踏み台用のSG($HTTPS_DEMO_BAT_SG)を指定してインバウンドルールを作成します。
まずはSSH(22番)の通信を許可します。
aws ec2 authorize-security-group-ingress \
--group-id $HTTPS_DEMO_BAT_SG \
--protocol tcp \
--port 22 \
--cidr ***.***.***.***/32
下記のような出力結果が返ってくれば成功です。
{
"Return": true,
"SecurityGroupRules": [
{
"SecurityGroupRuleId": "sgr-******************",
"GroupId": "sg-******************",
"GroupOwnerId": "916134420985",
"IsEgress": false,
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 22,
"CidrIpv4": "106.179.12.210/32",
"SecurityGroupRuleArn": "arn:aws:ec2:ap-northeast-3:***********:security-group-rule/***********"
}
]
}
RDP(3389)の通信も許可します。
aws ec2 authorize-security-group-ingress \
--group-id $HTTPS_DEMO_BAT_SG \
--protocol tcp \
--port 3389 \
--cidr ***.***.***.***/32
下記のような出力結果が返ってくれば成功です。
{
"Return": true,
"SecurityGroupRules": [
{
"SecurityGroupRuleId": "sgr-04fc091c234433ddc",
"GroupId": "sg-******************",
"GroupOwnerId": "916134420985",
"IsEgress": false,
"IpProtocol": "tcp",
"FromPort": 3389,
"ToPort": 3389,
"CidrIpv4": "106.179.12.210/32",
"SecurityGroupRuleArn": "arn:aws:ec2:ap-northeast-3:916134420985:security-group-rule/sgr-04fc091c234433ddc"
}
]
}
WEBサーバー用SGへのインバウンドルール作成
WEBサーバー用のSGには、踏み台用SGからのSSHとHTTP・HTTPS接続を許可します。
まずは22番のSSH接続を許可します。
aws ec2 authorize-security-group-ingress \
--group-id $HTTPS_DEMO_WEB_SG \
--protocol tcp \
--port 22 \
--source-group $HTTPS_DEMO_BAT_SG
443番のHTTPS接続を許可します。
aws ec2 authorize-security-group-ingress \
--group-id $HTTPS_DEMO_WEB_SG \
--protocol tcp \
--port 443 \
--source-group $HTTPS_DEMO_BAT_SG
80番のHTTP接続を許可します。
aws ec2 authorize-security-group-ingress \
--group-id $HTTPS_DEMO_WEB_SG \
--protocol tcp \
--port 80 \
--source-group $HTTPS_DEMO_BAT_SG
SGの設定確認
各SGのルールが正しく設定されていることを確認します。
基本の構文
aws ec2 describe-security-group-rules
参考:awscliコマンドリファレンス(describe-security-group-rules)
実行したコマンド
踏み台用SGの確認
まずは踏み台用SGに対してSGのルールを確認してみます。
aws ec2 describe-security-group-rules \
--filters "Name=group-id,Values=$HTTPS_DEMO_BAT_SG" \
--query "SecurityGroupRules[*].{IsEgress:IsEgress,FromPort:FromPort,CIDR:CidrIpv4,FROMSGID:ReferencedGroupInfo.GroupId}" \
--output table
下記のような出力結果が返ってくれば成功です。
「IsEgress」が「False」となっているものが、先ほど追加したインバウンドルールになっています。
-----------------------------------------------------------
| DescribeSecurityGroupRules |
+--------------------+-----------+-----------+------------+
| CIDR | FROMSGID | FromPort | IsEgress |
+--------------------+-----------+-----------+------------+
| ***.**.***.***/32 | None | 22 | False |
| ***.**.***.***/32 | None | 3389 | False |
| 0.0.0.0/0 | None | -1 | True |
+--------------------+-----------+-----------+------------+
WEB用SGに対しても同様に確認してみます。
aws ec2 describe-security-group-rules \
--filters "Name=group-id,Values=$HTTPS_DEMO_WEB_SG" \
--query "SecurityGroupRules[*].{IsEgress:IsEgress,FromPort:FromPort,CIDR:CidrIpv4,FROMSGID:ReferencedGroupInfo.GroupId}" \
--output table
下記のような出力結果が返ってくれば成功です。
「IsEgress」が「False」となっているものが、先ほど追加したインバウンドルールになっています。
WEBサーバー用SGではCIDR範囲ではなくSGIDにてインバウンドルールを追加しているため、「FROMSGID」の部分が出力されています。
---------------------------------------------------------------
| DescribeSecurityGroupRules |
+-----------+------------------------+-----------+------------+
| CIDR | FROMSGID | FromPort | IsEgress |
+-----------+------------------------+-----------+------------+
| 0.0.0.0/0| None | -1 | True |
| None | sg-***************** | 80 | False |
| None | sg-***************** | 22 | False |
| None | sg-***************** | 443 | False |
+-----------+------------------------+-----------+------------+
EC2の構築
キーペアの作成
EC2に接続するにはキーペアが必要となります。
そのため、EC2を構築する前に、EC2インスタンス用のキーペアを作成します。
基本の構文
aws ec2 create-key-pair --key-name <キーペア名> --key-type <キーペアのタイプ>
参考:awscliコマンドリファレンス(create-key-pair)
実行したコマンド
Linuxサーバー用のキーペア
Linuxサーバー用のキーペアのキータイプにはED25519を指定します。
※AmazonLinux2023では、ss-rsaが無効化されています。キータイプRSAのキーペアではデフォルト状態のAmazonLinux2023に接続できないのでご注意ください。
参考:AmazonLinux2023 デフォルトのSSHサーバー設定
キーペアを作成すると、返り値の「KeyMaterial」の部分にキーペアの秘密鍵の部分が出力されます。
そのため、「KeyMaterial」の内容を「HTTPS_DEMO_KEY_LINUX_OSAKA.pem」というファイルにリダイレクトします。
aws ec2 create-key-pair --key-name HTTPS_DEMO_KEY_LINUX_OSAKA --key-type ed25519 --query "KeyMaterial" --output text > HTTPS_DEMO_KEY_LINUX_OSAKA.pem
windowsサーバー用のキーペア
OSがWindowsのEC2は、キータイプED25519に対応していません。
そのため、Windows用のキーペアのキータイプにはRSAを指定します。
Linux用のキーペアと同様に、「HTTPS_DEMO_KEY_WINDOWS_OSAKA.pem」に返り値の「KeyMaterial」をリダイレクトさせます。
aws ec2 create-key-pair --key-name HTTPS_DEMO_KEY_WINDOWS_OSAKA --key-type rsa --query "KeyMaterial" --output text > HTTPS_DEMO_KEY_WINDOWS_OSAKA.pem
キーペアのダウンロード
キーペアの作成が完了したので、キーペアのファイルをダウンロードしておきます。
下記コマンドを実行し、ディレクトリの中身を表示します。
ls -la
下記のような感じで、「HTTPS_DEMO_KEY_WINDOWS_OSAKA.pem」「HTTPS_DEMO_KEY_LINUX_OSAKA.pem」の二つのファイルが存在することを確認します。
下記コマンドを実行し、現在のディレクトリ階層を確認しておきます。
pwd
現在のディレクトリ階層を控えておきます。
CloudShellの「アクション」ボタンを押下し、「ファイルのダウンロード」を選択します。
「個別のファイルパスに」に先ほど確認したファイルパスと、ダウンロードしたいファイル名を入力し、「ダウンロード」を押下します。
もう一つのキーペアも同様にダウンロードしておきます。
踏み台用EC2のAMIIDを検索する
踏み台サーバーのEC2には、WindowsとAmazonLinuxのパブリックイメージの中から、最新のバージョンの物を指定して使用します。
ssmパラメータストアを利用して、Windows・AmazonLinuxAMIの最新のものを検索することができます。
AmazonLinux2023のAMIを検索する
AmazonLinux2023の最新のAMIを検索し、AMIIDを変数に格納します。
LINUX_BAT_AMI=$(aws ssm get-parameters --names /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 --query 'Parameters[0].Value' --output text)
参考:Amazon Linux 1、Amazon Linux 2、および Amazon Linux 2023 の AMI パブリックパラメータを呼び出す
WindowsのAMIIDを検索する
WindowsServer2025の最新AMIを検索し、AMIIDを変数に格納します。
WINDOWS_BAT_AMI=$(aws ssm get-parameters --names "/aws/service/ami-windows-latest/Windows_Server-2025-English-Full-Base" --query "Parameters[0].Value" --output text)
参考:AMI 用の Windows Server パブリックパラメータを呼び出す
EC2を作成する
Linux踏み台サーバーの作成
Linuxの踏み台サーバーを作成します。
基本の構文
aws ec2 run-instances \
--image-id <AMIID> \
--count <インスタンス数> \
--instance-type <インスタンスタイプ> \
--key-name <キーペア名> \
--subnet-id <構築先サブネット> \
--associate-public-ip-address(パブリックサブネットIPを有効化する場合に付与) \
--private-ip-address <プライベートIPアドレス> \
--security-group-ids <SGのID> \
--block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"DeleteOnTermination":true}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=<Nameタグ>}]'
参考:awscliコマンドリファレンス(run-instances)
実行したコマンド
先程検索したAmazonLinuxのAMIを指定して、EC2を立ち上げます。
インスタンスタイプはt3.micro、キーペアにはLinux用のキーペアを指定しています。
サブネットはaz3aのパブリックサブネットを指定し、プライベートIPアドレスは「172.31.0.6」を指定します。
返り値から「InstanceId」の部分を変数に格納します。
LINUX_BASTION=$(aws ec2 run-instances \
--image-id $LINUX_BAT_AMI \
--count 1 \
--instance-type t3.micro \
--key-name HTTPS_DEMO_KEY_LINUX_OSAKA \
--subnet-id $HTTPS_DEMO_SUB_PUB3a \
--associate-public-ip-address \
--private-ip-address 172.31.0.5 \
--security-group-ids $HTTPS_DEMO_BAT_SG \
--block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"DeleteOnTermination":true}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=HTTPS_DEMO_BAT01}]' \
--query Instances[0].InstanceId --output text)
Windows踏み台サーバーの作成
同じ要領で、Windowsの踏み台サーバーも作成します。
AMIには先程検索したWindowsServer2025の最新AMIを指定します。
インスタンスタイプはt3.medium、キーペアにはWindows用のキーペアを指定しています。
サブネットはaz3aのパブリックサブネットを指定し、プライベートIPアドレスは「172.31.0.6」を指定します。
WindowsサーバーはルートデバイスとなるEBSのサイズが32GB以上必要となるため、ディスクサイズを50に指定しています。
WINDOWS_BASTION=$(aws ec2 run-instances \
--image-id $WINDOWS_BAT_AMI \
--count 1 \
--instance-type t3.medium \
--key-name HTTPS_DEMO_KEY_WINDOWS_OSAKA \
--subnet-id $HTTPS_DEMO_SUB_PUB3a \
--associate-public-ip-address \
--private-ip-address 172.31.0.6 \
--security-group-ids $HTTPS_DEMO_BAT_SG \
--block-device-mappings "DeviceName=/dev/sda1,Ebs={VolumeSize=50,DeleteOnTermination=true}" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=HTTPS_DEMO_BAT02}]' \
--query Instances[0].InstanceId --output text)
Windowsサーバーは、ログイン時にキーペアを指定してパスワードを復号化する必要があります。
下記コマンドを実行しパスワードを復号化し、手元に控えておきます。
aws ec2 get-password-data --instance-id $WINDOWS_BASTION --priv-launch-key HTTPS_DEMO_KEY_WINDOWS_OSAKA.pem --query PasswordData --output text
WEB1/2の作成
プライベートサブネット上にWEBサーバーを2台作成します。
AMIには、東京リージョンからコピーしてきたAMI($WEB_AMI_ID_apne3)を指定します。
WEB1は、AZ31のプライベートサブネットを指定します。
WEB_01=$(aws ec2 run-instances \
--image-id $WEB_AMI_ID_apne3 \
--count 1 \
--instance-type t3.micro \
--key-name HTTPS_DEMO_KEY_LINUX_OSAKA \
--subnet-id $HTTPS_DEMO_SUB_PRV3a \
--private-ip-address 172.31.1.5 \
--security-group-ids $HTTPS_DEMO_WEB_SG \
--block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"DeleteOnTermination":true}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=HTTPS_DEMO_WEB01}]' \
--query Instances[0].InstanceId --output text)
WEB2も同様に作成します。
WEB2は、AZ3cのプライベートサブネットを指定します。
WEB_02=$(aws ec2 run-instances \
--image-id $WEB_AMI_ID_apne3 \
--count 1 \
--instance-type t3.micro \
--key-name HTTPS_DEMO_KEY_LINUX_OSAKA \
--subnet-id $HTTPS_DEMO_SUB_PRV3c \
--private-ip-address 172.31.5.5 \
--security-group-ids $HTTPS_DEMO_WEB_SG \
--block-device-mappings '[{"DeviceName":"/dev/xvda","Ebs":{"DeleteOnTermination":true}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=HTTPS_DEMO_WEB02}]' \
--query Instances[0].InstanceId --output text)
これで、すべてのEC2を構築することができました。
Linux・Windowsの踏み台サーバーにログインし、SSH接続が行えることを確認します。
※接続手順については今回は割愛します。
Linuxからの接続手順はこちらをご参照ください。
Windowsからの接続手順はこちらをご参照ください。
今回ご紹介する手順は以上となります。
ここまでお読みくださりありがとうございました。