##1.Amazon CloudFormationとは?##
AWSでインスタンスやVPC環境を作成するとき、コンソール上で作ろうとすると、似たような環境を何度も作ったり、大量に作ったりする時は面倒。
そんな手間を一気に解消してくれるのがCloudFormaion。
平たく言うと「自動的にAWS上で作りたいものを作ってくれる」サービスです。
自分が作りたい環境を定義したファイルを作って、その定義書を読み込んで自動で環境を作ってくれます。
##2.CloudFormation/Elastic Beanstalk/OpsWorksとの違い##
サービス名 | 説明 | ○ | × |
---|---|---|---|
CloudFormation | AWSリソース管理、構築を自動化するサービスであり、JSONやYAMLで記述 | 自由度が高い | OSより上のレイヤはできないこともある |
Elastic Beanstalk | 定番インフラ構成の自動構築およびAppデプロイの自動化サービス | リソースをアプリ開発に集中できる | 自由度は低い |
OpsWorks | Chefレシピを利用した構成管理サービスであり、ChefはAWSがマネージドで管理 Zhttps://zenn.dev/yuta28/articles/opswork-wordpress |
Chefを既に利用している際に最適 | OSより下のレイヤはできないこともある |
##3.ベストプラクティス##
##4.基本用語##
- テンプレート:AWSリソースをJSONやYAMLで記述したドキュメント
- スタック:テンプレートから自動構築されたAWSリソースの集合
##5.機能##
- スタックセット:複数のAWSアカウントと複数のリージョンに対してスタックを作成できる。
[新機能] CloudFormation StackSetsを試してみた
基本的な手順は、
1.AアカウントでAWSCloudFormationStackSetAdministrationRole
2.BアカウントでAWSCloudFormationStackSetExecutionRole
3.スタックセットを設定する。
- スタック間のリソース参照機能:参照テンプレートをエクスポートして値を抽出し、その後参照するテンプレートのインポートによりリソース参照を行うことができる。
##7.テンプレート##
-
セクション
-
Parameters : 実行時に全く同じものをデプロイするのではなく、パラメータを選ぶことができる。(後でやってみます。)
-
Mappings : 実行環境によって、変わる値をMap形式で定義する。(これも後でやってみる)
-
Resources : AWSリソース群を定義する。(基本)
-
組み込み関数
-
Ref : 他の要素を参照する。
-
FindInMap : Mappingsで定義された変数を決めに行く。
-
擬似パラメータ
-
AWS:Region : テンプレートが実行されている環境に応じて変わるような値を取りに行く
[サンプルテンプレート] (https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-sample-templates.html)も準備されている。
##8.基本のCloudFormationを作成してみる##
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Resources" : {
"MyVPC" : {
"Type" : "AWS::EC2::VPC",
"Properties" : {
"CidrBlock" : "10.0.0.0/16",
"EnableDnsSupport" : "true",
"EnableDnsHostnames" : "true",
"InstanceTenancy" : "default",
"Tags" : [ {"Key" : "Name", "Value" : "demo-VPC"} ]
}
},
"MyIGW" : {
"Type" : "AWS::EC2::InternetGateway",
"Properties" : {
"Tags" : [ {"Key" : "Name", "Value" : "demo-IGW"}]
}
},
"AttachGateway" : {
"Type" : "AWS::EC2::VPCGatewayAttachment",
"Properties" : {
"VpcId" : { "Ref" : "MyVPC" },
"InternetGatewayId" : { "Ref" : "MyIGW" }
}
},
"MySubnet" : {
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : { "Ref" : "MyVPC" },
"CidrBlock" : "10.0.0.0/20",
"AvailabilityZone" : "ap-northeast-1a",
"Tags" : [ { "Key" : "Name", "Value" : "demo-Subnet" } ]
}
},
"MyRouteTable" : {
"Type" : "AWS::EC2::RouteTable",
"Properties" : {
"VpcId" : { "Ref" : "MyVPC" },
"Tags" : [ { "Key" : "Name", "Value" : "demo-RT" } ]
}
},
"SubnetAttache" : {
"Type" : "AWS::EC2::SubnetRouteTableAssociation",
"Properties" : {
"RouteTableId" : { "Ref" : "MyRouteTable" },
"SubnetId" : { "Ref" : "MySubnet" }
}
},
"MyRoute" : {
"Type" : "AWS::EC2::Route",
"Properties" : {
"RouteTableId" : { "Ref" : "MyRouteTable" },
"DestinationCidrBlock" : "0.0.0.0/0",
"GatewayId" : { "Ref" : "MyIGW" }
}
}
}
}
"Type" をそれぞれ書く必要があり、設定は "Properties" で書く。
AWS リソースおよびプロパティタイプのリファレンス を見てかけばいい。
シンプルそう。
慣れだろう。
"MyVPC"を例に見ていくと、
"Type" : "AWS::EC2::VPC"
は「10.0.0.0/16のCIDRでVPCを作り、作ったVPCのNameタグはdemo-VPCにする」
となる。
ちなみに "MyVPC" とかは論理IDなので任意のもので可。
"Ref" は参照するということ。
"AttachGateway"を例に見ていくと、
"VpcId" : { "Ref" : "MyVPC" },
は、「インターネットゲートウェイのIDはMyVPCを参照する」
となる。
##7.Parametersを試してみる##
AWSTemplateFormatVersion: '2010-09-09'
Description: Test cfn Template
Parameters:
InstanceType:
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- t2.small
- t2.medium
Description: Select EC2 instance type.
Resources:
cfnVpc:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: '192.168.0.0/16'
Tags:
- Key: 'Name'
Value: 'cfn-vpc'
cfnSubnet:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: '192.168.1.0/24'
MapPublicIpOnLaunch: true
Tags:
- Key: 'Name'
Value: 'cfn-subnet'
VpcId: !Ref cfnVpc
cfnInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: 'Name'
Value: 'cfn-igw'
cfnAttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref cfnVpc
InternetGatewayId: !Ref cfnInternetGateway
cfnRouteTable:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: 'Name'
Value: 'cfn-rt'
VpcId: !Ref cfnVpc
cfnRoute:
Type: AWS::EC2::Route
DependsOn: cfnInternetGateway
Properties:
RouteTableId: !Ref cfnRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref cfnInternetGateway
cfnSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref cfnSubnet
RouteTableId: !Ref cfnRouteTable
cfnEC2Instance:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: "ami-3bd3c45c"
InstanceType: !Ref InstanceType
SubnetId: !Ref cfnSubnet
BlockDeviceMappings:
- DeviceName: '/dev/xvda'
Ebs:
VolumeType: 'gp2'
VolumeSize: 8
Tags:
- Key: 'Name'
Value: 'cfn-ec2-instance'
SecurityGroupIds:
- !Ref cfnSecurityGroup
cfnSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: "cfnSecurityGroup"
VpcId: !Ref cfnVpc
Tags:
- Key: 'Name'
Value: 'cfn-ssh-sg'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
Parameters でインスタンスタイプを選択できるようにし、
InstanceType: !Ref InstanceType と定義すると、
スタック実行時に↓のような画面が選択できるようになる。
##8.Mappingsの動作を確認してみる##
AWSTemplateFormatVersion: '2010-09-09'
Description: Test cfn Template
Parameters:
InstanceType:
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- t2.small
- t2.medium
Description: Select EC2 instance type.
KeyPair:
Description: Select KeyPair Name.
Type: AWS::EC2::KeyPair::KeyName
Mappings:
RegionMap:
us-east-1:
hvm: "ami-a4c7edb2"
ap-northeast-1:
hvm: "ami-3bd3c45c"
Resources:
cfnVpc:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: '192.168.0.0/16'
Tags:
- Key: 'Name'
Value: 'cfn-vpc'
cfnSubnet:
Type: 'AWS::EC2::Subnet'
Properties:
CidrBlock: '192.168.1.0/24'
MapPublicIpOnLaunch: true
Tags:
- Key: 'Name'
Value: 'cfn-subnet'
VpcId: !Ref cfnVpc
cfnInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: 'Name'
Value: 'cfn-igw'
cfnAttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref cfnVpc
InternetGatewayId: !Ref cfnInternetGateway
cfnRouteTable:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: 'Name'
Value: 'cfn-rt'
VpcId: !Ref cfnVpc
cfnRoute:
Type: AWS::EC2::Route
DependsOn: cfnInternetGateway
Properties:
RouteTableId: !Ref cfnRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref cfnInternetGateway
cfnSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref cfnSubnet
RouteTableId: !Ref cfnRouteTable
cfnEC2Instance:
Type: 'AWS::EC2::Instance'
Properties:
ImageId: !FindInMap [ RegionMap, !Ref "AWS::Region", hvm ]
InstanceType: !Ref InstanceType
SubnetId: !Ref cfnSubnet
BlockDeviceMappings:
- DeviceName: '/dev/xvda'
Ebs:
VolumeType: 'gp2'
VolumeSize: 8
Tags:
- Key: 'Name'
Value: 'cfn-ec2-instance'
SecurityGroupIds:
- !Ref cfnSecurityGroup
KeyName: !Ref KeyPair
cfnSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: "cfnSecurityGroup"
VpcId: !Ref cfnVpc
Tags:
- Key: 'Name'
Value: 'cfn-ssh-sg'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
ImageIdをami-***のようにそのま書くと、amiはリージョンごとにしか使えないようになっている。
そこで、Mappingsで利用する複数のリージョンを記載しておき、
FindInMap [ RegionMap, !Ref "AWS::Region", hvm ] で定義しておけば、Mappingsに記載したリージョンでこのテンプレートを利用できることとなる。
##9.NestedStacks と Cross Stack Reference##
-
NestedStacks
-
各テンプレートの共通部分を作成し、スタックの親子関係を実現。
-
Cross Stack Reference
-
あるスタックから値をエクスポートし、別のスタックで参照し、多層またはサービス指向アーキテクチャを実現する。
-
Outputsセクションを使って、他のスタックから参照したい値をエクスポート >> 別のスタックで、ImportValue関数を使って値を参照する。
-
Cross Stack は、AWSアカウントの場合、エクスポート名はリージョン内で一意である必要があります。
例えば、東京リージョンの1人の従業員がCloudFormationスタック「Health1」を作成し、「NewStack」を出力しました。
別の従業員がシンガポールリージョンで別のアプリケーション「Health2」のCloudFormationスタックを作成し、「NewStack」という名前の出力をエクスポートしました。
最初の従業員は、シンガポールリージョンにCloud Formationスタック「Health1」をデプロイしようとしてもエラーになります。
##10.Dynamic Reference##
- CloudFormationにそのまま値を入れず、AWS Systems Managerのパラメータストア と AWS Secrets Manager に格納されたデータを動的に参照したい場合に利用する。
##11.Change Set(変更セット)とDrift Detection(ドリフト検出)##
- Change Set(変更セット)
- 現状のスタックとの変更点を確認してから、更新することができる。
- 確認できるのは、下記の画面の通り何のリソースが変更されるかである。
- Drift Detection(ドリフト検出)
- テンプレートと現状のリソースの差分を検出する。
- 例えば、CloudFormation外で、何かのリソースの設定を変更してしまったなど、手動で変更してしまったものをドリフトという機能で差分を確認できます。
- 検出できるリソースは全てではないので、ドキュメントを確認する必要がある。
##12.Rollback Triggers##
スタックの作成、更新中にアプリケーションの状態をAWS CloudFormationでモニタリングし、指定したアラームの閾値を超過した場合に、そのオペレーションをロールバック。
##13.StackSets##
1つのテンプレートを複数のAWSアカウントおよび複数のリージョンに展開することが可能。
##14.保護##
謝って削除することを防ぐために複数の機能があります。
-
ユーザーのIAMポリシー
-
そもそもユーザーに触らせない。
-
スタックの削除保護
-
スタック全体が誤って削除されるのを防ぐ。
-
スタックポリシー
-
スタックの更新中にスタックのリソースが意図せずに変更、削除されるのを防ぐ。
-
スタックポリシーファイルの例はドキュメントを参考に。
-
リソースのDeletionPolicy 属性
-
スタックが削除された際にリソースをどうするかをテンプレートのリソースに記載する。
オプション | 説明 |
---|---|
Delete | 削除 |
Retain | 保持 |
Snapshot | スナップショットを取得する |
##15.リソースのインポート##
- 手動で作成したAWSリソースをCloudFormationにインポートして管理可能。
- リソースをスタックから切り離し、別の管理下に移動することも可能。
##16.リンク##
AWS CloudFormation を開発・テストする際に役立つツール纏め