背景
軽作業のためにインスタンスが欲しくなるときがあります。
そういうケースは、マネコンからEIP、t3.nano、セキュリティグループリソースを手動で構成しています。
不要になると同じようにマネコンから手動で削除しています。
このオペレーションをAWS CloudFormationのテンプレートを利用して自動化化した記録。
AWS CloudFormation
公式サイトからの引用
AWS CloudFormation は、クラウド環境で AWS とサードパーティ製アプリケーションリソースのモデリングおよびプロビジョニングをする際の、共通的な手法を提供します。AWS CloudFormation では、プログラミング言語またはシンプルなテキストファイルを使用して、あらゆるリージョンとアカウントでアプリケーションに必要とされるすべてのリソースを、自動化された安全な方法でモデル化し、プロビジョニングできます。これは、AWS とサードパーティ製のリソースに真に単一のソースを与えます。
今回、実現したいこと
- パブリックからつながるEC2インスタンス
- 特定IPからのみ ssh できるEC2インスタンス
- aws cli を使いたい
- aws cli の config に東京リージョンを指定したい
- git コマンド使いたい
- リソースへの権限がEC2インスタンスに欲しい
- IAM
- CloudFormation
- EC2
- S3
- Lambda
テンプレート
YAML形式で記述しました
デザイナーを利用する場合の注意事項が記載されています。
デザイナー のテンプレートに # YAML コメントを追加しないことをお勧めします。YAML テンプレートに # コメントがある場合、デザイナー は、テンプレートを JSON に変換する際にコメントを保持しません。また、デザイナー でテンプレートを変更する場合 (たとえば、キャンバスにリソースを移動する場合)、コメントは失われます。
AWS公式サイト AWS CloudFormation テンプレート形式
テンプレートは、
メタデータ
パラメータをグルーピングして表示できるよう指定しました。
今回は、ネットワーク関連と作業用インスタンス関連の2グループです。
#------------------------------------------------------------------------------
# metadata
#------------------------------------------------------------------------------
Metadata:
LICENSE: Apache License, Version 2.0
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: 'Input network information'
Parameters:
- VpcId
- PublicSubnetId
- EC2KeyPairName
- WorkHostSecurityGroupCidr
- WorkHostSecurityGroupCidrDescription
- Label:
default: 'Input work instance information'
Parameters:
- WorkHostName
- WorkHostAmiOs
- WorkHostAmiImageId
- WorkHostInstanceType
- GitUserName
- GitUserEmail
パラメータ
ネットワーク関連のパラメータは、任意に指定できるようにし、OSには、「Amazon-Linux2-HVM」のAMIをデフォルト指定しています。
インスタンスタイプには、「t3.nano」をデフォルト指定しています。
#------------------------------------------------------------------------------
# parameter
#------------------------------------------------------------------------------
Parameters:
#------------------------------------------------------------------------------
# network information
#------------------------------------------------------------------------------
#-- Vpc
VpcId:
Type: String
Default: ''
#-- subnet
PublicSubnetId:
Type: String
Default: ''
#-- key pair
EC2KeyPairName:
Type: String
Default: ''
#-- security group cidr
WorkHostSecurityGroupCidr:
Type: String
Default: ''
#-- security group cidr description
WorkHostSecurityGroupCidrDescription:
Type: String
Default: 'from limited'
#------------------------------------------------------------------------------
# work instance information
#------------------------------------------------------------------------------
#-- host name
WorkHostName:
Type: String
Default: 'tmpwork-tokyo'
#-- AMI
WorkHostAmiOs:
Type: String
Default: 'Amazon-Linux2-HVM'
WorkHostAmiImageId:
Type: String
Default: 'ami-011facbea5ec0363b'
#-- instance type
WorkHostInstanceType:
Type: String
Default: 't3.nano'
#-- git user name
GitUserName:
Type: String
Default: ''
#-- git user email
GitUserEmail:
Type: String
Default: ''
リソース
構成するリソースは、次の通りです
- IAMロール設定
- セキュリティグループ設定
- EIP設定
- EC2インスタンス設定
- IAMロール
- セキュリティグループ設定
- EIP関連付け
サンプルコードを見る
#------------------------------------------------------------------------------
# resource
#------------------------------------------------------------------------------
Resources:
#------------------------------------------------------------------------------
# IAM role
#------------------------------------------------------------------------------
WorkHostIamRole:
Type: "AWS::IAM::Role"
#--- properties
Properties:
RoleName: !Sub '${WorkHostName}-role'
Path: '/'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
-
Action:
- "sts:AssumeRole"
Principal:
Service:
- "ec2.amazonaws.com"
Effect: 'Allow'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AWSCloudFormationFullAccess'
- 'arn:aws:iam::aws:policy/IAMFullAccess'
- 'arn:aws:iam::aws:policy/AmazonEC2FullAccess'
- 'arn:aws:iam::aws:policy/AmazonS3FullAccess'
- 'arn:aws:iam::aws:policy/AWSLambdaFullAccess'
#------------------------------------------------------------------------------
# profile
#------------------------------------------------------------------------------
WorkHostInstanceProfile:
Type: "AWS::IAM::InstanceProfile"
#--- properties
Properties:
Path: "/"
Roles:
- !Ref WorkHostIamRole
#------------------------------------------------------------------------------
# Security Group
#------------------------------------------------------------------------------
WorkHostSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
#--- properties
Properties:
VpcId: !Sub "${VpcId}"
GroupName: !Sub "${WorkHostName}-sg"
GroupDescription: !Sub "${WorkHostName}-sg"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Sub "${WorkHostSecurityGroupCidr}"
Description: !Sub "${WorkHostSecurityGroupCidrDescription}"
Tags:
- Key: 'Name'
Value: !Sub "${WorkHostName}-sg"
#------------------------------------------------------------------------------
# Elastic IP
#------------------------------------------------------------------------------
WorkHostEIP:
Type: "AWS::EC2::EIP"
Properties:
Domain: 'vpc'
Tags:
- Key: 'Name'
Value: !Sub "${WorkHostName}-eip"
#------------------------------------------------------------------------------
# EC2 Instance
#------------------------------------------------------------------------------
WorkHostInstance:
Type: "AWS::EC2::Instance"
#--- metadata
Metadata:
AWS::CloudFormation::Init:
configSets:
Install:
- "Install"
- "AwsConfig"
- "AwsCommand"
- "GitConfig"
- "GitCommand"
Install:
packages:
yum:
git: []
AwsConfig:
files:
/home/ec2-user/.aws/config:
content: !Sub |
[default]
region=${AWS::Region}
mode: "000600"
owner: 'ec2-user'
group: 'ec2-user'
AwsCommand:
commands:
dotaws_chown:
command: 'chown ec2-user:ec2-user /home/ec2-user/.aws'
dotaws_chmod:
command: 'chmod 775 /home/ec2-user/.aws'
GitConfig:
files:
/home/ec2-user/.gitconfig:
content: !Sub |
[user]
name=${GitUserName}
email=${GitUserEmail}
mode: "000600"
owner: 'ec2-user'
group: 'ec2-user'
GitCommand:
commands:
file_chown:
command: 'chown ec2-user:ec2-user /home/ec2-user/.gitconfig'
file_chmod:
command: 'chmod 664 /home/ec2-user/.gitconfig'
#--- properties
Properties:
ImageId: !Sub "${WorkHostAmiImageId}"
InstanceType: !Sub "${WorkHostInstanceType}"
IamInstanceProfile: !Ref WorkHostInstanceProfile
SubnetId: !Sub "${PublicSubnetId}"
SecurityGroupIds:
- !Ref WorkHostSecurityGroup
KeyName: !Sub "${EC2KeyPairName}"
Tags:
- Key: 'Name'
Value: !Sub "${WorkHostName}01"
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
yum install -y aws-cfn-bootstrap
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WorkHostInstance --configsets Install --region ${AWS::Region}
#------------------------------------------------------------------------------
# associate public ip
#------------------------------------------------------------------------------
WorkHostEIPAssociate:
Type: "AWS::EC2::EIPAssociation"
#--- properties
Properties:
AllocationId: !GetAtt WorkHostEIP.AllocationId
InstanceId: !Ref WorkHostInstance
スタックの登録
事前作業
手動対応をあらかじめ実施します
- VPCの構築
- サブネットの構築
- インターネットと通信できるサブネット(IGWがアタッチされるサブネット)
- キーペアの設定
- sshログインの鍵
マネージドコンソールにテンプレートをアップロードして実行
###「スタックの作成」>「新しいリソースを使用(標準)」を選択
テンプレートを指定してアップロード
パラメータ入力
スタック名、VpcId、PublicSubnetId、EC2KeyPairName、WorkHostSecurityGroupCidrをそれぞれ入力します
スタックオプションの設定
詳細オプション
スタックポリシーは、デフォルト「スタックポリシーなし」のまま
ロールバック設定、通知オプションとも特に指定しません
スタック作成オプションは、失敗時のロールバック・削除保護ともデフォルトのまま
必要がありましたら適時変更ください
レビュー {スタック名}
指定した内容の確認フォームとなります
今回テンプレートには、「AWS::IAM::Role」が含まれるため、下記の確認が表示されます
チェックして次に進みます
スタックのステータス
テンプレートに記載された内容で構成が開始されたらイベント情報でスタックのステータスが確認できます
スタック名のステータスが「CREATE_COMPLETE」になれば、完了です。
はまったこと・悩んだこと
- EC2インスタンス内のパッケージインストールやファイル操作
メモ・考察
- スタックの削除でテンプレートから構成されたリソースがすべて削除されるので安心してリソース削除が行える
- 削除確認を促す場合は、削除保護チェックをオンにすると良い
- 簡素な構成であってもリソース起動・削除が安価になった