CloudFormation のテンプレートの検証エラーまたは形式エラーの解決策を教えてください。
AWS CloudFormation テンプレートを検証して、構文エラーがないことを確認したいです。
簡単な説明
受け取ったエラーメッセージに基づいて、次の解決策のいずれかを選択してください:
- 「JSON not well-formed」または「YAML not well-formed」エラーについては、「テンプレート構文を検証する」セクションを参照してください。
- 「テンプレートのリソースブロックにある未解決のリソース依存関係 [XXXXXXXX]」エラーについては、「論理 ID とパラメーターを検証する]」セクションを参照してください。
- 「認識できないパラメータのタイプ: XXXXXXXX」または「無効なテンプレートパラメータプロパティ 「XXXXXXXX」」エラーについては、「パラメータ定義を検証する」セクションを参照してください。
- 「すべての Condition メンバーは文字列でなければなりません」エラーについては、「Condition が文字列として指定されていることを確認する」セクションを参照してください。
- 「認識されないリソースタイプ: [XXXXXXXX]」エラーについては、「リソースタイプの可用性を確認する」セクションを参照してください。
- 「[環境リソース]「XXXXXXXX」が存在しません」エラーについては、「リソースがスタック外に存在することを確認するか、同じスタック内のリソースの依存関係を検証する」セクションをご参照ください。
- 「無効なテンプレートプロパティまたはプロパティ [XXXXXXXX]」エラーについては、「テンプレートプロパティを確認する」セクションをご参照ください。
- 「Invalid policy syntax」または「MalformedPolicy」エラーについては、「IAM ポリシー関連リソースのポリシー構文を検証する」セクションを参照してください。
解決策
AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI エラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。
テンプレート構文を検証する
CloudFormation テンプレートで適切な JSON または YAML の構文に従うには、次の点を考慮してください:
- AWS CloudFormation デザイナーを使用してスタックを作成します。
- テキストエディタ、または AWS CLI テンプレート検証ツールなどのコマンドラインツールを使用して JSON 構文を検証します。
- AWS CloudFormation 検証テンプレートコマンドを使用して YAML 構文を検証します。
- GitHub ウェブサイトの AWS CloudFormation リンターを使用して、JSON または YAML テンプレートを検証します。
論理 ID とパラメータを検証する
リソースの論理 ID とパラメーターがテンプレートで定義されていることを確認します。
次の JSON および YAML テンプレートでは、ImageId プロパティの test が参照されています。ただし、どちらのテンプレートにもリソース論理 ID も test という名前のパラメーターも含まれていません。これらのテンプレートは: 「テンプレートのリソースブロックにある未解決のリソース依存関係 [test]」エラーを返します。 リソース定義とその構文の詳細については、[リソース] を参照してください。
JSON の例 (正しくない):
{ "Resources" : { "EC2Instance01" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : {"Ref": "test"} } } } }
YAML の例 (正しくない):
Resources: EC2Instance01: Type: AWS::EC2::Instance Properties: ImageId: !Ref test
この問題を解決するには、test という名前のリソース論理 ID を追加します。または、リファレンスが ImageId 値を返す test という名前のパラメータを作成します。次の JSON テンプレートと YAML テンプレートの例には、test という名前のパラメーターと ImageId が値として含まれています。
JSON の例 (正しい):
{ "Parameters": { "test": { "Type": "String", "Default": "ami-xxx" } }, "Resources" : { "EC2Instance01" : { "Type" : "AWS::EC2::Instance", "Properties" : { "ImageId" : {"Ref": "test"} } } } }
YAML の例 (正しい):
Parameters: test: Type: String Default: ami-xxx Resources: EC2Instance01: Type: 'AWS::EC2::Instance' Properties: ImageId: !Ref test
パラメータ定義を検証
- サポートされている以下のプロパティのいずれかに Type を設定します:
- 文字列、数値、リスト、またはカンマ区切りリスト
- AWS 固有のパラメータタイプ
- SSM パラメータタイプ
- CloudFormation テンプレートにおいて、パラメータに次の許可されたプロパティのみが含まれていることを確認します。許可されたプロパティの詳細については、[プロパティ] を参照してください。
- CloudFormation テンプレートにおいて、パラメーターセクションに組み込み関数が含まれていないことを確認します。
次の JSON テンプレートと YAML テンプレートの例では、PparameterC のデフォルト値に組み込み関数 Fn::Sub があります。この組み込み関数によって、検証エラー: 「Every Default member must be a string.」が発生します。
JSON の例 (正しくない):
{ "Parameters": { "ParameterA": { "Type": "String", "Default": "abc" }, "ParameterB": { "Type": "String", "Default": "def" }, "ParameterC": { "Type": "String", "Default": { "Fn::Sub": "${ParameterA}-${ParameterB}" } } }, "Resources": { "MyS3Bucket": { "Type": "AWS::S3::Bucket", "Properties": { "BucketName": { "Ref": "ParameterC" } } } } }
YAML の例 (正しくない):
Parameters: ParameterA: Type: String Default: abc ParameterB: Type: String Default: def ParameterC: Type: String Default: !Sub '${ParameterA}-${ParameterB}' Resources: MyS3Bucket: Type: 'AWS::S3::Bucket' Properties: BucketName: !Ref ParameterC
Conditions が文字列として指定されていることを確認する
CloudFormation テンプレートで、Conditions を文字列として指定します。
次の JSON テンプレートと YAML テンプレートの例では、リソース EC2RouteA の条件を 1 つの文字列ではなく文字列のリストとして指定しています。これらのテンプレートでは、検証エラー: 「Every Condition member must be a string.」が発生します。
JSON の例 (正しくない):
{ "Conditions": { "ConditionA": { "Fn::Not": [ { "Fn::Equals": [ "", "Sample" ] } ] }, "ConditionB": { "Fn::Not": [ { "Fn::Equals": [ "", "Sample" ] } ] } }, "Resources": { "EC2RouteA": { "Type": "AWS::EC2::Route", "Condition": [ "ConditionA", "ConditionB" ], "Properties": { ... } } } }
YAML の例 (正しくない):
Conditions: ConditionA: !Not - !Equals - '' - Sample ConditionB: !Not - !Equals - '' - Sample Resources: EC2RouteA: Type: 'AWS::EC2::Route' Condition: - ConditionA - ConditionB Properties:
このエラーを解決するには、テンプレートの Conditions セクションに ConditionsAandB を追加し、ConditionAandB を EC2RouteA リソースの条件として使用します。次の JSON テンプレートと YAML テンプレートの例を参照してください。
JSON の例 (正しい):
{ "Conditions": { "ConditionA": { "Fn::Not": [ { "Fn::Equals": [ "", "Sample" ] } ] }, "ConditionB": { "Fn::Not": [ { "Fn::Equals": [ "", "Sample" ] } ] }, "ConditionAandB": { "Fn::And": [ { "Condition": "ConditionA" }, { "Condition": "ConditionB" } ] } }, "Resources": { "EC2RouteA": { "Type": "AWS::EC2::Route", "Condition": "ConditionAandB", "Properties": { ... } } } }
YAML の例 (正しい):
Conditions: ConditionA: Fn::Not: - Fn::Equals: - '' - Sample ConditionB: Fn::Not: - Fn::Equals: - '' - Sample ConditionAandB: Fn::And: - Condition: ConditionA - Condition: ConditionB Resources: EC2RouteA: Type: AWS::EC2::Route Condition: ConditionAandB Properties:
リソースタイプの可用性を確認する
1.リソースが AWS リージョンで利用可能であることを確認します。
すべての AWS リージョンですべてのリソースタイプを利用できるわけではありません。お使いの AWS リージョンでは利用できないリソースタイプを含むテンプレートでは: 「Unrecognized resource types: [XXXXXXXX]」エラーが発生します。
2.テンプレートがサーバーレスリソースで構成されている場合は、Transform 宣言を含めてください。次の JSON テンプレートと YAML テンプレートの例を参照してください。
JSON の例:
{ "Transform": "AWS::Serverless-2016-10-31", #Please make sure to include this. "Resources": { "MyServerlessFunctionLogicalID": { "Type": "AWS::Serverless::Function", "Properties": { "Handler": "index.handler", "Runtime": "nodejs8.10", "CodeUri": "s3://testBucket/mySourceCode.zip" } } } }
YAML の例:
Transform: AWS::Serverless-2016-10-31 #Please make sure to include this. Resources: MyServerlessFunctionLogicalID: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs8.10 CodeUri: 's3://testBucket/mySourceCode.zip'
リソースがスタック外にあることを確認するか、もしくは同じスタック内のリソースの依存関係を検証する
リソースまたは Amazon リソースネーム (ARN) をスタックのリソースの 1 つに CloudFormation スタックの外部にあるリソース用にハードコーディングする場合は、以下を確認してください:
- リソース名または ARN が正しい。
- リソースが存在する。
- リソースがスタックと同じ AWS リージョンに存在する。一部のリソースは AWS リージョンまたはアカウント全体のプロパティを受け入れることを考慮してください。
例えば、セキュリティグループ (sg-1234567890) を指定するスタック内の AWS::EC2::インスタンスリソースは、次の場合に失敗します。もし:
- セキュリティグループが存在しない場合。
- セキュリティグループがスタックの AWS リージョンに存在しない場合。
結果として、 「The sg-1234567890 does not exist.」というエラーメッセージが表示されます。 以下の例を参照してください:
LinuxInstance: Type: AWS::EC2::Instance Properties: SubnetId: !Ref ServerSubnetID KeyName: !Ref EC2KeyPairName SecurityGroupIds: sg-1234567890 #<This resource must exist and be in the same AWS Region as the stack.>
テンプレートプロパティを確認する
CloudFormation テンプレートでは、許可されたテンプレートプロパティのみを使用してください。
次の JSON テンプレートと YAML テンプレートの例では、バケットリソースを [Resources] セクションと同じレベルに設定します。これにより、次のエラーが返されます: 「Template validation error: Invalid template property or properties [Bucket].」 このエラーは、CloudFormation テンプレート検証ツールがバケットリソースをセクションレベルの仕様として認識した場合に発生します。セクションレベルの仕様はテンプレートプロパティとして使用できません。
JSON の例 (正しくない):
{ "Resources": { "WaitCondition": { "Type": "AWS::CloudFormation::WaitCondition" } }, #<There is an extra '}' causing the Resources section to be closed off after the WaitCondition resource.> "Bucket": { "Type": "AWS::S3::Bucket", "Properties": { "Name": "BucketName" } } }
YAML の例 (正しくない):
Resources: WaitCondition: Type: AWS::CloudFormation::WaitCondition Bucket: # <The spacing for the entire Bucket resource is incorrect and needs to be shifted 2 spaces to the right.> Type: AWS::S3::Bucket Properties: Name: BucketName
この問題を解決するには、バケットリソースが [Resources] セクション内で指定されるようにフォーマットを修正してください。正しくフォーマットされた以下の JSON および YAML テンプレートの例を参照してください。
JSON の例 (正しい):
{ "Resources": { "WaitCondition": { "Type": "AWS::CloudFormation::WaitCondition" }, "Bucket": { "Type": "AWS::S3::Bucket", "Properties": { "Name": "BucketName" } } } }
YAML の例 (正しい):
Resources: WaitCondition: Type: 'AWS::CloudFormation::WaitCondition' Bucket: Type: 'AWS::S3::Bucket' Properties: Name: BucketName
すべての IAM ポリシー関連リソースのポリシー構文を確認する
Identity and Access Management (IAM) ポリシーリソースまたはリソースプロパティに関連する設定を作成する場合は、ポリシーがこの構造ベースで有効であることを確認してください。
{ "Resources": { "Policy": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyName": "IamPolicyName", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "effect", "Action": [ "<service>:<API_action>", "<...>" ], "Resource": "desiredResourceARN", "Condition": { "ConditionConfiguration": { "conditionKey": [ "values" ] }, "ConditionConfiguration2": "<...>" } } ] } } } } }
注:** は任意のサービス名に<service>置き換えてください。 は、選択したサービスの API アクションに<APIaction>**置き換えてください。詳細については、「IAM JSON ポリシー」を参照してください。
JSON ポリシードキュメントを YAML フォーマットと統合する
CloudFormation をプロビジョニングするために、JSON ポリシードキュメントを YAML 形式のテンプレートと統合したい場合があります。そのためには、テンプレート内での文書の表示方法を変更する必要があります。
統合後、ポリシー要素は以下のようになります:
Resources: Policy: Type: 'AWS::IAM::Policy' Properties: PolicyName: IamPolicyName PolicyDocument: Version: 2012-10-17 Statement: - Effect: effect Action: - '<service>:<API_action>' - <...> Resource: desiredResourceARN Condition: ConditionConfiguration: conditionKey: - values ConditionConfiguration2: <...>