CloudFormationを使うようになったので、学習メモを記録。
- CloudFormationって何?
- 注意点
- 用語
- AnsibleでAWSリソースを作った場合との比較
- テンプレート
- スタックの作成
- スタックの更新
- TIPS、トラブル対応
- Auroraを使ったRDS環境をCloudFormerで構築する方法
- CloudFormerでElastic BeanstalkのDNSをRoute53に設定する
- AWS::Route53::RecordSetGroupのスタック作成時、一言 Invalid requestと怒られる
- スタック更新時に「CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename 'MYResourceXXX' and update the stack again.」と怒られる
- 「テンプレートの検証エラー: Template format error: [/Resources/xxxx/xxxx/xxxx] map keys must be strings; received a collection instead」と怒られる
- リンク
CloudFormationって何?
AWS Black Belt Online Seminar 2016 AWS CloudFormation
とりあえず、どんな機能か知りたいときはBlack Belt Online Seminar。
概要もわかりやすく、まず知りたかった情報も大体載ってた。
Black Belt Online Seminarの気になったページ
P.12 Elastic BeanstalkやOpsWorksとの位置付けの違いがわかりやすく書かれている。
P.13 OpsWorksやCodeDeployの対象レイヤーの違いがわかりやすく書かれている。
P.66 AWS CloudFormation Designer。テンプレート内のリソース可視化。ドラッグアンドドロップで編集も可能
P.66 AWS CloudFormationにおける運用
P.81 変更セット(Change set)。変更を要求した箇所と影響を事前確認できる。
注意点
CloudFormationで作成したAWSリソースは、CloudFormation以外の方法で変更してはいけない。
CloudFormationで作成や変更に失敗したときには自動でロールバックしてくれるので、そのことも考慮する必要がある。CloudFormation以外の方法で変更してしまうと正常にロールバックできない。
用語
言葉 | 内容 |
---|---|
テンプレート | スタックを作成するときの入力となるテキスト(JSONまたはYAML1.1) |
スタック | テンプレートからプロビジョニングされたリソースの集合。スタックを簡単に作成/破棄できるのが、CloudFormationの特徴の一つ |
変更セット | 変更セットは、スタックに加えられる変更を要約した JSON形式のドキュメント。CloudFormationが作ってくれる |
AnsibleでAWSリソースを作った場合との比較
AnsibleでもAWSリソースを作ったり、変更したりできるけど、それと比べても色々便利。
- 作成時にGUI上でパラメータを設定できる。
- 指定したパラメータを後から確認できる。
- 作成したリソースが一覧表示できる。変更時にリソースへの影響を事前に表示してくれる。
- 作成や変更のイベントが記録されている
- 作成したときのテンプレートが残っている
- 作成や変更に失敗したときにロールバックしてくれる
テンプレート
テンプレートのフォーマット
サポートしている書式は、JSON、YAML1.1。
YAML1.1なら、JSONではできなかったコメントの記載ができる。
JSONからYAMLの変換はこちらでできる。
テンプレートの構成
名前 | 内容 |
---|---|
AWSTemplateFormatVersion | テンプレートのバージョン |
Parameters | 実行時にユーザー入力を求めるパラメータを定義 |
Resources | EC2などスタックを構成するリソースを定義 |
Mappings | キーと値のマッピング。例:入力した内容やリージョンに応じて値を変える |
Conditions | 条件名と成立条件を列挙 |
Outputs | スタック構築後に取得・表示した情報の定義。GUIでも確認できて便利らしい |
CloudFormer(既存AWSリソースからのテンプレート作成)
自分でゼロからテンプレートを作るのはキツイので、CloudFormerという既存AWSリソースからテンプレート作成できるツールを使う。
CloudFormerを作成する手順:
スタック作成 > テンプレート > CloudFormerを選択。
CloudFormerが入ったWebサーバーのEC2インスタンスが立ち上がるので、 https でアクセス。
CLIで情報を取得して、テンプレート作成の参考にする
CLIで取得した情報をそのままCloudFormationでそのまま使えるわけではないけど、参考になることは多いような気がする。
EC2インスタンスの情報取得
公式リファレンス
AWS CLIを使ってEC2インスタンスの情報を取得する
aws ec2 describe-instances
aws rds describe-db-instances
Beanstalkの情報取得
公式リファレンス
aws elasticbeanstalk describe-application-versions aws elasticbeanstalk describe-applications aws elasticbeanstalk describe-configuration-options aws elasticbeanstalk describe-configuration-settings aws elasticbeanstalk describe-environment-resources aws elasticbeanstalk describe-environments aws elasticbeanstalk describe-events
サンプルテンプレート、スニペット
パラメータの記載方法
"AWS::EC2::KeyPair::KeyName"など、AWS固有のパラメーター型の一覧はこちら。
パラメータのDescriptionには日本語を使えない。残念。
リソースの記載方法
公式:EC2のリソース記載方法(AWS::EC2::Instance)。
ページ左側に各詳細項目へのリンクがある。
値の記載方法:
やりたいこと | 例 |
---|---|
文字列を直接記載する | "abc" |
パラメータの入力結果を参照する | { "Ref": "パラメータ名(例:)" } |
作成したEC2インスタンスIDを参照する | { "Ref": "リソース名(例:EC2Instance)" } |
Base64エンコード | { "Fn::Base64": "abc" } |
結合 | { "Fn::JOIN": [ "", ["IPAddress=", {"Ref":"IPAddress"} ]] } |
組み込み関数リファレンス
YAMLの場合、「Fn::」を「!」に省略可能。例:Fn::Join → !Join
立ち上げたEC2リソースの初期化方法
EC2にはUserDataに一定の書式で記載することで、インスタンス起動時にスクリプトを実行する機能がある。
スクリプトの実行で「CloudFormationヘルパースクリプト」を呼び出すことで、複雑なインストールなどもできる。
公式:AWS CloudFormation による Amazon EC2 へのアプリケーションのデプロイ
UserDataの設定方法やヘルパースクリプトの呼び出し方のサンプル。
ファイルの書き換えを行う場合はUserDataでsedを呼び出す。
sedの書式はsedでこういう時はどう書く? を参考にした。
sedは-iオプションを指定することで、ファイルに上書き保存することができる。
sedで/を扱いたい場合は、区切り文字に|を使う。
$ echo "/123/" | sed 's|/|abc|g' abc123abc
CloudFormationヘルパースクリプト
ヘルパースクリプトにはcfn-init、cfn-signal、cfn-get-metadata、cfn-hupがある。
Amazon Linux AMIを使っている場合、デフォルトで、AWS CloudFormationヘルパースクリプトが /opt/aws/bin にインストール済み。
cfn-init用メタデータの記載方法(AWS::CloudFormation::Init)
テンプレートのバージョン管理をしたい
テンプレートを置いているS3バケットのバージョニングを有効にする。
テンプレートの書式を事前チェックする
S3上のテンプレートをチェック
aws cloudformation validate-template --template-url https://s3.amazonaws.com/cloudformation-templates-us-east-1/S3_Bucket.template
ローカルのテンプレートをチェック(Macの場合)
aws cloudformation validate-template --template-body file:///Users/user-name/test/sampletemplate.json
ローカルのテンプレートをチェック(Windowsの場合)
aws cloudformation validate-template --template-body file://C:/Users/user-name/test/sampletemplate.json
スタックの作成
テンプレートの選択
「Amazon S3 テンプレート URL の指定」を選ぶ場合、httpで始まるリンクを指定する。リンクはS3上で該当ファイルの詳細を確認すると表示される。
スタック名には英数字 (大文字と小文字が区別されます) とハイフンのみを使用可能。
似たようなスタックを大量に作りたい(クイック作成)
スタック作成時、「作成」ボタンを押す手前に表示される「クイック作成」のリンクを控えておく。クイック作成の詳細な説明は公式ページ参照。
スタックの更新
直接更新(Update)、変更セット(Change set)を作って変更内容を確認してから適用の2つの方式がある。変更セットは、スタック一覧画面の変更セットタブに表示される。
TIPS、トラブル対応
Auroraを使ったRDS環境をCloudFormerで構築する方法
公式ページのAWS::RDS::DBClusterリファレンスだけではよくわからなかった。
CloudFormerの出力もイマイチ。現時点ではDBClusterには対応していない。
こちらのページが参考になったので、手直しして無事作成。
CloudFormerでElastic BeanstalkのDNSをRoute53に設定する
HostedZoneIdがないのでエラーが表示されるけど、Fn::GetAttでは取得できないので途方にくれた。
こちらのページを参考に、DNSNameとHostedZoneIdを設定。
AWS::Route53::RecordSetGroupのスタック作成時、一言 Invalid requestと怒られる
スタック更新時に「CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename 'MYResourceXXX' and update the stack again.」と怒られる
メッセージだとわかりにくいけど、リネームの対象はテンプレート(JSONもしくはYAMLの文書) に書かれている該当リソース名。
公式ページの推奨方法も該当するリソース名の変更。
テンプレートの該当リソース名を変更すれば、更新できる。
もう一度、該当リソース名を元の名前に変更して再更新すれば、同じリソース名も使える。
「テンプレートの検証エラー: Template format error: [/Resources/xxxx/xxxx/xxxx] map keys must be strings; received a collection instead」と怒られる
よくあるミス:
- 最後のカンマを忘れている
- []で囲むのを忘れている