使い捨て環境をサクッと作りたくてバッチを適当に書いた。
実行するとSSM経由で接続できるEC2を起動し、SSHの設定と共にKeyPairを取得して配置してVSCodeをリモートモードで起動する。
起動と同時に以下のようなバッチも生成し簡単に削除できるようにした。
Delete-{インスタンス名}.bat
@REM SSHConfの削除
@RD /S /Q "C:\Users\szk/.ssh/conf.d/ephemeral/amz-ec2-20220930072729"
@REM リソースの削除
aws cloudformation delete-stack --stack-name "amz-ec2-20220930072729"
@DEL %0
準備
VSCodeからSSH経由接続するため、バッチ実行時に以下のディレクトリにSSH設定の設定のプライベートキーを出力する。
~/.ssh/conf.d/ephemeral/${インスタンス名}
この設定を有効化するためには予め ~/.ssh/confg に以下の設定を追加してインポートできるようにする。
(例)~/.ssh/config
Include conf.d/ephemeral/*/*.conf
内容
StartSandboxAmzLinuxEc2.bat: エントリーポイントのバッチ
amz-ec2.yml: EC2を起動するためのCloudFormation template
scripts/StartSandboxAmzLinuxEc2.ps1: 処理を記述したスクリプト
ディレクトリ構成
./
├── StartSandboxAmzLinuxEc2.bat
├── amz-ec2.yml
└── scripts
└── StartSandboxAmzLinuxEc2.ps1
1. StartSandboxAmzLinuxEc2.bat
powershell -ExecutionPolicy Bypass -command .\scripts\StartSandboxAmzLinuxEc2.ps1
pause
2. amz-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
instanceType:
Type : String
Default: t3.large
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: !Ref instanceType
KeyName: !Ref Ec2KeyPair
SecurityGroupIds:
- !Ref Ec2SecurityGroup
IamInstanceProfile:
!Ref Ec2InstanceProfile
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}
LaunchTemplate:
LaunchTemplateId: !Ref Ec2LaunchTemplate
Version: !GetAtt Ec2LaunchTemplate.LatestVersionNumber
Outputs:
Ec2InstanceId:
Value: !Ref Ec2
Export:
Name: !Sub ${AWS::StackName}-Ec2InstanceId
KeyPairId:
Value: !GetAtt Ec2KeyPair.KeyPairId
Export:
Name: !Sub ${AWS::StackName}-KeyPairId
KeyPairPath:
Value: !Sub
- /ec2/keypair/${KeyPairId}
- KeyPairId: !GetAtt Ec2KeyPair.KeyPairId
Export:
Name: !Sub ${AWS::StackName}-KeyPairPath
3.scripts/StartSandboxAmzLinuxEc2.ps1
$stackName="amz-ec2-$(Get-Date -Format yyyyMMddHHmmss)"
$instanceName="${stackName}"
$sshConfigDirPath="${Home}/.ssh/conf.d/ephemeral/${stackName}"
$sshConfigFilePath="${sshConfigDirPath}/${instanceName}.conf"
$keyFileName="${instanceName}.pem"
$keyFilePath="${sshConfigDirPath}/${keyFileName}"
$remoteHomeDirPath="/home/ec2-user"
$deleteBatFilePath="Delete-${stackName}.bat"
echo "###########################################"
echo "# StackName: ${stackName}"
echo "# InstanceName: ${instanceName}"
echo "# KeyFileName: ${keyFileName}"
echo "# KeyFilePath: ${keyFilePath}"
echo "# SshConfigFilePath: ${sshConfigFilePath}"
echo "###########################################"
## SSHConfigディレクトリの作成
mkdir "${sshConfigDirPath}" > $null
## リソースの作成
aws cloudformation deploy --template-file ./amz-ec2.yml --stack-name "${stackName}" --capabilities CAPABILITY_NAMED_IAM
## リソース作成待ち
aws cloudformation wait stack-create-complete --stack-name "${stackName}"
## インスタンスIDの取得
$instanceId = (aws cloudformation describe-stacks --stack-name "${stackName}" --query "Stacks[0].Outputs[?OutputKey==``Ec2InstanceId``].OutputValue" --output text).trim()
echo "instanceId:${instanceId}"
## EC2起動まち
aws ec2 wait instance-status-ok --include-all-instances --instance-ids "${instanceId}"
## キーペア取得
### キーペア名を取得
$keyPairName = (aws cloudformation describe-stacks --stack-name "${stackName}" --query "Stacks[0].Outputs[?OutputKey==``KeyPairPath``].OutputValue" --output text).trim()
echo "keyPairName:${keyPairName}"
### キーペアを取得
aws ssm get-parameter --name "${keyPairName}" --with-decryption --query "Parameter.Value" --output text | Set-Content -Path "${keyFilePath}"
## SSH設定の生成
$sshConfig = @"
Host ${instanceName}
User ec2-user
Port 22
ProxyCommand powershell.exe aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters portNumber=%p
HostName ${instanceId}
IdentityFile ${keyFilePath}
"@
Set-Content -Path $sshConfigFilePath -Value $sshConfig
## VSCodeの起動
code --remote "ssh-remote+${instanceName}" "${remoteHomeDirPath}"
## 削除バッチの生成
$deleteBat = @"
@REM SSHConfの削除
@RD /S /Q "${sshConfigDirPath}"
@REM リソースの削除
aws cloudformation delete-stack --stack-name "${stackName}"
@DEL %0
"@
Set-Content -Path $deleteBatFilePath -Value $deleteBat
実行
作成
StartSandboxAmzLinuxEc2.bat をクリック
削除
Delete-${インスタンス名}.bat をクリック