一部のパラメーターを受け取り、他のAWSリソースとともにEC2インスタンスを起動するAWS CloudFormationスタックを実行しています。パラメーターはEC2インスタンスのユーザーデータにフィードされ、その変更に基づいて、EC2インスタンスにあるWebアプリケーションに動的に変更が加えられます。
UserData:
Fn::Base64:
Fn::Join:
- ""
-
- "#!/bin/bash \n"
- "sh website-conf/website_mysql_config.sh "
- " -c \""
-
Ref: "CompanyName"
上記の例に示すように、CompanyNameは、userdataスクリプトに渡される多くのパラメーターの1つです。問題は、1つまたは複数のパラメーターが更新されると、CloudFormationがそれを検出せず、代わりにこのエラーをスローすることです。
そのため、スタックを更新するには、CloudFormationが変更を「確認」してスタックの更新を実行できるように、スタックを編集してASGに変更を加える必要があります。
パラメータが更新されたときにCFNがスタックを強制的に更新する方法はありますか?
AWS CLI Update-Stackコマンドを使用します。 AWS CLIを使用する場合は、スタックにパラメーターを注入できるため、パラメーターを変更すると新しいスタックが生成されます。私はこれを自分で行って、Git /バージョンのコミットIDをUserDataに挿入しているので、スタックのJSON/Yamlへの変更をGitにコミットするだけで、スタックの更新が可能になります。パラメータファイルを変更すると、コメントだけでもスタックを更新できます。 Ref:CompanyNameを参照しているのと同じ方法でUserDataでGitコミットIDを参照しているため、GitコミットIDを変更すると、スタックの更新時にuserDataセクションが更新されます。
スタックコマンドの更新
aws cloudformation update-stack --stack-name MyStack --template-body file:///Users/Documents/Git/project/cloudformation/stack.json --parameters file:///Users/Documents/Git/project/cloudformation/parameters/stack-parameters.dev.json --capabilities CAPABILITY_IAM
プロセス
このアプローチでは、パラメーターのjsonまたはyamlファイルのパラメーターを変更し、それをバージョン管理にチェックインします。ビルドサーバーを使用している場合は、マスターをチェックアウトして上記の1行を実行するだけでスタックを更新できます。 AWS CodeBuildを使用すると、これが簡単になるため、ジェンキンが不要になります。
CloudFormationは、スタックにすでに作成されているリソースのプロパティの変更がない限り、スタックを更新しません。
例: 2つのパラメーターを渡す必要があるデータベースを作成するための単純なテンプレートがあると考えてください。
db-name
を使用して、値としてDBInstanceIdentifier
に渡しているとします。
また、スタックのリソース(またはそのプロパティ)の作成において、入力パラメーターregion
を何らかの目的で使用していないとします。これは、読みやすさの目的で保持するダミーパラメーターです。
CloudFormationテンプレートへの入力パラメーターとして(TEST-DB1, us-east-1)
を渡し、リソースを正常に作成しました。
Scenario-1:
スタックを更新した場合(引き続き既存のテンプレートを使用)、入力パラメータを(TEST-DB2, us-east-1)
に変更するだけです。つまり、リージョンではなく、db-nameのみを変更します。次に、CloudFormationは、このパラメーターの更新により、スタックの実行中のリソースのプロパティが変更されたことを検出し、変更を変更セットとして計算して表示します。
Scenario-2:
別の更新を行い(既存のテンプレートを引き続き使用して)、入力パラメータを(TEST-DB1, us-east-2)
に変更するとします。つまり、db-nameではなく、リージョンのみを変更します。次に、CloudFormationは、このパラメーターの更新により、スタックの実行中のリソースのプロパティに変更はありませんがError creating change set
を示すことを検出します。
ボトムライン:入力パラメータを変更すると、リソース(またはセキュリティグループ、ポートなどの属性)が更新/置換される必要がありますのスタック。次に、AWS CloudFormationはそれらをレビュー用にChange Sets
として表示します。また、AWS CloudFormationが使用するメソッド(更新または置換)は、特定のリソースタイプで更新するプロパティによって異なります。
パラメーター "CompanyName"は、スタックの実行中のリソースに変更を加えていません。したがって、
Error creating change set
として報告されます。スタックのリソース/リソースプロパティを作成するには、これを使用する必要があります。次に、CloudFormationは変更時に変更セットを検出します。同じことが、使用する他の入力パラメータにも当てはまります。
問題の答えはすでにこの状態で答えられています。CloudFormationは、スタックに既に作成されているリソースのプロパティに変更がない限り、スタックを更新しません。
また、質問に対する回答は、以下の説明をご確認ください。
CloudformationがAWS::CloudFormation::Init
を使用してスタックを更新するように強制する方法があります。 cfn-initを使用することにより、各インスタンスは、メタデータ内のAWS::CloudFormation::Init
によって行われた変更を検出すると、それ自体を更新できます。
最初に理解しなければならない概念があります。それは、少なくともAWS::CloudFormation::Init
のケースでは、UserDataとメタデータの違いです。
Userdata
:インスタンスが初めて起動されるときに1回だけ呼び出されます(これには、インスタンスを置き換える必要がある更新も含まれます)。したがって、スタックを更新する場合(新しいスタックを作成しない場合)、パラメーター値を変更しても、UserData
でパラメーターを呼び出しても何も変更されません。Metadata
:いつでも更新できます。機能させるには、変更されたメタデータを検出するデーモンが実行されていることを確認する必要があります(このデーモンはcfn-hupと呼ばれます)。Metadata
およびAWS::CloudFormation::Init
をすでに使用している場合、データはすぐには更新されません。私の知る限り、これはMetadata
値を変更した後にデータが変更される条件です。
cfn-init
コマンドを再度実行しますMetadata
の変更を確認するデーモンが15分に1回変更を確認しているため、約15分待機しています。