Skip to content

템플릿 기본 사항 알아보기


시작하기에서는 템플릿을 사용하여 스택을 생성하는 방법을 배웠다. 템플릿에 선언된 리소스와 이들 리소스를 스택의 리소스로 매핑하는 방법에 대해 살펴보았다. 입력 파라미터와 템플릿에서 스택 생성 시 이러한 파라미터를 사용하여 특정 값을 전달하는 방법도 살펴보았다. 이 섹션에서는 리소스와 파라미터에 대해 좀더 자세히 살펴본다. 또한 이러한 구성 요소를 함께 사용하여 원하는 AWS 리소스를 생성하는 템플릿을 작성하는 방법을 알 수 있도록 템플릿의 다양한 구성 요소도 살펴본다.


1. AWS CloudFormation 템플릿이란 무엇인가요?

템플릿이란 스택을 구성하는 AWS 리소스를 선언한 것이다. 템플릿은 JavaScript Object Notation(JSON) 또는 YAML 표준을 준수하는 형식의 텍스트 파일로 저장된다. 템플릿은 텍스트 파일에 불과하기 때문에 텍스트 편집기에서 작성 및 편집하고 소스 코드의 나머지 부분과 함께 소스 제어 시스템에서 관리할 수 있다. 템플릿 형식에 대한 자세한 내용은 AWS CloudFormation 템플릿 형식 단원을 참조한다.

생성 및 구성할 AWS 리소스를 템플릿에서 선언한다. 객체를 이름-값 페어 또는 이름과 포함된 자식 객체 세트 페어로 선언한다. 구문은 사용하는 형식에 따라 다르다. 자세한 내용은 템플릿 구조를 참조한다. 필요한 최상위 객체는 Resources 객체뿐이며, 하나 이상의 리소스를 선언해야 한다. Resources 객체만을 포함하는 가장 기본적인 수준의 템플릿으로 시작한다. 이 템플릿에는 단일 리소스 선언만 들어 있다.


2. Resources: Hello Bucket

Resources 객체에는 리소스 객체 목록이 포함된다. 리소스 선언에는 리소스의 속성이 포함되는데, 이러한 속성은 자식 객체로 자체 선언된다. 리소스에는 Type 속성이 지정되어야 하며, 이 속성은 생성할 AWS 리소스의 종류를 정의한다. Type 속성은 특수한 형식으로 되어 있다.

AWS::ProductIdentifier::ResourceType

예를 들면 Amazon S3 버킷의 리소스 유형은 AWS::S3::Bucket이다. 전체 리소스 유형 목록은 템플릿 참조 단원을 참조한다.

기본 템플릿을 살펴본다. 다음 템플릿은 HelloBucket 이름을 사용하여 AWS::S3::Bucket: 형식의 단일 리소스를 선언한다.

JSON

{
    "Resources" : {
        "HelloBucket" : {
            "Type" : "AWS::S3::Bucket"
        }
    }
}

YAML

Resources:
  HelloBucket:
    Type: AWS::S3::Bucket

이 템플릿을 사용하여 스택을 생성할 경우 AWS CloudFormation에서는 Amazon S3 버킷을 생성한다. CloudFormation에서는 기본 설정을 사용하여 버킷을 생성할 수 있으므로 버킷을 간단히 생성할 수 있다. Amazon EC2 Auto Scaling 그룹이나 EC2 인스턴스 같은 기타 리소스의 경우 CloudFormation은(는) 추가 정보를 요구한다. 리소스 선언에서는 Properties 속성을 사용하여 리소스 생성을 위한 정보를 지정한다.

리소스 유형에 따라, AWS::EC2::Instance 리소스의 경우 ImageId 등 일부 속성은 필수 속성이고 그 밖의 속성은 선택적 속성이다. AWS::S3::Bucket 리소스의 AccessControl 등 일부 속성에는 기본값이 있으므로, 이러한 속성에는 선택적으로 값을 지정할 수 있다. 그 밖의 속성은 필수는 아니지만, AWS::S3::Bucket 리소스의 WebsiteConfiguration 속성과 같이 원하는 기능을 추가하기도 한다. 이러한 속성에 대한 값은 반드시 지정할 필요는 없으며, 필요에 따라 지정하면 된다. 위의 예제에서 AWS::S3::Bucket 리소스에는 선택적 속성만 포함되어 있으며 우리에게는 선택적 기능이 필요하지 않으므로 기본값을 그대로 사용하고 Properties 속성을 생략할 수도 있다.

각 리소스 유형에 대한 속성을 보려면 AWS 리소스 및 속성 유형 참조 단원의 주제를 참조한다.


3. 리소스 속성과 여러 리소스를 함께 사용

일반적으로 리소스 속성은 단순 문자열 값이다. 예를 들면 다음 템플릿은 버킷의 AccessControl 속성에 대해 미리 준비된 ACL(PublicRead)을 지정한다.

JSON

{
    "Resources" : {
        "HelloBucket" : {
            "Type" : "AWS::S3::Bucket",
            "Properties" : {
               "AccessControl" : "PublicRead"
            }
        }
    }
}

YAML

Resources:
  HelloBucket:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: PublicRead

일부 리소스에는 여러 속성을 지정할 수 있으며, 또 다른 일부 속성에는 하나 이상의 하위 속성을 지정할 수도 있다. 예를 들면 AWS::S3::Bucket 리소스에는 AccessControl 속성과 WebsiteConfiguration 속성이라는 두 가지 속성이 지정되어 있다. WebsiteConfiguration 속성에는 IndexDocument 및 ErrorDocument라는 두 가지 하위 속성이 있다. 다음 템플릿은 추가 속성이 지정된 원래 버킷 리소스를 표시한다.

JSON

{
    "Resources" : {
        "HelloBucket" : {
            "Type" : "AWS::S3::Bucket",
            "Properties" : {
               "AccessControl" : "PublicRead",
               "WebsiteConfiguration" : {
                    "IndexDocument" : "index.html",
                    "ErrorDocument" : "error.html"
               }
            }
        }
    }
}

YAML

Resources:
  HelloBucket:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html

템플릿 및 CloudFormation의 가장 큰 이점 중 하나는 함께 작동하는 리소스 세트를 만들어서 애플리케이션이나 솔루션을 생성할 수 있다는 점이다. 템플릿 내 리소스에 사용되는 이름은 논리적 이름이다. CloudFormation에서는 리소스 생성 시 논리적 이름, 스택 이름 및 고유 ID의 조합에 기초한 물리적 이름을 생성한다.

다른 리소스의 이름이나 속성에 기초하여 한 리소스에 대한 속성을 설정하는 방법이 궁금할 것이다. 예를 들면 S3 버킷이 지원하는 CloudFront 배포 또는 EC2 보안 그룹을 사용하는 EC2 인스턴스와 이러한 모든 리소스를 동일한 템플릿 안에서 만들 수 있다. CloudFormation에는 다른 리소스와 관련 속성을 참조하는 데 사용할 수 있는 내장 함수가 있다. Ref 함수를 사용하여 리소스의 식별 속성을 참조할 수 있다. 대체로 이 속성은 리소스의 물리적 이름이지만, 경우에 따라서 AWS::EC2::EIP 리소스용 IP 주소나 Amazon SNS 주제에 대한 Amazon 리소스 이름(ARN) 등 식별자일 수도 있다. Ref 함수에서 반환되는 값 목록은 Ref 함수를 참조한다. 다음 템플릿에는 AWS::EC2::Instance 리소스가 포함되어 있다. 이 리소스의 SecurityGroups 속성은 Ref 함수를 호출하여 AWS::EC2::SecurityGroup 리소스 InstanceSecurityGroup을 참조한다.

JSON

{
    "Resources": {
        "Ec2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "SecurityGroups": [
                    {
                        "Ref": "InstanceSecurityGroup"
                    }
                ],
                "KeyName": "mykey",
                "ImageId": ""
            }
        },
        "InstanceSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable SSH access via port 22",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 22,
                        "ToPort": 22,
                        "CidrIp": "0.0.0.0/0"
                    }
                ]
            }
        }
    }
}

YAML

Resources:
  Ec2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      SecurityGroups:
        - !Ref InstanceSecurityGroup
      KeyName: mykey
      ImageId: ''
  InstanceSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: Enable SSH access via port 22
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0

SecurityGroups 속성은 보안 그룹 목록이며, 이전 예제에서는 이 목록에 항목이 하나만 들어 있었다. 다음 템플릿에는 SecurityGroups 속성 목록에 추가 항목이 있다.

JSON

{
    "Resources": {
        "Ec2Instance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "SecurityGroups": [
                    {
                        "Ref": "InstanceSecurityGroup"
                    },
                    "MyExistingSecurityGroup"
                ],
                "KeyName": "mykey",
                "ImageId": "ami-7a11e213"
            }
        },
        "InstanceSecurityGroup": {
            "Type": "AWS::EC2::SecurityGroup",
            "Properties": {
                "GroupDescription": "Enable SSH access via port 22",
                "SecurityGroupIngress": [
                    {
                        "IpProtocol": "tcp",
                        "FromPort": 22,
                        "ToPort": 22,
                        "CidrIp": "0.0.0.0/0"
                    }
                ]
            }
        }
    }
}

YAML

Resources:
  Ec2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      SecurityGroups:
        - !Ref InstanceSecurityGroup
        - MyExistingSecurityGroup
      KeyName: mykey
      ImageId: ami-7a11e213
  InstanceSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: Enable SSH access via port 22
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0

MyExistingSecurityGroup은 템플릿에 선언된 보안 그룹 대신에 기존 EC2 보안 그룹을 참조하는 문자열이다. 리터럴 문자열을 사용하여 기존 AWS 리소스를 참조한다.

위의 예제에서 AWS::EC2::Instance의 KeyName 속성은 리터럴 문자열 mykey이다. 다시 말해서 이름 mykey를 포함하는 키 페어가 스택을 생성 중인 리전에 존재해야 한다. 그렇지 않으면 키 페어가 존재하지 않아서 스택이 생성되지 않는다. 사용하는 키 페어는 스택을 생성 중인 리전마다 다르거나, 다른 사람과 템플릿을 공유하여 그들의 AWS 계정에서 사용하도록 할 수도 있다. 이 경우, 입력 파라미터를 사용하면 스택 생성 시 키 페어 이름을 지정할 수 있다. Ref 함수는 스택 생성 시 지정되는 입력 파라미터를 참조할 수 있다. 다음 템플릿은 KeyName 파라미터를 포함하는 Parameters 객체를 추가한다. KeyName 파라미터는 AWS::EC2::Instance 리소스의 KeyName 속성을 지정하는 데 사용된다. 파라미터 유형은 AWS::EC2::KeyPair::KeyName으로, 사용자가 스택을 생성 중인 리전과 자신의 계정에서 유효한 키 페어 이름을 지정하는지 확인한다.

JSON

{
  "Parameters": {
    "KeyName": {
      "Description": "The EC2 Key Pair to allow SSH access to the instance",
      "Type": "AWS::EC2::KeyPair::KeyName"
    }
  },
  "Resources": {
    "Ec2Instance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "SecurityGroups": [
          {
            "Ref": "InstanceSecurityGroup"
          },
          "MyExistingSecurityGroup"
        ],
        "KeyName": {
          "Ref": "KeyName"
        },
        "ImageId": "ami-7a11e213"
      }
    },
    "InstanceSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription": "Enable SSH access via port 22",
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": 22,
            "ToPort": 22,
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    }
  }
}

YAML

Parameters:
  KeyName:
    Description: The EC2 Key Pair to allow SSH access to the instance
    Type: 'AWS::EC2::KeyPair::KeyName'
Resources:
  Ec2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      SecurityGroups:
        - !Ref InstanceSecurityGroup
        - MyExistingSecurityGroup
      KeyName: !Ref KeyName
      ImageId: ami-7a11e213
  InstanceSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupDescription: Enable SSH access via port 22
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0

Ref 함수는 리소스에 대해 반환되는 파라미터나 값이 정확히 원하는 값인 경우에 유용하지만, 리소스의 다른 속성이 필요할 수도 있다. 예를 들어 S3 오리진을 사용하여 CloudFront 배포를 생성하려는 경우 DNS 스타일 주소를 사용하여 버킷 위치를 지정해야 한다. 일부 리소스에는 템플릿에서 사용할 수 있는 값이 지정되는 추가 속성이 있다. 이러한 속성을 가져오려면 Fn::GetAtt 함수를 사용한다. 다음 템플릿은 Fn::GetAtt 함수를 사용하여 버킷의 DomainName 속성을 가져옴으로써 S3 버킷 리소스의 DNS 이름을 지정하는 CloudFront 배포 리소스를 생성한다.

JSON

{
  "Resources": {
    "myBucket": {
      "Type": "AWS::S3::Bucket"
    },
    "myDistribution": {
      "Type": "AWS::CloudFront::Distribution",
      "Properties": {
        "DistributionConfig": {
          "Origins": [
            {
              "DomainName": {
                "Fn::GetAtt": [
                  "myBucket",
                  "DomainName"
                ]
              },
              "Id": "myS3Origin",
              "S3OriginConfig": {}
            }
          ],
          "Enabled": "true",
          "DefaultCacheBehavior": {
            "TargetOriginId": "myS3Origin",
            "ForwardedValues": {
              "QueryString": "false"
            },
            "ViewerProtocolPolicy": "allow-all"
          }
        }
      }
    }
  }
}

YAML

Resources:
  myBucket:
    Type: 'AWS::S3::Bucket'
  myDistribution:
    Type: 'AWS::CloudFront::Distribution'
    Properties:
      DistributionConfig:
        Origins:
          - DomainName: !GetAtt
              - myBucket
              - DomainName
            Id: myS3Origin
            S3OriginConfig: {}
        Enabled: 'true'
        DefaultCacheBehavior:
          TargetOriginId: myS3Origin
          ForwardedValues:
            QueryString: 'false'
          ViewerProtocolPolicy: allow-all

Fn::GetAtt 함수는 두 개 파라미터, 리소스의 논리적 이름, 그리고 검색할 속성의 이름을 사용한다. 리소스에 사용할 수 있는 전체 속성 목록은 Fn::GetAtt를 참조한다. Fn::GetAtt 함수는 두 파라미터를 어레이 형태로 나열한다. 여러 파라미터를 사용하는 함수의 경우 어레이를 사용하여 파라미터를 지정한다.


4. 입력 파라미터를 사용하여 사용자 입력 수신

지금까지는 리소스에 대해 알아보았으며 템플릿 내에서 리소스를 함께 사용하는 방법도 조금 살펴보았다. 입력 파라미터를 참조하는 방법을 배웠지만 입력 파라미터를 자체적으로 정의하는 방법에 대해서는 아직까지 자세히 살펴보지 않았다. 이번에는 파라미터 선언과 사용자 입력을 제한하고 확인하는 방법에 대해 살펴본다.

파라미터는 템플릿의 Parameters 객체에서 선언한다. 파라미터에는 해당 값과 값에 대한 구속 조건을 정의하는 속성 목록이 포함된다. 유일한 필수 속성은 Type으로, String, Number 또는 AWS 특정 유형일 수 있다. 사용자에게 지정해야 하는 값의 종류에 대해 자세히 알려 주는 Description 속성을 추가할 수도 있다. 파라미터의 이름과 설명은 사용자가 [Create Stack] 마법사에서 템플릿을 사용할 때 [Specify Parameters] 페이지에 나타난다.

다음 템플릿 조각은 위의 [Specify Parameters] 페이지에 사용된 파라미터를 선언하는 Parameters 객체이다.

JSON

  "Parameters": {
    "KeyName": {
      "Description" : "Name of an existing EC2 KeyPair to enable SSH access into the WordPress web server",
      "Type": "AWS::EC2::KeyPair::KeyName"
    },
    "WordPressUser": {
      "Default": "admin",
      "NoEcho": "true",
      "Description" : "The WordPress database admin account user name",
      "Type": "String",
      "MinLength": "1",
      "MaxLength": "16",
      "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*"
    },
    "WebServerPort": {
      "Default": "8888",
      "Description" : "TCP/IP port for the WordPress web server",
      "Type": "Number",
      "MinValue": "1",
      "MaxValue": "65535"
    }
  }

YAML

Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access into the WordPress web server
    Type: AWS::EC2::KeyPair::KeyName
  WordPressUser:
    Default: admin
    NoEcho: true
    Description: The WordPress database admin account user name
    Type: String
    MinLength: 1
    MaxLength: 16
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
  WebServerPort:
    Default: 8888
    Description: TCP/IP port for the WordPress web server
    Type: Number
    MinValue: 1
    MaxValue: 65535

기본값이 있는 파라미터의 경우 CloudFormation에서는 사용자가 다른 값을 지정하지 않을 경우 기본값이 사용된다. 기본 속성을 생략하는 경우에는 사용자가 해당 파라미터에 대해 값을 지정해야 하지만, 사용자가 값을 입력한다고 해서 값이 반드시 유효한 것은 아니다. 파라미터 값을 검증하려는 경우 제약을 선언하거나 AWS 특정 유형을 지정할 수 있다.

KeyName 파라미터에는 Default 속성이 없지만 다른 파라미터에는 있다. WordPressUser 파라미터에는 Default: admin 속성이 없지만 KeyName 파라미터에는 있다. 사용자는 스택 생성 시 키 이름 값을 지정해야 한다. 지정하지 않을 경우 CloudFormation에서 스택을 생성할 수 없으며 예외(Parameters: [KeyName] must have values)가 발생한다.

AWS 특정 파라미터 유형의 경우, CloudFormation에서는 사용자가 스택 리소스를 생성하기 전에 사용자가 스택을 생성 중인 리전과 사용자의 AWS 계정에서 기존 값과 대조하여 입력 값을 검증한다. 동일한 템플릿에서 KeyName 파라미터는 AWS::EC2::KeyPair::KeyName의 AWS 특정 파라미터 유형이다. CloudFormation에서는 사용자가 스택 생성 전에 유효한 EC2 키 페어 이름을 지정하는지 확인한다. AWS 특정 유형의 또 한 가지 예는 AWS::EC2::VPC::Id이며 사용자는 유효한 VPC ID를 지정해야 한다. 선행 검증에 더해 AWS 콘솔은 사용자가 [스택 생성(Create Stack)] 마법사를 사용할 때 유효한 EC2 키 페어 이름이나 VPC ID 같은 AWS 특정 파라미터 유형에 대한 유효 값의 드롭다운 목록을 표시한다.

String 유형의 경우 MinLength, MaxLength, Default, AllowedValuesAllowedPattern 속성을 사용하여 제약을 선언할 수 있다. 위의 예제에서 WordPressUser 파라미터에는 세 가지 제약으로, 파라미터 값 길이는 1 ~ 16자여야 하며(MinLength, MaxLength), 문자로 시작하고 그 뒤에 문자와 숫자의 조합(AllowedPattern)이 이어져야 한다.

Number 유형의 경우 MinValue, MaxValue, DefaultAllowedValues 제약을 선언할 수 있다. 숫자는 정수 또는 부동 소수점 값일 수 있다. 위의 예제에서 WebServerPort 파라미터는 1에서 65535 사이(포함)의 정수여야 한다(MinValue, MaxValue).

이 섹션 앞부분에서, 사용해야 하지만 템플릿에 자체적으로 포함하지 않을 암호나 사용자 이름 같은 중요 또는 구현 관련 데이터를 지정하기에 파라미터가 바람직한 방법이라고 언급했다. NoEcho 속성을 true로 설정한 경우, 아래 지정된 위치에 저장된 정보를 제외하고 CloudFormation은 스택 또는 스택 이벤트를 설명하는 모든 호출에 대해 별표(*)로 마스킹 처리된 파라미터 값을 반환한다. 위의 예제에서 WordPressUser 파라미터 값은 스택 설정을 보고 있는 사람에게 표시되지 않으며, 해당 값이 별표로 반환된다.

Warning

NoEcho 속성을 사용해도 다음에 저장된 정보는 마스킹되지 않는다.

  • Metadata 템플릿 섹션이다. CloudFormation은 Metadata 섹션에 포함된 정보를 변환, 수정 또는 삭제하지 않는다. 자세한 내용은 메타데이터를 참조한다.

  • Outputs 템플릿 섹션. 자세한 내용은 출력을 참조한다.

  • 리소스 정의의 Metadata 속성이다. 자세한 내용은 메타데이터 속성을 참조한다.

이러한 메커니즘을 사용하여 암호나 보안 정보와 같은 중요한 정보를 포함하지 않는 것이 좋다.

Warning

AWS Systems Manager 파라미터 스토어 또는 AWS Secrets Manager와 같이 CloudFormation 외부에서 저장 및 관리되는 민감한 정보를 참조하려면 CloudFormation 템플릿에 직접 민감한 정보를 포함하는 대신 스택 템플릿에 있는 동적 파라미터를 사용하는 것이 좋다.

자세한 내용은 템플릿에 자격 증명을 포함하지 않음을 참조한다.


5. 매핑을 사용하여 조건 값 지정

파라미터는 사용자가 스택 리소스의 속성에서 사용해야 할 고유하거나 중요한 값을 지정할 수 있도록 하는 좋은 방법이다. 하지만 리전에 따라 설정이 달라지거나 다른 조건 또는 종속성으로 인해 사용자가 이해하기에 다소 어려울 수도 있다. 이러한 경우 사용자가 원하는 결과를 얻기 위해 보다 간단한 값을 지정할 수 있도록(또는 전혀 지정할 필요가 없도록) 템플릿에 자체적으로 논리를 추가할 수도 있다. 앞의 예제에서는 EC2 인스턴스의 ImageId 속성에 대한 AMI ID를 하드코딩했다. 이 설정은 원하는 AMI를 표현하는 미국 동부 리전에서는 문제가 되지 않는다. 그러나 사용자가 다른 리전에서 스택을 구성하려고 하면 잘못된 AMI를 받거나 AMI를 아예 받지 못한다. AMI ID가 리전마다 고유하여 다른 리전의 동일 AMI ID는 AMI를 나타내지 않거나 전혀 다른 AMI를 나타낼 수도 있기 때문이다.

이 문제를 방지하려면 조건부 입력(이 예제에서는 스택이 생성되는 리전)에 따라 올바른 AMI ID를 지정하는 방법이 필요하다. 도움이 될 수 있는 템플릿 기능 두 가지가 있으며, 각각 Mappings 객체와 AWS::Region 가상 파라미터이다.

CloudFormation 가상 파라미터는 AWS::Region에서 스택이 생성되는 리전으로 확인되는 값이다. 가상 파라미터는 스택 생성 시 CloudFormation에서 확인된다. 매핑을 사용하면 다른 값을 결정하는 조건으로서 입력 값을 사용할 수 있다. switch 문과 마찬가지로, 매핑은 값 세트 하나를 다른 세트와 연결한다. AWS::Region 파라미터와 매핑을 함께 사용하면 리전에 해당하는 AMI ID를 지정할 수 있다. 다음 템플릿에는 AMI ID를 해당 리전으로 매핑하는 데 사용되는 RegionMap이라는 매핑이 지정된 Mappings 객체가 들어 있다.

JSON

{
  "Parameters": {
    "KeyName": {
      "Description": "Name of an existing EC2 KeyPair to enable SSH access to the instance",
      "Type": "String"
    }
  },
  "Mappings": {
    "RegionMap": {
      "us-east-1": {
        "AMI": "ami-76f0061f"
      },
      "us-west-1": {
        "AMI": "ami-655a0a20"
      },
      "eu-west-1": {
        "AMI": "ami-7fd4e10b"
      },
      "ap-southeast-1": {
        "AMI": "ami-72621c20"
      },
      "ap-northeast-1": {
        "AMI": "ami-8e08a38f"
      }
    }
  },
  "Resources": {
    "Ec2Instance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "KeyName": {
          "Ref": "KeyName"
        },
        "ImageId": {
          "Fn::FindInMap": [
            "RegionMap",
            {
              "Ref": "AWS::Region"
            },
            "AMI"
          ]
        },
        "UserData": {
          "Fn::Base64": "80"
        }
      }
    }
  }
}

YAML

Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
    Type: String
Mappings:
  RegionMap:
    us-east-1:
      AMI: ami-76f0061f
    us-west-1:
      AMI: ami-655a0a20
    eu-west-1:
      AMI: ami-7fd4e10b
    ap-southeast-1:
      AMI: ami-72621c20
    ap-northeast-1:
      AMI: ami-8e08a38f
Resources:
  Ec2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      KeyName: !Ref KeyName
      ImageId: !FindInMap
        - RegionMap
        - !Ref 'AWS::Region'
        - AMI
      UserData: !Base64 '80'

RegionMap에서 각 리전은 이름-값 페어로 매핑된다. 이름-값 페어는 레이블과, 매핑할 값이다. RegionMap에서 AMI는 레이블이며 AMI ID는 값이다. 맵을 사용하여 값을 반환하려면 Fn::FindInMap 함수를 사용하여 맵의 이름, 매핑된 값을 찾는 데 사용되는 값, 그리고 반환할 매핑된 값의 레이블을 전달한다. 위의 예제에서 리소스 Ec2Instance의 ImageId 속성은 Fn::FindInMap 함수를 사용하여 RegionMap을 사용할 맵으로, AWS::Region을 매핑할 소스 입력 값으로, 그리고 AMI를 매핑할 값을 식별할 레이블로 지정하여 값을 결정한다. 예를 들어 이 템플릿이 미국 서부(캘리포니아 북부 지역) 리전에서 스택을 생성하는 데 사용된 경우 ImageId은(는) ami-655a0a20(으)로 설정된다.

Note

AWS::Region 가상 파라미터를 사용하면 스택이 생성되는 리전을 가져올 수 있다. AWS::EC2::Instance, AWS::AutoScaling::AutoScalingGroupAWS::ElasticLoadBalancing::LoadBalancer 같은 일부 리소스에는 가용 영역을 지정하는 속성이 있다. Fn::GetAZs 함수를 사용하여 리전에서 모든 가용 영역의 목록을 가져올 수 있다.


6. 구성된 값과 출력 값

파라미터와 매핑은 스택 생성 시간에 특정 값을 전달하거나 확인할 수 있는 유용한 방법이지만, 파라미터의 값이나 기타 리소스 속성이 필요한 값의 일부일 뿐인 경우가 발생할 수 있다. 예를 들어, WordPress 템플릿의 다음 조각에서 Fn::Join 함수는 필요한 값을 만들기 위해 WebServerPort 파라미터를 다른 리터럴 문자열과 연결하여 ElasticLoadBalancer 리소스에 대한 HealthCheck 속성의 Target 하위 속성을 구성한다.

JSON

{
  "Resources": {
    "ElasticLoadBalancer": {
      "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties": {
        "AvailabilityZones": {
          "Fn::GetAZs": ""
        },
        "Instances": [
          {
            "Ref": "Ec2Instance1"
          },
          {
            "Ref": "Ec2Instance2"
          }
        ],
        "Listeners": [
          {
            "LoadBalancerPort": "80",
            "InstancePort": {
              "Ref": "WebServerPort"
            },
            "Protocol": "HTTP"
          }
        ],
        "HealthCheck": {
          "Target": {
            "Fn::Join": [
              "",
              [
                "HTTP:",
                {
                  "Ref": "WebServerPort"
                },
                "/"
              ]
            ]
          },
          "HealthyThreshold": "3",
          "UnhealthyThreshold": "5",
          "Interval": "30",
          "Timeout": "5"
        }
      }
    }
  }
}

YAML

Resources:
  ElasticLoadBalancer:
    Type: 'AWS::ElasticLoadBalancing::LoadBalancer'
    Properties:
      AvailabilityZones: !GetAZs ''
      Instances:
        - !Ref Ec2Instance1
        - !Ref Ec2Instance2
      Listeners:
        - LoadBalancerPort: '80'
          InstancePort: !Ref WebServerPort
          Protocol: HTTP
      HealthCheck:
        Target: !Join
          - ''
          - - 'HTTP:'
            - !Ref WebServerPort
            - /
        HealthyThreshold: '3'
        UnhealthyThreshold: '5'
        Interval: '30'
        Timeout: '5'

Fn::Join 함수는 연결할 값을 구분하는 구분 기호와 표시될 순서대로 나열된 값 어레이, 이렇게 두 파라미터를 사용한다. 위의 예제에서 Fn::Join 함수는 빈 문자열을 구분 기호로 지정하고 HTTP:를 WebServerPort 파라미터로, / 문자를 연결할 값으로 지정한다. WebServerPort의 값이 8888인 경우 Target 속성은 다음 값으로 설정된다.

HTTP:8888/

Fn::Join 함수는 스택의 출력 값을 선언할 때도 유용하다. 템플릿의 Outputs 객체에는 스택이 생성된 후 사용 가능하도록 설정할 값에 대한 선언이 포함되어 있다. 출력은 리소스 또는 입력 파라미터에 대한 중요한 정보를 편리하게 수집할 수 있는 방법이다. 예를 들면 WordPress 템플릿에서 다음 Outputs 객체를 선언한다.

JSON

"Outputs": {
  "InstallURL": {
    "Value": {
      "Fn::Join": [
        "",
        [
          "http://",
          {
            "Fn::GetAtt": [
              "ElasticLoadBalancer",
              "DNSName"
            ]
          },
          "/wp-admin/install.php"
        ]
      ]
    },
    "Description": "Installation URL of the WordPress website"
  },
  "WebsiteURL": {
    "Value": {
      "Fn::Join": [
        "",
        [
          "http://",
          {
            "Fn::GetAtt": [
              "ElasticLoadBalancer",
              "DNSName"
            ]
          }
        ]
      ]
    }
  }
}

YAML

Outputs:
  InstallURL:
    Value: !Join
      - ''
      - - 'http://'
        - !GetAtt
          - ElasticLoadBalancer
          - DNSName
        - /wp-admin/install.php
    Description: Installation URL of the WordPress website
  WebsiteURL:
    Value: !Join
      - ''
      - - 'http://'
        - !GetAtt
          - ElasticLoadBalancer
          - DNSName

각 출력 값에는 이름, 출력 값으로 반환된 값의 선언을 포함하는 Value 속성, 그리고 값에 대한 설명(선택 사항)이 포함되어 있다. 이전 예제에서 InstallURL은 Fn::Join 함수 호출에 의해 반환되는 문자열로, http://, ElasticLoadBalancer 리소스의 DNS 이름, 그리고 /wp-admin/install.php가 연결된다. 출력 값은 다음과 비슷하다.

http://mywptests-elasticl-1gb51l6sl8y5v-206169572.us-east-2.elb.amazonaws.com/wp-admin/install.php

Get Started 자습서에서는 이 링크를 사용하여 우리가 생성한 WordPress 블록의 설치 페이지로 편리하게 이동했다. CloudFormation에서는 스택 생성이 완료된 후 출력 값을 생성한다. CloudFormation 콘솔의 출력 탭이나 aws cloudformation describe-stacks 명령을 사용하여 출력 값을 볼 수 있다.


7. 다음 단계

조금 전에는 템플릿의 기본적인 부분과 이러한 부분들을 사용하는 방법에 대해 살펴보았다. 템플릿에 대해 다음과 같은 내용을 알아보았다.

  • 리소스 및 해당 속성 선언이다.

  • Ref 함수를 사용한 다른 리소스 참조와 Fn::GetAtt 함수를 사용한 리소스 속성을 참조한다.

  • 파라미터를 사용하여 사용자가 스택 생성 시 값을 지정하도록 허용하고 제약을 사용하여 파라미터 입력을 확인하도록 허용한다.

  • 매핑을 사용하여 조건 값을 결정한다.

  • Fn::Join 함수를 사용하여 파라미터, 리소스 속성 및 기타 문자열에 기초한 값을 구성한다.

  • 출력 값을 사용하여 스택의 리소스에 대한 정보를 수집한다.

AWSTemplateFormatVersion과 Description이라는 템플릿의 최상위 객체 두 가지에 대해서는 살펴보지 않았다. AWSTemplateFormatVersion은 단순히 템플릿 형식의 버전으로, 지정하지 않을 경우 CloudFormation에서 최신 버전이 사용된다.

Description은 유효한 JSON 또는 YAML 문자열이다. 이 설명은 [Create Stack] 마법사의 Specify Parameters 페이지에 표시된다. 자세한 내용은 포맷 버전설명을 참조한다.

물론, 더 전문적인 템플릿과 스택 기능도 있다. 다음은 자세히 알아보아야 할 몇 가지 중요 항목이다.

리소스와 함께 사용할 수 있는 선택적 속성:

  • DependsOn속성을 사용하면 한 리소스 다음에 다른 리소스 하나를 생성하도록 지정할 수 있다.

  • DeletionPolicy 속성을 사용하면 CloudFormation에서 리소스 삭제를 처리하는 방법을 지정할 수 있다.

  • Metadata 속성을 사용하면 리소스와 함께 구조화된 데이터를 지정할 수 있다.

AWS::CloudFormation::Stack을 사용하면 다른 스택을 템플릿 내에서 리소스로 중첩할 수 있다.


References