実験用の使い捨てEC2を建てたくなることが多々あるため、CloudFormationでデフォルトVPCにEC2を簡単に建てるメモ。
準備
CloudFomationのTemplateを用意する。
Templateでは以下のリソースを作成している。
InstanceProfileに紐づけるRoleの作成。ポリシーにはAmazonSSMManagedInstanceCOreを付与してSSM経由で接続できるようにする。
Outboundだけ許可するSG
KeyPair(後でSSMParameterStoreから鍵を取得する)
DockerインストールのUserDataを含んだLaunchTemplate(UserDataをコンソールから確認したいため)
EC2
ec2.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Create EC2 Instance
Parameters:
latestAmazonLinux2AmiId:
Type : AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
Resources:
Ec2Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Ec2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref Ec2Role
Ec2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: EC2SecurityGroup
# VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-Ec2SecurityGroup
Ec2SecurityGroupEgress:
Type: AWS::EC2::SecurityGroupEgress
Properties:
IpProtocol: -1
CidrIp: 0.0.0.0/0
GroupId: !GetAtt Ec2SecurityGroup.GroupId
Ec2SecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
IpProtocol: -1
CidrIp: 127.0.0.1/32
GroupId: !GetAtt Ec2SecurityGroup.GroupId
Ec2KeyPair:
Type: AWS::EC2::KeyPair
Properties:
KeyName: !Sub ${AWS::StackName}-KeyPair
Ec2LaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: !Sub ${AWS::StackName}-LaunchTemplate
LaunchTemplateData:
UserData:
Fn::Base64: |-
#!/bin/bash
yum update -y
amazon-linux-extras install docker -y
systemctl enable docker
systemctl start docker
usermod -aG docker ec2-user
curl -L --fail https://github.com/docker/compose/releases/download/1.29.2/run.sh -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
Ec2:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref latestAmazonLinux2AmiId
InstanceType: t2.micro
KeyName: !Ref Ec2KeyPair
SecurityGroupIds:
- !Ref Ec2SecurityGroup
IamInstanceProfile:
!Ref Ec2InstanceProfile
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-Ec2
LaunchTemplate:
LaunchTemplateId: !Ref Ec2LaunchTemplate
Version: !GetAtt Ec2LaunchTemplate.LatestVersionNumber
Outputs:
StackName:
Value: !Sub ${AWS::StackName}
Export:
Name: StackName
KeyPairId:
Value: !GetAtt Ec2KeyPair.KeyPairId
KeyPairPath:
Value: !Sub
- /ec2/keypair/${KeyPairId}
- KeyPairId: !GetAtt Ec2KeyPair.KeyPairId
Export:
Name: KeyPairPath
手順
リソース作成
起動しているEC2のインスタンスIDの取得
SSMParameterStoreに格納されたキーペアのパスを取得
生成したKeyPairのプライベートキーを取得
SSMを使用してポートフォワード開始
EC2に接続
リソース削除
1. リソース作成
cmd
aws cloudformation deploy --template-file ./ec2.yml --stack-name sample-ec2 --capabilities CAPABILITY_NAMED_IAM
2. 起動しているEC2のインスタンスIDの取得
cmd
aws ec2 describe-instances --filter "Name=instance-state-name,Values=running" "Name=tag:Name,Values=sample-ec2-Ec2" --query "Reservations[0].Instances[0].InstanceId" --output text
結果
C:\Users\szk>aws ec2 describe-instances --filter "Name=tag:Name,Values=sample-ec2-Ec2" --query "Reservations[0].Instances[0].InstanceId" --output text
i-06ca26d6c01bfdf03
3. SSMParameterStoreに格納されたキーペアのパスを取得
cmd
aws cloudformation describe-stacks --stack-name sample-ec2 --query "Stacks[0].Outputs[?OutputKey==`KeyPairPath`].OutputValue" --output text
結果
C:\Users\szk>aws cloudformation describe-stacks --stack-name sample-ec2 --query "Stacks[0].Outputs[?OutputKey==`KeyPairPath`].OutputValue" --output text
/ec2/keypair/key-0ec16c1a1e6b69305
4. 生成したKeyPairのプライベートキーを取得
cmd
aws ssm get-parameter --name "/ec2/keypair/key-0ec16c1a1e6b69305" --with-decryption --query "Parameter.Value" --output text > ec2.key
5. SSMを使用してポートフォワード開始
cmd
aws ssm start-session --target i-06ca26d6c01bfdf03 --document-name AWS-StartPortForwardingSession --parameters "{\"portNumber\":[\"22\"],\"localPortNumber\":[\"10022\"]}"
6. EC2に接続
cmd
ssh -i ec2.key -p 10022 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ec2-user@localhost
7. リソース削除
cmd
aws cloudformation delete-stack --stack-name sample-ec2