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

최종 업데이트 날짜: 2021년 6월 25일

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" or "Invalid template parameter property 'XXXXXXXX'" 오류의 경우 파라미터 정의 확인 섹션을 참조하십시오.
  • "Every Condition member must be a string" 오류의 경우 조건이 문자열로 지정되어 있는지 확인 섹션을 참조하십시오.
  • "Unrecognized resource types: [XXXXXXXX]" 오류의 경우 리소스 유형의 가용성 확인 섹션을 참조하십시오.
  • "Encountered unsupported property XXXXXXXX" 오류의 경우는 속성, 값 및 값 유형 확인 섹션을 참조하십시오.
  • "The [environmental resource] 'XXXXXXXX' does not exist" 오류의 경우 리소스가 스택 외부에 있는지 확인 또는 동일한 스택의 리소스에 대한 종속성 확인 섹션을 참조하십시오.
  • "At least one Resources member must be defined" 오류의 경우 템플릿에 리소스 섹션 포함 섹션을 참조하십시오.
  • "Invalid template property or properties [XXXXXXXX]" 오류의 경우 템플릿 속성 확인 섹션을 참조하십시오.

해결 방법

참고: AWS 명령줄 인터페이스(AWS CLI) 명령줄을 실행할 때 오류가 발생할 경우 AWS CLI의 가장 최신 버전을 사용하고 있는지 확인하세요.

템플릿 구문 확인

CloudFormation 템플릿에서 올바른 JSON 또는 YAML 구문을 따르려면 다음을 고려합니다.

논리적 및 물리적 ID 확인

1.    리소스 논리 ID가 템플릿에 정의되어 있는지 확인합니다.

2.    리소스 물리적 ID가 환경에 있는지 확인합니다.

예를 들어 다음 JSON 및 YAML 템플릿의 imageID 속성에 test가 참조됩니다. 두 템플릿 중 어디에도 이름이 test인 리소스 논리적 ID나 파라미터가 없습니다.

다음 JSON 및 YAML 템플릿에는 리소스 ID가 올바르게 정의되어 있지 않습니다. 이러한 템플릿은 "Unresolved resource dependencies [test] in the Resources block of the template”이라는 오류를 반환합니다. 리소스 정의 및 해당 구문에 대한 자세한 내용은 리소스를 참조하십시오.

JSON:

{
  "Parameters" : { ... },
  "Resources" : {
    "EC2Instance01" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : {"Ref": "test"},
        ...
      }
    }
  }
}

YAML:

Parameters:
Resources:
  EC2Instance01:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref: test

파라미터 정의 확인

1.    TypeString, Number, List<Number> 또는 CommaDelimitedList 속성 중 하나로만 설정합니다.

참고: 이러한 속성에는 AWS 관련 파라미터 유형 및 AWS Systems Manager 에이전트(SSM 에이전트) 파라미터 유형이 포함됩니다.

2.    CloudFormation 템플릿에서 파라미터에 다음과 같은 허용되는 속성만 포함되어 있는지 확인합니다.

"Parameters" : {
  "ParameterName" : {
    "AllowedPattern" : "A regular expression that represents the patterns to allow for String types.",
    "AllowedValues" : "An array containing the list of values allowed for the parameter",
    "ConstraintDescription" : "A string that explains a constraint when the constraint is violated"
    "Default" : "A value of the appropriate type for the template to use if no value is specified when a stack is created. If you define constraints for the parameter, you must specify a value that adheres to those constraints",
    "Description" : "A string of up to 4000 characters that describes the parameter",
    "MaxLength" : "An integer value that determines the largest number of characters you want to allow for String types",
    "MaxValue" : "A numeric value that determines the largest numeric value you want to allow for Number types.",
    "MinLength" : "An integer value that determines the smallest number of characters you want to allow for String types.",
    "MinValue" : "A numeric value that determines the smallest numeric value you want to allow for Number types.",
    "NoEcho" : "Whether to mask the parameter value when a call is made that describes the stack.
                 If you set the value to true, the parameter value is masked with asterisks (*****).",
    "Type" : "The data type for the parameter (DataType)."
 },

3.    CloudFormation 템플릿에서 [파라미터(Parameters)] 섹션에 내장 함수가 포함되지 않았는지 확인합니다.

예를 들어, 다음과 같은 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를 추가하고 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 리전에서 사용할 수 없습니다. 예를 들어 다음과 같은 JSON 및 YAML 템플릿의 리소스 유형 AWS::WAFRegional::IPSet은 현재 ap-south-1 리전에서 사용할 수 없습니다. 이러한 템플릿은 "Unrecognized resource types: [XXXXXXXX]."라는 오류를 유발합니다.

JSON:

{
  "IPSetlistA": {
    "Type": "AWS::WAFRegional::IPSet",
    "Properties": {
      "Name": "IPSet for IP addresses that are not allowed",
      "IPSetDescriptors": [
        {
          "Type": "IPV4",
          "Value": "x.x.x.x/x"
        },
        {
          "Type": "IPV4",
          "Value": "x.x.x.x/x"
        }
      ]
    }
  }
}

YAML:

IPSetlistA:
 Type: 'AWS::WAFRegional::IPSet'
 Properties:
  Name: IPSet for IP addresses that are not allowed
  IPSetDescriptors:
   - Type: IPV4
    Value: x.x.x.x/x
   - Type: IPV4
    Value: x.x.x.x/x

참고: CloudFormation 템플릿은 JSON 또는 YAML 표준을 준수하는 형식을 사용하여 텍스트 파일로 저장됩니다. 앞에서 소개한 JSON 및 YAML 템플릿에는 동일하지만 형식이 서로 다른 템플릿이 사용됩니다. YAML 지원에 대한 자세한 내용은 템플릿 기본 사항 알아보기, AWS CloudFormation Update – YAML, Cross-Stack References, Simplified Substitution을 참조하십시오.

2.    템플릿이 서버리스 리소스로 구성된 경우 Transform 선언을 포함합니다. 다음의 JSON 및 YAML 예제를 참조하십시오.

JSON:

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

속성, 값 및 값 유형 확인

템플릿 섹션 및 리소스 정의에 유효한 속성, 값 및 값 유형을 사용합니다.

리소스가 스택 외부에 있는지 확인 또는 동일한 스택의 리소스에 대한 종속성 확인

리소스 또는 CloudFormation 스택 외부에 있는 리소스의 Amazon 리소스 이름(ARN)을 스택의 리소스 중 하나로 하드코딩 하는 경우 다음을 확인합니다.

  • 리소스 이름 또는 ARN이 올바르지 여부
  • 리소스가 존재하는지 여부
  • 리소스가 스택과 동일한 AWS 리전에 있는지 여부 일부 리소스가 여러 AWS 리전 또는 계정에서 속성을 받는다는 점을 고려하십시오.

예를 들어 보안 그룹이 없거나 보안 그룹(sg-1234567890)을 지정하는 스택의 AWS::EC2::Instance 리소스에 대한 스택의 AWS 리전에 존재하지 않는 경우, AWS::EC2::Instance 리소스가 실패합니다. "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 템플릿에 Resources 섹션을 포함해야 합니다. 그렇지 않으면 오류가 발생합니다.

템플릿 속성 확인

CloudFormation 템플릿에서 허용된 템플릿 속성만 사용합니다.

다음 JSON 및 YAML 예제에서 버킷 리소스는 [리소스(Resources)] 섹션과 동일한 수준에 있습니다. 이렇게 하면 "Template validation error: Invalid template property or properties [Bucket]." 오류가 반환됩니다. 이 오류는 CloudFormation 템플릿 검사기가 버킷 리소스를 템플릿 속성으로서 허용되지 않는 섹션 수준의 사양으로 인식하기 때문에 발생합니다.

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

참고: 앞서 설명한 JSON 및 YAML 템플릿에서 BucketName을 버킷 이름으로 바꿉니다.


이 문서가 도움이 되었나요?


결제 또는 기술 지원이 필요하세요?