[AWS]CloudFormationを使いこなして早く帰るTips5選
コンニチハ、千葉です。
最近CloudFormationで20台くらい、どっかーんとEC2立てて気持ちよくなってる私です。 CloudFormationを利用すると、規模が大きかったり環境(dev/stg/prd)がたくさんあっても、かなり楽できます。そうです、早く帰れます。
ということで、使ったTipsをまとめておきます。今回は、よく構築するであろうEC2にフォーカスします。
Tips
Tips1:環境によってパラメータを変える
パラメータを変数化して、1つのCFnファイルで複数の環境(dev/stg/prd)を扱います。Mappings
を使います。コードの例です。*Mappingsに関連する部分だけ抜粋
CFnスタック作成するときに、prd/stgを選ぶと、Mappingsで定義したパラメータを利用できます。これで、1つのCFnでprd/stgを管理できます。
Mappings: prd: PublicSubnet1a: { ID: subnet-xxxxx } stg: PublicSubnet1a: { ID: subnet-xxxxx } Parameters: Environment: Description: Type of this environment. Type: String Default: prd AllowedValues: - prd - stg BastionEc2Instance: ・・・省略 - SubnetId: !FindInMap [ !Ref Environment, PublicSubnet1a, ID ]
Tips2:命名規則
リソース名など、最初から命名規則を決めて組み込みましょう。
Parameters: Environment: Description: Type of this environment. Type: String Default: prd AllowedValues: - prd - stg Parameters: SystemName: Description: Name of this system. Type: String Default: chiba-system ・・・省略 Tags: - Key: Name Value: !Sub ${SystemName}-${Environment}-web1
Tips3:ユーザーデータを使って初期構築windows編
windowsの初期構築です。ユーザーデータを使って、ホスト名、時刻同期、文字コード、タイムゾーンを設定します。
Mappings
と!Sub
をうまく組み合わせて変数を取り込んでます。ちょっと複雑。ただ、ログインしなくていいんですよ、圧倒的です。
Mappings: prd: OSSettings: TimeZone: "Tokyo Standard Time" BastionEc2Instance: HostName: chiba-bastion ・・・省略 UserData: Fn::Base64: !Sub - | # hostname Rename-Computer -NewName ${HostName} -Force # TimeZone Set-TimeZone -id "${TimeZone}" # time sync w32tm /config /manualpeerlist:169.254.169.123 /syncfromflags:manual /update - { HostName: !FindInMap [ !Ref Environment, BastionEc2Instance, HostName ], TimeZone: !FindInMap [ !Ref Environment, OSSettings, TimeZone ] }
Tips4:ユーザーデータを使って初期構築Linux編
Linuxバージョンです。ホスト名、時刻同期、文字コード、タイムゾーンを設定します。
Mappings: prd: OSSettings: Locale: ja_JP.utf8 TimeZone: "Asia/Tokyo" BastionEc2Instance: HostName: chiba-bastion ・・・省略 UserData: Fn::Base64: !Sub - | #!/bin/sh -ex # timezon timedatectl set-timezone ${TimeZone} # hostname hostnamectl set-hostname --static ${HostName} echo 'preserve_hostname: true' >> /etc/cloud/cloud.cfg # time sync yum erase 'ntp*' yum install chrony echo '#Add TimeSync' >> /etc/chrony.conf echo 'server 169.254.169.123 prefer iburst' >> /etc/chrony.conf systemctl start chrony systemctl enable chrony # locale localectl set-locale LANG=${Locale} - { HostName: !FindInMap [ !Ref Environment, BastionEc2Instance, HostName ], TimeZone: !FindInMap [ !Ref Environment, OSSettings, TimeZone ], Locale: !FindInMap [ !Ref Environment, OSSettings, Locale ] }
Tips5:注意:DeviceNameは気をつける
EC2構築時にDeviceNameを利用しますが、デバイス名を意識して指定する必要があります。指定を誤るとEC2が起動できなかったりします。インスタンスタイプ(仮想化方式の違い)やAMIによって違ったりします。こちらを参考にしたり、実際に手動でEC2を作るときに確認できます。
- https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/device_naming.html
- https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/device_naming.html
全部入りコード
これらをまとめたコードを置いておきます!
windows
windows1台構築します。EC2の設定に加え、ホスト名、時刻同期、タイムゾーンを設定します。
AWSTemplateFormatVersion: '2010-09-09' Description: This CloudFormation template to create EC2 instances. Mappings: prd: PublicSubnet1a: { ID: subnet-xxxxxx } PublicSubnet1c: { ID: subnet-xxxxxx } PrivateSubnet1a: { ID: subnet-xxxxxx } PrivateSubnet1c: { ID: subnet-xxxxxx } OSSettings: TimeZone: "Tokyo Standard Time" BastionEc2Instance: HostName: xxxx_ec2 InstanceType: t3.small AmiId: ami-0a2de1c3b415889d2 RootVolumeSize: 30 PrivateIpAddress: xx.xx.xx.xx SecurityGroupId: sg-xxxxxxx Parameters: Environment: Description: Type of this environment. Type: String Default: prd AllowedValues: - prd - stg SystemName: Description: Name of this system. Type: String Default: chiba-web KeyName: Type: AWS::EC2::KeyPair::KeyName Description: Name of an existing EC2 KeyPair to enable access to instances. Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Environment Configuration Parameters: - SystemName - Environment - Label: default: EC2 Instance Keypair Name Parameters: - KeyName Resources: BastionEc2Instance: Type: AWS::EC2::Instance Properties: InstanceType: !FindInMap [ !Ref Environment, BastionEc2Instance, InstanceType ] ImageId: !FindInMap [ !Ref Environment, BastionEc2Instance, AmiId ] KeyName: !Ref KeyName BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeType: gp2 VolumeSize: !FindInMap [ !Ref Environment, BastionEc2Instance, RootVolumeSize ] DeleteOnTermination: true NetworkInterfaces: - SubnetId: !FindInMap [ !Ref Environment, PublicSubnet1a, ID ] PrivateIpAddress: !FindInMap [ !Ref Environment, BastionEc2Instance, PrivateIpAddress ] AssociatePublicIpAddress: false GroupSet: - !FindInMap [ !Ref Environment, BastionEc2Instance, SecurityGroupId ] DeviceIndex: 0 DeleteOnTermination: true DisableApiTermination: true UserData: Fn::Base64: !Sub - | # hostname Rename-Computer -NewName ${HostName} -Force # TimeZone Set-TimeZone -id "${TimeZone}" # time sync w32tm /config /manualpeerlist:169.254.169.123 /syncfromflags:manual /update - { HostName: !FindInMap [ !Ref Environment, BastionEc2Instance, HostName ], TimeZone: !FindInMap [ !Ref Environment, OSSettings, TimeZone ] } Tags: - Key: Name Value: !FindInMap [ !Ref Environment, BastionEc2Instance, HostName ]
Linux
Linux1台構築します。EC2の設定に加え、ホスト名、時刻同期、タイムゾーンを設定します。
AWSTemplateFormatVersion: '2010-09-09' Description: This CloudFormation template to create EC2 instances. Mappings: prd: PublicSubnet1a: { ID: subnet-xxxxxx } PublicSubnet1c: { ID: subnet-xxxxxx } PrivateSubnet1a: { ID: subnet-xxxxxx } PrivateSubnet1c: { ID: subnet-xxxxxx } OSSettings: Locale: ja_JP.utf8 TimeZone: "Asia/Tokyo" BastionEc2Instance: HostName: xxxx_ec2 InstanceType: t3.small AmiId: ami-0a2de1c3b415889d2 RootVolumeSize: 50 PrivateIpAddress: xx.xx.xx.xx SecurityGroupId: sg-xxxxxxx Parameters: Environment: Description: Type of this environment. Type: String Default: prd AllowedValues: - prd - stg SystemName: Description: Name of this system. Type: String Default: chiba-web KeyName: Type: AWS::EC2::KeyPair::KeyName Description: Name of an existing EC2 KeyPair to enable access to instances. Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Environment Configuration Parameters: - SystemName - Environment - Label: default: EC2 Instance Keypair Name Parameters: - KeyName Resources: # Bastion instance BastionEc2Instance: Type: AWS::EC2::Instance Properties: InstanceType: !FindInMap [ !Ref Environment, BastionEc2Instance, InstanceType ] ImageId: !FindInMap [ !Ref Environment, BastionEc2Instance, AmiId ] KeyName: !Ref KeyName CreditSpecification: CPUCredits: standard BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeType: gp2 VolumeSize: !FindInMap [ !Ref Environment, BastionEc2Instance, RootVolumeSize ] DeleteOnTermination: true NetworkInterfaces: - SubnetId: !FindInMap [ !Ref Environment, PublicSubnet1a, ID ] PrivateIpAddress: !FindInMap [ !Ref Environment, BastionEc2Instance, PrivateIpAddress ] AssociatePublicIpAddress: false GroupSet: - !FindInMap [ !Ref Environment, BastionEc2Instance, SecurityGroupId ] DeviceIndex: 0 DeleteOnTermination: true DisableApiTermination: true UserData: Fn::Base64: !Sub - | #!/bin/sh -ex # timezon timedatectl set-timezone ${TimeZone} # hostname hostnamectl set-hostname --static ${HostName} echo 'preserve_hostname: true' >> /etc/cloud/cloud.cfg # time sync yum erase 'ntp*' yum install chrony echo '#Add TimeSync' >> /etc/chrony.conf echo 'server 169.254.169.123 prefer iburst' >> /etc/chrony.conf systemctl start chrony systemctl enable chrony # locale localectl set-locale LANG=${Locale} - { HostName: !FindInMap [ !Ref Environment, BastionEc2Instance, HostName ], TimeZone: !FindInMap [ !Ref Environment, OSSettings, TimeZone ], Locale: !FindInMap [ !Ref Environment, OSSettings, Locale ] } Tags: - Key: Name Value: !FindInMap [ !Ref Environment, BastionEc2Instance, HostName ]
まとめ
仕事はサクッと終わらせて早く帰りたい派のみなさま。早く帰って家族と過ごしたり、自分のスキル磨いたり、ゲームしたり、温泉入ったりライフワークバランスを大切にしたいものです。