スキップしてコンテンツを表示

CloudFormation のテンプレートの検証エラーまたは形式エラーの解決策を教えてください。

所要時間5分
0

AWS CloudFormation テンプレートを検証して、構文エラーがないことを確認したいです。

解決策

注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI のエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。

表示されたエラーメッセージに基づいて、次のタスクを実行します。

"JSON not well-formed" または "YAML not well-formed" エラー

CloudFormation テンプレートの形式を正しく整えなかった場合、次のいずれかのエラーメッセージが表示されます。

"JSON not well-formed"

"YAML not well-formed"

CloudFormation テンプレートの JSON または YAML 構文のベストプラクティスに必ず従ってください。このエラーを解決するには、次の手順を実行します。

  • Infrastructure Composer でスタックを作成します。
  • AWS CLI コマンド validate-template を使用して JSON と YAML 構文を検証します。
  • AWS CloudFormation リンターを使用して JSON または YAML テンプレートを検証するには、GitHub ウェブサイトの cfn-lint を参照してください。

"Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template" エラー

CloudFormation テンプレートでリソースの論理 ID またはパラメータが指定されていない場合、次のエラーメッセージが表示されます。

"Unresolved resource dependencies [test] in the Resources block of the template."

このエラーを解決するには、リソースの論理 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

"Unrecognized parameter type: XXXXXXXX" または "Invalid template parameter property 'XXXXXXXX'" エラー

JSON テンプレートと YAML テンプレートに ParameterC のデフォルト値が組み込み関数 Fn::Sub として含まれている場合、次のエラーメッセージが表示されます。

"Every Default member must be a string."

パラメータは組み込み関数をサポートしていません。Fn::Sub 関数を使用して、ParameterA 値と ParameterB 値を指定します。このエラーを解決するには、ParameterC を削除します。

CloudFormation テンプレートから ParameterC を削除するには、以下の手順を実行します。

  1. Type を、サポートされている次のプロパティのいずれかに設定します: StringNumberList、または CommaDelimitedList
  2. パラメータに許可されたプロパティのみが含まれていることを確認します。
  3. [Parameters] セクションに組み込み関数が含まれていないことを確認します。

JSON の例:

{
  "Parameters": {
    "ParameterA": {
      "Type": "String",
      "Default": "abc"
    },
    "ParameterB": {
      "Type": "String",
      "Default": "def"
    }
  },
  "Resources": {
    "MyS3Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": {
          "Fn::Sub": "${ParameterA}-${ParameterB}"
        }
      }
    }
  }
}

YAML の例:

Parameters:
 ParameterA:
  Type: String
  Default: abc
 ParameterB:
  Type: String
  Default: def
Resources:
 MyS3Bucket:
  Type: 'AWS::S3::Bucket'
  Properties:
   BucketName: !Sub ${ParameterA}-${ParameterB}

"Every Condition member must be a string" エラー

JSON テンプレートと YAML テンプレートでは、リソース EC2RouteA条件を 1 つの文字列ではなく文字列のリストとして指定する場合があります。その場合、次のエラーメッセージが表示されます。

"Every Condition member must be a string."

このエラーを解決するには、テンプレートの [Conditions] セクションに ConditionAandB を追加します。次に、ConditionAandBEC2RouteA リソースの条件として使用します。

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:

"Unrecognized resource types: [XXXXXXXX]" エラー

すべての AWS リージョンですべてのリソースタイプを利用できるわけではありません。テンプレートに、ご利用のリージョンでは利用できないリソースタイプが含まれている場合、次のエラーメッセージが表示されます。

"Unrecognized resource types: [XXXXXXXX]."

このエラーを解決するには、リソースがご利用のリージョンで利用可能であることを確認してください。テンプレートがサーバーレスリソースで構成されている場合は、Transform 宣言を含めてください。

JSON の例:

{
    "Transform": "AWS::Serverless-2016-10-31", #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 #Make sure to include this.
Resources:
  MyServerlessFunctionLogicalID:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs8.10
      CodeUri: 's3://testBucket/mySourceCode.zip'

"The [environmental resource] 'XXXXXXXX' does not exist" エラー

スタックの AWS::EC2::Instance リソースがセキュリティグループを指定している場合、次のエラーメッセージが表示されます。

"The sg-1234567890 does not exist."

セキュリティグループが存在しない場合、またはセキュリティグループがスタックのリージョンに存在しない場合、スタックは失敗します。このエラーを解決するには、テンプレートに SecurityGroupIDs を追加します。

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.>

リソースまたは Amazon リソースネーム (ARN) をスタックのリソースの 1 つに CloudFormation スタックの外部にあるリソース用にハードコーディングする場合は、以下を確認してください。

  • リソース名または ARN が正しい。
  • リソースが存在する。
  • リソースがスタックと同じリージョンに存在する。一部のリソースは、リージョンやアカウントをまたいでプロパティを受け入れます。

"Invalid template property or properties [XXXXXXXX]" エラー

バケットリソースを JSON テンプレートおよび YAML テンプレートの [Resources] セクションと同じレベルに設定すると、次のエラーメッセージが表示されます。

"Template validation error: Invalid template property or properties [Bucket]."

このエラーは、CloudFormation テンプレート検証ツールがバケットリソースをセクションレベルの仕様として認識した場合に発生します。セクションレベルの仕様はテンプレートプロパティとして使用できません。CloudFormation テンプレートでは、許可されたテンプレートプロパティのみを使用するのがベストプラクティスです。

このエラーを解決するには、[Resources] セクション内でバケットリソースを指定します。

JSON の例:

{
  "Resources": {
    "WaitCondition": {
      "Type": "AWS::CloudFormation::WaitCondition"
    },
    "Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "Name": "BucketName"
      }
    }
  }
}

注: BucketName を実際のバケット名に置き換えてください。

YAML の例:

Resources:
  WaitCondition:
    Type: 'AWS::CloudFormation::WaitCondition'
  Bucket:
    Type: 'AWS::S3::Bucket'
    Properties:
      Name: BucketName

注: BucketName を実際のバケット名に置き換えてください。

"Invalid policy syntax" または "MalformedPolicy" エラー

ID ポリシー、リソースポリシー、サービスコントロールポリシー、またはリソースコントロールポリシーを作成する場合、検証は 2 つのステップに分かれています。これらのステップには、AWS Identity and Access Management (IAM) 検証と CloudFormation 検証が含まれます。

ポリシーを検証するには、ポリシーを作成し、次の AWS CLI コマンド validate-policy を実行します。

➜  aws accessanalyzer validate-policy --policy-document file://policy-document.json --policy-type IDENTITY_POLICY

注: policy-document.json を JSON ファイルへのファイルパスに置き換えてください。

AWS CLI コマンド validate-policy を実行すると、"Invalid policy syntax" または "MalformedPolicy" というエラーメッセージが表示されます。この問題を解決するには、[Action]s3:DeleteObject に変更し、コマンドを再実行します。

JSON の例:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyObjectDeletionForAllExceptRolePrefix",
      "Effect": "Deny",
      "Action": [
        "s3:DeleteObject",
        "s3:DeleteObjectVersion",
        "s3:PutLifecycleConfiguration"
      ],
      "Resource": ["arn:aws:s3:::BUCKET_NAME/*"]
    }
  ]
}

注: BUCKET_NAME を実際のバケット名に置き換えてください。

検証済みのポリシーを CloudFormation テンプレートに追加し、パラメータまたはリソースを指定します。

サブ関数がテンプレートに存在しないパラメータを参照する場合、次のエラーメッセージが表示されます。

"An error occurred (ValidationError) when calling the ValidateTemplate operation: Template format error: Unresolved resource dependencies [Bucket] in the Resources block of the template"

このエラーを解決するには、テンプレート内の [Resource]arn:aws:s3:::${BucketName}/* に更新します。

JSON の例:

{
  "Parameters": {
    "BucketName": {
      "Type": "String"
    },
    "RoleName": {
      "Type": "String"
    }
  },
  "Resources": {
    "ManagedPolicy": {
      "Type": "AWS::IAM::ManagedPolicy",
      "Properties": {
        "Roles": [
          {
            "Ref": "RoleName"
          }
        ],
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "DenyObjectDeletionForAllExceptRolePrefix",
              "Effect": "Deny",
              "Action": [
                "s3:DeleteObject",
                "s3:DeleteObjectVersion",
                "s3:PutLifecycleConfiguration"
              ],
              "Resource": [
                {
                  "Fn::Sub": "arn:aws:s3:::${BucketName}/*"
                }
              ]
            }
          ]
        }
      }
    }
  }
}

注: BucketName を実際のバケット名に置き換えてください。

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_action を選択したサービスの API アクションに置き換えてください。詳細については、「IAM JSON ポリシー要素のリファレンス」を参照してください。

JSON ポリシードキュメントを YAML フォーマットテンプレートと統合する

JSON ポリシードキュメントを YAML フォーマットテンプレートと統合して CloudFormation をプロビジョニングする場合、テンプレートでのドキュメントの表示方法を変更できます。これにより、YAML ブロックと JSON ブロックが混在することを回避できます。統合後、ポリシー要素は次のテンプレート例のようになります。

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: <...>

注: IamPolicyName を実際の IAM ポリシー名に置き換えてください。

コメントはありません

関連するコンテンツ