CloudFormation에서 템플릿 검증 또는 템플릿 형식 오류를 해결하려면 어떻게 해야 하나요?

8분 분량
0

AWS CloudFormation 템플릿을 검증하여 구문 오류가 없는지 확인하려 합니다.

간략한 설명

수신한 오류 메시지를 기반으로 다음 해결 방법 중 하나를 선택합니다.

  • "JSON not well-formed" 또는 "YAML not well-formed" 오류에 대해서는 템플릿 구문 유효성 검사 섹션을 참조하세요.
  • "Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template" 오류에 대해서는 논리적 ID 및 파라미터 검증 섹션을 참조하세요.
  • "Unrecognized parameter type: “XXXXXXXX” 또는 "Invalid template parameter property 'XXXXXXXX'" 오류는 파라미터 정의 유효성 검사 섹션을 참조하세요.
  • "Every Condition member must be a string" 오류에 대해서는 조건이 문자열로 지정되었는지 확인 섹션을 참조하세요.
  • "Unrecognized resource types: [XXXXXXXX]" 오류에 대해서는 리소스 유형의 가용성 확인 섹션을 참조하세요.
  • "The [environmental resource] 'XXXXXXXX' does not exist" 오류에 대해서는 리소스가 스택 외부에 존재하는지 확인 또는 동일한 스택에 있는 리소스에 대한 종속성 검증 섹션을 참조하세요.
  • "Invalid template property or properties [XXXXXXXX]" 오류에 대해서는 템플릿 속성 확인 섹션을 참조하세요.
  • "Invalid policy syntax" 또는 "MalformedPolicy" 오류에 대해서는 IAM 정책 관련 리소스의 정책 구문 확인 섹션을 참조하세요.

해결 방법

AWS Command Line Interface(AWS CLI) 명령 실행 시 오류가 발생하는 경우, AWS CLI 오류 문제 해결을 참고하세요. 또한 최신 AWS CLI 버전을 사용하고 있는지 확인하세요.

템플릿 구문 검증

CloudFormation 템플릿에서 적절한 JSON 또는 YAML 구문을 따르려면 다음을 고려하세요.

논리적 ID 및 파라미터 검증

템플릿에 리소스 논리적 ID와 파라미터가 정의되어 있는지 확인합니다.

다음 JSON 및 YAML 템플릿에서는 ImageId 속성에 대한 test가 참조됩니다. 하지만 템플릿에는 리소스 논리적 ID나 test라는 파라미터가 포함되어 있지 않습니다. 이러한 템플릿은 다음과 같은 오류를 반환합니다. "Unresolved resource dependencies [test] in the Resources block of the template." 리소스 정의 및 해당 구문에 대한 자세한 내용은 리소스를 참조하세요.

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 템플릿에는 ImageId를 값으로 하는 test라는 이름의 파라미터가 포함됩니다.

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

파라미터 정의 검증

  1. Type을 다음과 같은 지원되는 속성 중 하나로 설정합니다.
  2. CloudFormation 템플릿에서 파라미터에 다음과 같은 허용된 속성만 포함되어 있는지 확인하세요. 허용된 속성에 대한 자세한 내용은 속성을 참조하세요.
  3. CloudFormation 템플릿에서 파라미터 섹션에 내장 함수가 포함되어 있지 않은지 확인하세요.

다음 예시 JSON 및 YAML 템플릿에서 ParameterC의 기본 값은 내장 함수 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

조건이 문자열로 지정되었는지 확인

CloudFormation 템플릿에서 Conditions를 문자열로 지정합니다.

다음 예시 JSON 및 YAML 템플릿에서는 EC2RouteA 리소스의 조건을 단일 문자열이 아닌 문자열 목록으로 지정합니다. 이러한 템플릿으로 인해 다음과 같은 검증 오류가 발생합니다. "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:

이 오류를 해결하려면 ConditionAandB를 템플릿의 Conditions 섹션에 추가한 다음, ConditionAandBEC2RouteA 리소스에 대한 조건으로 사용하세요. 다음 예시 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) 을 CloudFormation 스택 외부에 있는 스택의 리소스 중 하나에 하드코딩하는 경우 다음을 확인하세요.

  • 리소스 이름 또는 ARN이 정확합니다.
  • 리소스가 존재합니다.
  • 리소스가 스택과 동일한 AWS 리전에 있습니다. 일부 리소스는 여러 AWS 리전 또는 계정에 걸친 속성을 허용한다는 점을 고려하세요.

예를 들어, 보안 그룹(sg-1234567890)을 지정하는 스택의 AWS::EC2::Instance 리소스는 다음과 같은 경우에 실패합니다.

  • 해당 보안 그룹이 존재하지 않습니다.
  • 해당 보안 그룹이 이 스택의 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 템플릿은 리소스 섹션과 동일한 수준에서 버킷 리소스를 설정합니다. 그러면 다음과 같은 오류가 반환됩니다. "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

이 문제를 해결하려면 리소스 섹션 내에 버킷 리소스가 지정되도록 형식을 수정하세요. 올바른 형식의 다음 예시 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: <...>
AWS 공식
AWS 공식업데이트됨 한 달 전