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]" 오류의 경우 템플릿 속성 확인 섹션을 참조하십시오.

해결 방법

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

템플릿 구문 확인

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

논리 ID 및 파라미터 검증

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

다음 JSON 및 YAML 템플릿에서 testimageID 속성에 참조됩니다. 하지만 두 템플릿 중 어디에도 이름이 test인 리소스 논리적 ID나 파라미터가 없습니다. 이러한 템플릿은 "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 템플릿에는 이름이 testimageID인 값이 지정된 파라미터가 포함되어 있습니다.

예제 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 템플릿에서 파라미터에 다음과 같은 허용되는 속성만 포함되어 있는지 확인합니다.

"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을 템플릿의 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 리전 또는 계정에서 속성을 받는다는 점을 고려하십시오.

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

  • 보안 그룹이 존재하지 않습니다.
  • 보안 그룹이 스택의 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

AWS 공식
AWS 공식업데이트됨 6달 전