CloudFormationは納品物に丁度いい
- 転職して1ヶ月。AWSを利用する仕事になった今、CloudFormationは納品物として非常にわかりやすいものなので、とりあえず何でもかんでもCloudFormation化することを考える必要が出てきました。
- 右も左もわからない中、CloudFormationを最低限読み書きできるようにはなったかなと思えたので、それまでの試行錯誤で学んだことをここに記録しておきます。
俺的基本方針
- テンプレート作成の方針を決める
- CloudFormationを実行したら全てが出来上がっている、というのはまずないと思った
- 実務上、既存のネットワークがあった上でそこにCloudFormationで追加していくみたいな流れが自然だと思った
- なので、まずは
既存環境にリソースを追加するためのCloudFormation
ってことでテンプレートを作っていくことにした
既存環境にリソースを追加するためには
- どうやらCloudFormationには、自分でネットワークを指定したり元になるAMI(AmazonMachineImage)を指定したりできるみたい
- この指定するっていうのが、項目があって空欄があって、という時の空欄のことで、その空欄をいかに出すかを理解しようと決めたことでCloudFormationの理解がだいぶ進んだ気がした
いかにリソースを指定するか
- で、上記のような見た目にするために必要なのは以下の2つでした
parameter
AWSTemplateFormatVersion: 2010-09-09
Parameters:
PJPrefix:
Type: String
VpcId:
Type: AWS::EC2::VPC::Id
Default: ""
SubnetId:
Type: AWS::EC2::Subnet::Id
Default: ""
KeyPairName:
Type: AWS::EC2::KeyPair::KeyName
Default: ""
EC2InstanceName:
Type: String
Default: ""
EC2InstanceAMI:
Type: String
Default: ""
EC2InstanceInstanceType:
Type: String
Default: "t2.micro"
EC2InstanceVolumeType:
Type: String
Default: "gp2"
EC2InstanceVolumeSize:
Type: String
Default: "30"
SSHAccessSourceIP:
Type: String
metadata
- これはparameterとセットなのかなくらいにしか意識していなかったですが、よくよく調べてみると、このmetadataの順序でparameterが表示されるという仕組みでした。metadata大事!
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "Project Name Prefix"
Parameters:
- PJPrefix
- Label:
default: "Network Configuration"
Parameters:
- VpcId
- SubnetId
- Label:
default: "EC2Instance Configuration"
Parameters:
- KeyPairName
- EC2InstanceName
- EC2InstanceAMI
- EC2InstanceInstanceType
- EC2InstanceVolumeType
- EC2InstanceVolumeSize
- SSHAccessSourceIP
ParameterLabels:
VpcId:
default: "VpcId"
SubnetId:
default: "SubnetId"
KeyPairName:
default: "KeyPairName"
EC2InstanceName:
default: "EC2 Name"
EC2InstanceAMI:
default: "EC2 AMI"
EC2InstanceInstanceType:
default: "EC2 InstanceType"
EC2InstanceVolumeType:
default: "EC2 VolumeType"
EC2InstanceVolumeSize:
default: "EC2 VolumeSize"
SSHAccessSourceIP:
default: "SSH AccessSourceIP"
必要なリソースができたらあとは定義していくのみ
その他、組み込み関数について
Fn::Join
- 特定の区切り文字で区切って文字列をつなげる
- AWSのリソースはいい感じに文字を繋げないと定義できないことがあるのでそういった時に利用する
- 個人的な感覚としては、Outputsでエクスポートした値を利用するときに以下のようにImportValueと一緒に使うことが多い気がする
- Fn::Join:
- ""
- - Fn::ImportValue: !Sub s3-${Env}-DataBucketArn
- /*
Fn::Sub
- 変数と普通の文字列を接続する
- これはCloudFormationで作成したリソースを一意の名前にしたいときに変数を頭に付けるみたいな手法がよく使われていて、その際に利用する
Profile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- !Ref IAMRole
InstanceProfileName: !Sub "${PJPrefix}-${EC2InstanceName}-profile"
- {PJPrefix}と${EC2InstanceName}に入れた値をここでprofileという文字列に繋げている
Fn::Ref
- 値を参照する
- これは一番わかり易いものかもしれない
PublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
- subnetのidはpublicsubnetとして定義したサブネットのidだよってことで
!Ref
(Fn::Refの短縮形)を利用している
とりあえずは
- これくらいの知識でも十分にCloudFormationを読み書きできるようになったと感じています。
- というか一ヶ月丸々と調査と勉強の時間を与えてもらえたのが大きい。そして業務の一環としてやっていると妥協もできないので、良い緊張感となってより身についた
- あとはアウトプットとして、1日の成果をWikiにアップするという自分の中での縛りを作っていたのでアウトプットまでを一連の流れに組み込めたのはとても良かった