

지원 종료 알림: 2026년 10월 7일에 AWS 에 대한 지원이 종료됩니다 AWS Proton. 2026년 10월 7일 이후에는 AWS Proton 콘솔 또는 AWS Proton 리소스에 더 이상 액세스할 수 없습니다. 배포된 인프라는 그대로 유지됩니다. 자세한 내용은 [AWS Proton 서비스 사용 중단 및 마이그레이션 안내서](https://docs.aws.amazon.com/proton/latest/userguide/proton-end-of-support.html)를 참조하세요.

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 용 템플릿 작성 및 번들 생성 AWS Proton
<a name="ag-template-authoring"></a>

AWS Proton 는 코드형 인프라(IaC) 파일을 기반으로 리소스를 프로비저닝합니다. 재사용 가능한 IaC 파일로 인프라를 설명합니다. 다양한 환경 및 응용 프로그램에서 파일을 재사용할 수 있도록 하려면 파일을 *템플릿*으로 작성하고 입력 파라미터를 정의한 다음 이러한 파라미터를 IaC 정의에 사용합니다. 나중에 프로비저닝 리소스(환경, 서비스 인스턴스 또는 구성 요소)를 생성할 때는 입력 값을 템플릿과 결합하여 프로비저닝할 준비가 된 IaC 파일을 생성하는 렌더링 엔진을 AWS Proton 사용합니다.

관리자는 대부분의 템플릿을 *템플릿 번들*로 작성한 다음 업로드하여에 등록합니다 AWS Proton. 이 페이지의 나머지 부분에서는 이러한 AWS Proton 템플릿 번들에 대해 설명합니다. *직접 정의된 구성 요소*는 예외입니다. 개발자가 직접 만든 구성 요소는 IaC 템플릿 파일을 직접 제공합니다. 구성 요소에 대한 자세한 내용은 [AWS Proton 구성 요소](ag-components.md)를 참조하세요.

**Topics**
+ [템플릿 번들](#ag-template-bundles)
+ [AWS Proton 파라미터](parameters.md)
+ [AWS Proton 코드형 인프라 파일](ag-infrastructure-tmp-files.md)
+ [스키마 파일](ag-schema.md)
+ [에 대한 템플릿 파일 정리 AWS Proton](ag-wrap-up.md)
+ [템플릿 번들 고려 사항](template-considerations.md)

## 템플릿 번들
<a name="ag-template-bundles"></a>

관리자는 [템플릿을 생성하고에 등록](template-create.md)합니다 AWS Proton. 이러한 템플릿을 사용하여 환경과 서비스를 만들 수 있습니다. 서비스를 생성할 때는 서비스 인스턴스를 AWS Proton 프로비저닝하고 선택한 환경에 배포합니다. 자세한 내용은 [AWS Proton 플랫폼 팀용](Welcome.md#ag-admin) 단원을 참조하십시오.

에서 템플릿을 생성하고 등록하려면 및 환경 또는 서비스를 프로비저닝 AWS Proton 해야 하는 코드형 인프라(IaC) 파일이 포함된 템플릿 번들을 업로드 AWS Proton합니다.

*템플릿 번들*에는 다음이 포함됩니다.
+ *IaC 파일*을 나열하는 [매니페스트 YAML 파일](ag-wrap-up.md)이 포함된 [코드형 인프라(IaC)파일](ag-infrastructure-tmp-files.md).
+ IAC 파일 입력 파라미터 정의를 위한 [스키마 YAML 파일](ag-schema.md).

CloudFormation 환경 템플릿 번들에는 IaC 파일 하나가 포함되어 있습니다.

CloudFormation 서비스 템플릿 번들에는 서비스 인스턴스 정의를 위한 IaC 파일 하나와 파이프라인 정의를 위한 선택적 IaC 파일이 하나 포함되어 있습니다.

Terraform 환경 및 서비스 템플릿 번들에는 각각 여러 IaC 파일이 포함될 수 있습니다.

AWS Proton 에는 입력 파라미터 스키마 파일이 필요합니다. AWS CloudFormation 를 사용하여 IaC 파일을 생성할 때 [Jinja](https://jinja.palletsprojects.com/en/2.11.x/) 구문을 사용하여 입력 파라미터를 참조합니다.는 IaC 파일의 파라미터를 참조하는 데 사용할 수 있는 [파라미터](parameters.md) 네임스페이스를 AWS Proton 제공합니다.

다음 다이어그램은 *템플릿을* 생성하기 위해 수행할 수 있는 단계의 예를 보여줍니다 AWS Proton.

![\[AWS Proton 인프라 리소스 세트에 대한 템플릿 번들을 생성하는 프로세스를 설명하는 다이어그램입니다.\]](http://docs.aws.amazon.com/ko_kr/proton/latest/userguide/images/bundles.png)


 ![\[Red circle with the number 1 inside, typically used as a notification icon.\]](http://docs.aws.amazon.com/ko_kr/proton/latest/userguide/images/label-one.png)은 [입력 파라미터](parameters.md)를 식별합니다.

 ![\[Number 2 icon in a pink circle.\]](http://docs.aws.amazon.com/ko_kr/proton/latest/userguide/images/label-two.png)은 [스키마 파일](ag-schema.md)을 생성하여 입력 파라미터를 정의합니다.

 ![\[Pink square icon with a white exclamation mark inside a circle.\]](http://docs.aws.amazon.com/ko_kr/proton/latest/userguide/images/label-three.png)은 입력 파라미터를 참조하는 [IaC 파일](ag-infrastructure-tmp-files.md)을 생성합니다. 환경 IaC 파일 *출력*을 서비스 IaC 파일의 *입력*으로 참조할 수 있습니다.

 ![\[Number 4 in a red circle icon, commonly used to indicate a notification count.\]](http://docs.aws.amazon.com/ko_kr/proton/latest/userguide/images/label-four.png) [에 템플릿 버전을 등록](template-create.md) AWS Proton 하고 템플릿 번들을 업로드합니다.

# AWS Proton 파라미터
<a name="parameters"></a>

IaC(코드형 인프라) 파일에서 파라미터를 정의하고 사용하여 유연하고 재사용 가능하게 만들 수 있습니다. 네임 AWS Proton *스페이스*에서 파라미터의 이름을 참조하여 IaC 파일의 파라미터 값을 읽습니다. 파라미터 값은 리소스 프로비저닝 중에 생성하는 렌더링된 IaC 파일에 AWS Proton 주입됩니다. AWS CloudFormation IaC 파라미터를 처리하려면 [Jinja](https://jinja.palletsprojects.com/en/2.11.x/)를 AWS Proton 사용합니다. Terraform IaC 파라미터를 처리하기 위해는 Terraform 파라미터 값 파일을 AWS Proton 생성하고 HCL에 내장된 파라미터화 기능에 의존합니다.

를 사용하면 코드가 가져올 수 있는 입력 파일을 [CodeBuild 프로비저닝](ag-works-prov-methods.md#ag-works-prov-methods-codebuild) AWS Proton 생성합니다. 파일은 템플릿 매니페스트의 속성에 따라 JSON 또는 HCL 파일입니다. 자세한 내용은 [CodeBuild 프로비저닝 파라미터 세부 정보 및 예제](parameters-codebuild.md) 단원을 참조하세요.

환경, 서비스, 구성 요소 IaC 파일의 파라미터 또는 프로비저닝 코드에서 다음 요구 사항을 참조할 수 있습니다.
+ 각 파라미터 이름의 길이는 100자를 초과할 수 없습니다.
+ 파라미터 네임스페이스와 리소스 이름을 합친 길이는 리소스 이름의 문자 제한을 초과하지 않습니다.

AWS Proton 이러한 할당량을 초과하면 프로비저닝이 실패합니다.

## 파라미터 유형
<a name="param-name-types"></a>

다음 파라미터 유형을 AWS Proton IaC 파일에서 참조할 수 있습니다.

**입력 파라미터**  
환경 및 서비스 인스턴스는 환경 또는 서비스 템플릿에 연결하는 [스키마 파일](ag-schema.md)에 정의한 입력 파라미터를 사용할 수 있습니다. 리소스의 IaC 파일에서 리소스의 입력 파라미터를 참조할 수 있습니다. 구성 요소 IaC 파일은 구성 요소가 연결된 서비스 인스턴스의 입력 파라미터를 참조할 수 있습니다.  
AWS Proton 는 스키마 파일에 대해 입력 파라미터 이름을 확인하고 IaC 파일에서 참조되는 파라미터와 일치시켜 리소스 프로비저닝 중에 사양 파일에 제공하는 입력 값을 주입합니다.

**출력 파라미터**  
모든 IaC 파일에서 출력을 정의할 수 있습니다. 출력은 예를 들어 템플릿에서 제공하는 리소스 중 하나의 이름, ID 또는 ARN일 수도 있고 템플릿의 입력 중 하나를 전달하는 방법일 수도 있습니다. 다른 리소스의 IaC 파일에서 이러한 출력을 참조할 수 있습니다.  
클라우드포메이션 IaC 파일에서 `Outputs:` 블록의 출력 파라미터를 정의합니다. Terraform IaC 파일에서 `output` 명령문을 사용하여 각 출력 파라미터를 정의합니다.

**리소스 파라미터**  
AWS Proton 는 AWS Proton 리소스 파라미터를 자동으로 생성합니다. 이러한 파라미터는 AWS Proton 리소스 객체의 속성을 노출합니다. 리소스 파라미터의 예는 `environment.name`입니다.

## IaC 파일에서 AWS Proton 파라미터 사용
<a name="param-name-spaces"></a>

IaC 파일에서 파라미터 값을 읽으려면 파라미터 네임스페이스에서 AWS Proton 파라미터 이름을 참조합니다. AWS CloudFormation IaC 파일의 경우 *Jinja* 구문을 사용하고 파라미터를 중괄호와 따옴표 쌍으로 묶습니다.

다음 표는 지원되는 각 템플릿 언어에 대한 참조 구문을 예제와 함께 보여 줍니다.


| 템플릿 언어 | 구문 | 예: "VPC"라는 이름의 환경 입력 | 
| --- | --- | --- | 
|  CloudFormation  |  `"{{ parameter-name }}"`  |  `"{{ environment.inputs.VPC }}"`  | 
|  Terraform  |  `var.parameter-name`  |  `var.environment.inputs.VPC` [생성된 테라폼 변수 정의](ag-infrastructure-tmp-files-terraform.md#compiled-tform)  | 

**참고**  
IaC 파일에서 [CloudFormation 동적 파라미터](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html)를 사용하는 경우 Jinja의 오해 오류를 방지하려면 [파라미터를 이스케이프 처리](https://jinja.palletsprojects.com/en/2.11.x/templates/#escaping)해야 합니다. 자세한 내용은 [문제 해결 AWS Proton](ag-troubleshooting.md) 섹션을 참조하세요.

다음 표에는 모든 AWS Proton 리소스 파라미터의 네임스페이스 이름이 나열되어 있습니다. 각 템플릿 파일 형식은 파라미터 네임스페이스의 다른 하위 집합을 사용할 수 있습니다.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/proton/latest/userguide/parameters.html)

자세한 내용과 예제는 다양한 리소스 유형 및 템플릿 언어에 대한 IaC 템플릿 파일의 파라미터에 대한 하위 항목을 참조하세요.

**Topics**
+ [파라미터 유형](#param-name-types)
+ [IaC 파일에서 AWS Proton 파라미터 사용](#param-name-spaces)
+ [환경 CloudFormation IaC 파일 파라미터 세부 정보 및 예제](env-parameters.md)
+ [CloudFormation IaC 파일 파라미터 세부 정보 및 예제](svc-parameters.md)
+ [구성 요소 CloudFormation IaC 파일 파라미터 세부 정보 및 예제](comp-parameters.md)
+ [CloudFormation IaC 파일용 파라미터 필터](parameter-filters.md)
+ [CodeBuild 프로비저닝 파라미터 세부 정보 및 예제](parameters-codebuild.md)
+ [Terraform 코드형 인프라(IaC) 파일 파라미터 세부 정보 및 예제](env-parameters-tform.md)

# 환경 CloudFormation IaC 파일 파라미터 세부 정보 및 예제
<a name="env-parameters"></a>

환경 인프라의 파라미터를 코드형 인프라(IaC) 파일로 정의하고 참조할 수 있습니다. AWS Proton 파라미터, 파라미터 유형, 파라미터 네임스페이스 및 IaC 파일에서 파라미터를 사용하는 방법에 대한 자세한 설명은 섹션을 참조하세요[AWS Proton 파라미터](parameters.md).

## 환경 파라미터를 정의하세요.
<a name="env-parameters.define"></a>

환경 IaC 파일의 입력 및 출력 파라미터를 모두 정의할 수 있습니다.
+ **입력 파라미터** — [스키마 파일](ag-schema.md)에 환경 입력 파라미터를 정의합니다.

  다음 목록에는 일반적인 사용 사례에 대한 환경 입력 파라미터의 예가 포함되어 있습니다.
  + VPC CIDR 값
  + 로드 밸런서 설정
  + 데이터베이스 설정
  + 상태 확인 타임아웃

  관리자는 [환경을 생성](ag-create-env.md)할 때 입력 파라미터 값을 제공할 수 있습니다.
  + 콘솔을 사용하여가 AWS Proton 제공하는 스키마 기반 양식을 작성합니다.
  + CLI를 사용하여 값이 포함된 사양을 제공하세요.
+ **출력 파라미터** - 환경 IaC 파일에서 환경 출력을 정의합니다. 그런 다음 다른 리소스의 IaC 파일에서 이러한 출력을 참조할 수 있습니다.

## 환경 IaC 파일에서 파라미터 값을 읽습니다.
<a name="env-parameters.refer"></a>

환경 IaC 파일에서 환경과 관련된 파라미터를 읽을 수 있습니다. IaC 파일에서 파라미터 값을 읽으려면 AWS Proton 파라미터 네임스페이스에 있는 파라미터 이름을 참조하세요.
+ **입력 파라미터** - `environment.inputs.input-name` 참조를 통해 환경 입력 값을 읽습니다.
+ **리소스 파라미터** -와 같은 이름을 참조하여 AWS Proton 리소스 파라미터를 읽습니다`environment.name`.

**참고**  
환경 IaC 파일에는 다른 리소스의 출력 파라미터를 사용할 수 없습니다.

## 파라미터가 포함된 예제 환경 및 서비스 IaC 파일
<a name="env-parameters.example"></a>

다음 예제는 환경 IaC 파일의 파라미터 정의 및 참조를 보여줍니다. 그런 다음 예제는 환경 IaC 파일에 정의된 환경 출력 파라미터를 서비스 IaC 파일에서 참조할 수 있는 방법을 보여줍니다.

**Example 환경 CloudFormation IaC 파일**  
이 예제에서는 다음 사항에 유의합니다.  
+ `environment.inputs.` 네임스페이스는 환경 입력 파라미터를 나타냅니다.
+ EC2 Systems Manager (SSM) `StoreInputValue` 파라미터는 환경 입력을 연결합니다.
+ `MyEnvParameterValue` 출력에는 출력 파라미터와 동일한 입력 파라미터 연결이 표시됩니다. 세 개의 추가 출력 파라미터도 입력 파라미터를 개별적으로 노출합니다.
+ 6개의 추가 출력 파라미터는 환경이 제공하는 리소스를 노출합니다.

```
Resources:
  StoreInputValue:
    Type: AWS::SSM::Parameter
    Properties:
      Type: String
      Value: "{{ environment.inputs.my_sample_input }} {{ environment.inputs.my_other_sample_input}} {{ environment.inputs.another_optional_input }}"
              # input parameter references

# These output values are available to service infrastructure as code files as outputs, when given the 
# the 'environment.outputs' namespace, for example, service_instance.environment.outputs.ClusterName.
Outputs:
  MyEnvParameterValue:                                        # output definition
    Value: !GetAtt StoreInputValue.Value
  MySampleInputValue:                                         # output definition
    Value: "{{ environment.inputs.my_sample_input }}"         #   input parameter reference
  MyOtherSampleInputValue:                                    # output definition
    Value: "{{ environment.inputs.my_other_sample_input }}"   #   input parameter reference
  AnotherOptionalInputValue:                                  # output definition
    Value: "{{ environment.inputs.another_optional_input }}"  #   input parameter reference
  ClusterName:                                                # output definition
    Description: The name of the ECS cluster
    Value: !Ref 'ECSCluster'                                  #   provisioned resource
  ECSTaskExecutionRole:                                       # output definition
    Description: The ARN of the ECS role
    Value: !GetAtt 'ECSTaskExecutionRole.Arn'                 #   provisioned resource
  VpcId:                                                      # output definition
    Description: The ID of the VPC that this stack is deployed in
    Value: !Ref 'VPC'                                         #   provisioned resource
  PublicSubnetOne:                                            # output definition
    Description: Public subnet one
    Value: !Ref 'PublicSubnetOne'                             #   provisioned resource
  PublicSubnetTwo:                                            # output definition
    Description: Public subnet two
    Value: !Ref 'PublicSubnetTwo'                             #   provisioned resource
  ContainerSecurityGroup:                                     # output definition
    Description: A security group used to allow Fargate containers to receive traffic
    Value: !Ref 'ContainerSecurityGroup'                      #   provisioned resource
```

**Example 서비스 클라우드포메이션 IAC 파일**  
`environment.outputs.` 네임스페이스는 환경 IaC 파일의 환경 출력을 나타냅니다. 예를 들어 이름 `environment.outputs.ClusterName`은 `ClusterName` 환경 출력 파라미터의 값을 읽습니다.  

```
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy a service on AWS Fargate, hosted in a public subnet, and accessible via a public load balancer.
Mappings:
  TaskSize:
    x-small:
      cpu: 256
      memory: 512
    small:
      cpu: 512
      memory: 1024
    medium:
      cpu: 1024
      memory: 2048
    large:
      cpu: 2048
      memory: 4096
    x-large:
      cpu: 4096
      memory: 8192
Resources:
  # A log group for storing the stdout logs from this service's containers
  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: '{{service_instance.name}}' # resource parameter

  # The task definition. This is a simple metadata description of what
  # container to run, and what resource requirements it has.
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: '{{service_instance.name}}' # resource parameter
      Cpu: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, cpu] # input parameter
      Memory: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, memory] 
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      ExecutionRoleArn: '{{environment.outputs.ECSTaskExecutionRole}}'  # output reference to an environment infrastructure code file
      TaskRoleArn: !Ref "AWS::NoValue"
      ContainerDefinitions:
        - Name: '{{service_instance.name}}'  # resource parameter
          Cpu: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, cpu]
          Memory: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, memory]
          Image: '{{service_instance.inputs.image}}'
          PortMappings:
            - ContainerPort: '{{service_instance.inputs.port}}' # input parameter
          LogConfiguration:
            LogDriver: 'awslogs'
            Options:
              awslogs-group: '{{service_instance.name}}' # resource parameter
              awslogs-region: !Ref 'AWS::Region'
              awslogs-stream-prefix: '{{service_instance.name}}' # resource parameter

  # The service_instance. The service is a resource which allows you to run multiple
  # copies of a type of task, and gather up their logs and metrics, as well
  # as monitor the number of running tasks and replace any that have crashed
  Service:
    Type: AWS::ECS::Service
    DependsOn: LoadBalancerRule
    Properties:
      ServiceName: '{{service_instance.name}}'  # resource parameter
      Cluster: '{{environment.outputs.ClusterName}}' # output reference to an environment infrastructure as code file
      LaunchType: FARGATE
      DeploymentConfiguration:
        MaximumPercent: 200
        MinimumHealthyPercent: 75
      DesiredCount: '{{service_instance.inputs.desired_count}}'# input parameter
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
            - '{{environment.outputs.ContainerSecurityGroup}}' # output reference to an environment infrastructure as code file
          Subnets:
            - '{{environment.outputs.PublicSubnetOne}}' # output reference to an environment infrastructure as code file
            - '{{environment.outputs.PublicSubnetTwo}}' # output reference to an environment infrastructure as code file
      TaskDefinition: !Ref 'TaskDefinition'
      LoadBalancers:
        - ContainerName: '{{service_instance.name}}'  # resource parameter
          ContainerPort: '{{service_instance.inputs.port}}' # input parameter
          TargetGroupArn: !Ref 'TargetGroup'
[...]
```

# CloudFormation IaC 파일 파라미터 세부 정보 및 예제
<a name="svc-parameters"></a>

서비스 및 파이프라인 인프라에서 파라미터를 코드형 인프라(IaC) 파일로 정의하고 참조할 수 있습니다. AWS Proton 파라미터, 파라미터 유형, 파라미터 네임스페이스 및 IaC 파일의 파라미터 사용 방법에 대한 자세한 설명은 [AWS Proton 파라미터](parameters.md)을 참조하세요.

## 서비스 파라미터를 정의하세요.
<a name="svc-parameters.define"></a>

서비스 IaC 파일의 입력 및 출력 파라미터를 모두 정의할 수 있습니다.
+ **입력 파라미터** — [스키마 파일](ag-schema.md)에 서비스 인스턴스 입력 파라미터를 정의합니다.

  다음 목록에는 일반적인 사용 사례에 대한 서비스 입력 파라미터의 예가 나와 있습니다.
  + 포트
  + 작업 크기
  + 이미지
  + 원하는 개수
  + Docker 파일
  + 유닛 테스트 명령

  [서비스를 생성](ag-create-svc.md)할 때 입력 파라미터 값을 제공합니다.
  + 콘솔을 사용하여가 AWS Proton 제공하는 스키마 기반 양식을 작성합니다.
  + CLI를 사용하여 값이 포함된 사양을 제공하세요.
+ **출력 파라미터** — 서비스 IaC 파일에서 서비스 인스턴스 출력을 정의합니다. 그런 다음 다른 리소스의 IaC 파일에서 이러한 출력을 참조할 수 있습니다.

## 서비스 IaC 파일에서 파라미터 값 읽기
<a name="svc-parameters.refer"></a>

서비스 IaC 파일에서 서비스 및 기타 리소스와 관련된 파라미터를 읽을 수 있습니다. 파라미터 네임스페이스에서 파라미터 이름을 참조하여 AWS Proton 파라미터 값을 읽습니다.
+ **입력 파라미터** - `service_instance.inputs.input-name`를 참조하여 서비스 인스턴스 입력 값을 읽습니다.
+ **리소스 파라미터** - `service.name`, `service_instance.name`및와 같은 이름을 참조하여 AWS Proton 리소스 파라미터를 읽습니다`environment.name`.
+ **출력 파라미터** - `environment.outputs.output-name` 또는 `service_instance.components.default.outputs.output-name`를 참조하여 다른 리소스의 출력을 읽습니다.

## 파라미터가 포함된 서비스 IaC 파일 예시
<a name="svc-parameters.example"></a>

다음 예시는 서비스 클라우드포메이션 IaC 파일의 스니펫입니다. `environment.outputs.` 네임스페이스는 환경 IaC 파일의 환경 출력을 나타냅니다. `service_instance.inputs.` 네임스페이스는 서비스 인스턴스 입력 파라미터를 나타냅니다. `service_instance.name` 속성은 AWS Proton 리소스 파라미터를 나타냅니다.

```
Resources:
  StoreServiceInstanceInputValue:
    Type: AWS::SSM::Parameter
    Properties:
      Type: String
      Value: "{{ service.name }} {{ service_instance.name }} {{ service_instance.inputs.my_sample_service_instance_required_input }} {{ service_instance.inputs.my_sample_service_instance_optional_input }} {{ environment.outputs.MySampleInputValue }} {{ environment.outputs.MyOtherSampleInputValue }}"
              #  resource parameter references               # input parameter references                                                                                                                    # output references to an environment infrastructure as code file
Outputs:
  MyServiceInstanceParameter:                                                         # output definition
    Value: !Ref StoreServiceInstanceInputValue 
  MyServiceInstanceRequiredInputValue:                                                # output definition
    Value: "{{ service_instance.inputs.my_sample_service_instance_required_input }}"  # input parameter reference
  MyServiceInstanceOptionalInputValue:                                                # output definition
    Value: "{{ service_instance.inputs.my_sample_service_instance_optional_input }}"  # input parameter reference
  MyServiceInstancesEnvironmentSampleOutputValue:                                     # output definition
    Value: "{{ environment.outputs.MySampleInputValue }}"                             # output reference to an environment IaC file
  MyServiceInstancesEnvironmentOtherSampleOutputValue:                                # output definition
    Value: "{{ environment.outputs.MyOtherSampleInputValue }}"                        # output reference to an environment IaC file
```

# 구성 요소 CloudFormation IaC 파일 파라미터 세부 정보 및 예제
<a name="comp-parameters"></a>

구성요소 코드형 인프라(IaC) 파일에서 파라미터를 정의하고 참조할 수 있습니다. AWS Proton 파라미터, 파라미터 유형, 파라미터 네임스페이스 및 IaC 파일에서 파라미터를 사용하는 방법에 대한 자세한 설명은 섹션을 참조하세요[AWS Proton 파라미터](parameters.md). 구성 요소에 대한 자세한 내용은 [AWS Proton 구성 요소](ag-components.md)를 참조하세요.

## 구성 요소 출력 파라미터를 정의합니다.
<a name="comp-parameters.define"></a>

구성 요소 IaC 파일에서 출력 파라미터를 정의할 수 있습니다. 다른 리소스의 서비스 IaC 파일에서 이러한 출력을 참조할 수 있습니다.

**참고**  
구성 요소 IaC 파일의 입력은 정의할 수 없습니다. 연결된 구성 요소는 연결된 서비스 인스턴스에서 입력을 가져올 수 있습니다. 분리된 구성 요소에는 입력이 없습니다.

## 구성 요소 IaC 파일에서 파라미터 값 읽기
<a name="comp-parameters.refer"></a>

구성 요소와 관련된 파라미터 및 구성 요소 IaC 파일에서 다른 리소스를 읽을 수 있습니다. 파라미터 네임스페이스에서 파라미터 이름을 참조하여 AWS Proton 파라미터 값을 읽습니다.
+ **입력 파라미터** - `service_instance.inputs.input-name`를 참조하여 첨부된 서비스 인스턴스 입력 값을 읽습니다.
+ **리소스 파라미터** - `component.name`, `service.name`, `service_instance.name`, 등의 이름을 참조하여 AWS Proton 리소스 파라미터를 읽습니다`environment.name`.
+ **출력 파라미터** - `environment.outputs.output-name` 참조를 통해 환경 출력을 읽습니다.

## 파라미터가 포함된 구성 요소 및 서비스 IaC 파일 예시
<a name="comp-parameters.example"></a>

다음 예에서는 Simple Storage Service(S3) 버킷과 관련 액세스 정책을 프로비저닝하고 두 리소스의 리소스 이름(ARN) 을 구성 요소 출력으로 노출하는 구성 요소를 보여줍니다. 서비스 IaC 템플릿은 구성 요소 출력을 Elastic Container Service(ECS) 작업의 컨테이너 환경 변수로 추가하여 컨테이너에서 실행 중인 코드에서 출력을 사용할 수 있도록 하고, 작업 역할에 버킷 액세스 정책을 추가합니다. 버킷 이름은 환경, 서비스, 서비스 인스턴스 및 구성 요소의 이름을 기반으로 합니다. 즉, 버킷은 특정 서비스 인스턴스를 확장하는 구성 요소 템플릿의 특정 인스턴스와 결합됩니다. 개발자는 이 구성 요소 템플릿을 기반으로 여러 사용자 지정 구성 요소를 생성하여 다양한 서비스 인스턴스 및 기능 요구 사항에 맞게 S3 버킷을 프로비저닝할 수 있습니다.

이 예제는 Jinja `{{ ... }}` 구문을 사용하여 서비스 IaC 파일의 구성 요소 및 기타 리소스 파라미터를 참조하는 방법을 보여줍니다. 구성 요소가 서비스 인스턴스에 연결된 경우에만 `{% if ... %}` 명령문을 사용하여 명령문 블록을 추가할 수 있습니다. `proton_cfn_*` 키워드는 출력 파라미터 값을 삭제하고 형식을 지정하는 데 사용할 수 있는 *필터*입니다. 필터에 대한 자세한 내용은 [CloudFormation IaC 파일용 파라미터 필터](parameter-filters.md) 단원을 참조하세요.

 관리자는 서비스 IaC 템플릿 파일을 작성합니다.

**Example 구성 요소를 사용한 서비스 CloudFormation IaC 파일**  

```
# service/instance_infrastructure/cloudformation.yaml

Resources: 
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      TaskRoleArn: !Ref TaskRole
      ContainerDefinitions:
        - Name: '{{service_instance.name}}'
          # ...
          {% if service_instance.components.default.outputs | length > 0 %}
          Environment:
            {{ service_instance.components.default.outputs |
                proton_cfn_ecs_task_definition_formatted_env_vars }}
          {% endif %}

  # ...

  TaskRole:
    Type: AWS::IAM::Role
    Properties:
      # ...
      ManagedPolicyArns:
        - !Ref BaseTaskRoleManagedPolicy
        {{ service_instance.components.default.outputs
            | proton_cfn_iam_policy_arns }}

  # Basic permissions for the task
  BaseTaskRoleManagedPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      # ...
```

개발자는 구성 요소 IaC 템플릿 파일을 작성합니다.

**Example 컴포넌트 CloudFormation IaC 파일**  

```
# cloudformation.yaml

# A component that defines an S3 bucket and a policy for accessing the bucket.
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: '{{environment.name}}-{{service.name}}-{{service_instance.name}}-{{component.name}}'
  S3BucketAccessPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      PolicyDocument:
        Version: "2012-10-17"		 	 	 
        Statement:
          - Effect: Allow
            Action:
              - 's3:Get*'
              - 's3:List*'
              - 's3:PutObject'
            Resource: !GetAtt S3Bucket.Arn
Outputs:
  BucketName:
    Description: "Bucket to access"
    Value: !GetAtt S3Bucket.Arn
  BucketAccessPolicyArn:
    Value: !Ref S3BucketAccessPolicy
```

가 서비스 인스턴스에 대한 CloudFormation 템플릿을 AWS Proton 렌더링하고 모든 파라미터를 실제 값으로 대체하는 경우 템플릿은 다음 파일과 같을 수 있습니다.

**Example 서비스 인스턴스 CloudFormation 렌더링 IaC 파일**  

```
Resources: 
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      TaskRoleArn: !Ref TaskRole
      ContainerDefinitions:
        - Name: '{{service_instance.name}}'
          # ...
          Environment:
            - Name: BucketName
              Value: arn:aws:s3:us-east-1:123456789012:environment_name-service_name-service_instance_name-component_name
            - Name: BucketAccessPolicyArn
              Value: arn:aws:iam::123456789012:policy/cfn-generated-policy-name
  # ...

  TaskRole:
    Type: AWS::IAM::Role
    Properties:
      # ...
      ManagedPolicyArns:
        - !Ref BaseTaskRoleManagedPolicy
        - arn:aws:iam::123456789012:policy/cfn-generated-policy-name

  # Basic permissions for the task
  BaseTaskRoleManagedPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      # ...
```

# CloudFormation IaC 파일용 파라미터 필터
<a name="parameter-filters"></a>

 AWS CloudFormation IaC 파일의 [AWS Proton 파라미터를](parameters.md) 참조할 때 *필터*라고 하는 Jinja 한정자를 사용하여 파라미터 값을 렌더링된 템플릿에 삽입하기 전에 검증, 필터링 및 형식을 지정할 수 있습니다. 구성 요소 생성 및 첨부는 개발자가 수행하므로 서비스 인스턴스 템플릿에서 [구성 요소](ag-components.md) 출력을 사용하는 관리자는 구성 요소 출력 파라미터의 존재 여부와 유효성을 확인하고자 할 수 있으므로 필터 검증은 구성 요소 출력 파라미터를 참조할 때 특히 유용합니다. 하지만 Jinja IaC 파일에서는 필터를 사용할 수 있습니다.

다음 섹션에서는 사용 가능한 파라미터 필터를 설명하고 정의하며 example. AWS Proton defines를 제공합니다. `default`은 Jinja 내장 필터입니다.

## ECS 작업의 환경 속성 형식 지정
<a name="parameter-filters.proton.cfn-ecs"></a>

**선언**

```
dict → proton_cfn_ecs_task_definition_formatted_env_vars (raw: boolean = True) → YAML list of dicts
```

**설명**

이 필터는 Elastic Container Service(ECS) 태스크 정의 `ContainerDefinition`섹션의 [환경 속성](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-containerdefinitions.html#cfn-ecs-taskdefinition-containerdefinition-environment)에 사용될 출력 목록의 형식을 지정합니다.

`raw`을 `False`로 설정하여 파라미터 값의 유효성도 확인합니다. 이 경우 값은 정규 표현식 `^[a-zA-Z0-9_-]*$`과 일치해야 합니다. 값이 이 검증에 실패하면 템플릿 렌더링이 실패합니다.

### 예시
<a name="parameter-filters.proton.cfn-ecs.example"></a>

다음과 같은 사용자 지정 구성 요소 템플릿 사용:

```
Resources:
  # ...
Outputs:
  Output1:
    Description: "Example component output 1"
    Value: hello
  Output2:
    Description: "Example component output 2"
    Value: world
```

그리고 다음 서비스 템플릿:

```
Resources:
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      # ...
      ContainerDefinitions:
        - Name: MyServiceName
          # ...
          Environment:
            {{ service_instance.components.default.outputs
              | proton_cfn_ecs_task_definition_formatted_env_vars }}
```

렌더링된 서비스 템플릿은 다음과 같습니다.

```
Resources:
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      # ...
      ContainerDefinitions:
        - Name: MyServiceName
          # ...
          Environment:
            - Name: Output1
              Value: hello
            - Name: Output2
              Value: world
```

## Lambda 함수의 환경 속성 형식 지정
<a name="parameter-filters.proton.cfn-lambda"></a>

**선언**

```
dict → proton_cfn_lambda_function_formatted_env_vars (raw: boolean = True) → YAML dict
```

**설명**

이 필터는 AWS Lambda 함수 정의의 `Properties` 섹션에 있는 [환경 속성](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-environment)에서 사용할 출력 목록의 형식을 지정합니다.

`raw`을 `False`로 설정하여 파라미터 값의 유효성도 확인합니다. 이 경우 값은 정규 표현식 `^[a-zA-Z0-9_-]*$`과 일치해야 합니다. 값이 이 검증에 실패하면 템플릿 렌더링이 실패합니다.

### 예시
<a name="parameter-filters.proton.cfn-lambda.example"></a>

다음과 같은 사용자 지정 구성 요소 템플릿 사용:

```
Resources:
  # ...
Outputs:
  Output1:
    Description: "Example component output 1"
    Value: hello
  Output2:
    Description: "Example component output 2"
    Value: world
```

그리고 다음 서비스 템플릿:

```
Resources:
  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      Environment:
        Variables:
          {{ service_instance.components.default.outputs
            | proton_cfn_lambda_function_formatted_env_vars }}
```

렌더링된 서비스 템플릿은 다음과 같습니다.

```
Resources:
  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      Environment:
        Variables:
          Output1: hello
          Output2: world
```

## IAM 정책 ARN을 추출하여 IAM 역할에 포함시킵니다.
<a name="parameter-filters.proton.cfn-policy-arns"></a>

**선언**

```
dict → proton_cfn_iam_policy_arns → YAML list
```

**설명**

이 필터는 AWS Identity and Access Management (IAM) 역할 정의의 `Properties` 섹션에 있는 [ManagedPolicyArns 속성](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html#cfn-iam-role-managepolicyarns)에서 사용할 출력 목록의 형식을 지정합니다. 필터는 정규 표현식 `^arn:[a-zA-Z-]+:iam::\d{12}:policy/`을 사용하여 출력 파라미터 목록에서 유효한 IAM 정책 ARN을 추출합니다. 이 필터를 사용하여 출력 파라미터 값의 정책을 서비스 템플릿의 IAM 역할 정의에 추가할 수 있습니다.

### 예시
<a name="parameter-filters.proton.cfn-policy-arns.example"></a>

다음과 같은 사용자 지정 구성 요소 템플릿 사용:

```
Resources:
  # ...
  ExamplePolicy1:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      # ...
  ExamplePolicy2:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      # ...

  # ...

Outputs:
  Output1:
    Description: "Example component output 1"
    Value: hello
  Output2:
    Description: "Example component output 2"
    Value: world
  PolicyArn1:
    Description: "ARN of policy 1"
    Value: !Ref ExamplePolicy1
  PolicyArn2:
    Description: "ARN of policy 2"
    Value: !Ref ExamplePolicy2
```

그리고 다음 서비스 템플릿:

```
Resources: 

  # ...

  TaskRole:
    Type: AWS::IAM::Role
    Properties:
      # ...
      ManagedPolicyArns:
        - !Ref BaseTaskRoleManagedPolicy
        {{ service_instance.components.default.outputs
            | proton_cfn_iam_policy_arns }}

  # Basic permissions for the task
  BaseTaskRoleManagedPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      # ...
```

렌더링된 서비스 템플릿은 다음과 같습니다.

```
Resources: 

  # ...

  TaskRole:
    Type: AWS::IAM::Role
    Properties:
      # ...
      ManagedPolicyArns:
        - !Ref BaseTaskRoleManagedPolicy
        - arn:aws:iam::123456789012:policy/cfn-generated-policy-name-1
        - arn:aws:iam::123456789012:policy/cfn-generated-policy-name-2

  # Basic permissions for the task
  BaseTaskRoleManagedPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      # ...
```

## 속성 값 삭제
<a name="parameter-filters.proton.cfn-sanitize"></a>

**선언**

```
string → proton_cfn_sanitize → string
```

**설명**

범용 필터입니다. 이를 사용하여 파라미터 값의 안전성을 검증할 수 있습니다. 필터는 값이 정규 표현식 `^[a-zA-Z0-9_-]*$`과 일치하는지 또는 유효한 리소스 이름(ARN) 인지 확인합니다. 값이 이 검증에 실패하면 템플릿 렌더링이 실패합니다.

### 예시
<a name="parameter-filters.proton.cfn-sanitize.example"></a>

다음과 같은 사용자 지정 구성 요소 템플릿 사용:

```
Resources:
  # ...
Outputs:
  Output1:
    Description: "Example of valid output"
    Value: "This-is_valid_37"
  Output2:
    Description: "Example incorrect output"
    Value: "this::is::incorrect"
  SomeArn:
    Description: "Example ARN"
    Value: arn:aws:some-service::123456789012:some-resource/resource-name
```
+ 서비스 템플릿의 다음 참조:

  ```
  # ...
    {{ service_instance.components.default.outputs.Output1
      | proton_cfn_sanitize }}
  ```

  다음과 같이 렌더링됩니다.

  ```
  # ...
    This-is_valid_37
  ```
+ 서비스 템플릿의 다음 참조:

  ```
  # ...
    {{ service_instance.components.default.outputs.Output2
      | proton_cfn_sanitize }}
  ```

  다음과 같은 렌더링 오류가 발생한 결과:

  ```
  Illegal character(s) detected in "this::is::incorrect". Must match regex ^[a-zA-Z0-9_-]*$ or be a valid ARN
  ```
+ 서비스 템플릿의 다음 참조:

  ```
  # ...
    {{ service_instance.components.default.outputs.SomeArn
      | proton_cfn_sanitize }}
  ```

  다음과 같이 렌더링됩니다.

  ```
  # ...
    arn:aws:some-service::123456789012:some-resource/resource-name
  ```

## 존재하지 않는 참조에 대한 기본값 제공
<a name="parameter-filters.proton.default"></a>

**설명**

`default` 필터는 네임스페이스 참조가 없는 경우 기본값을 제공합니다. 이를 사용하여 참조하는 파라미터가 누락된 경우에도 오류 없이 렌더링할 수 있는 강력한 템플릿을 작성할 수 있습니다.

### 예시
<a name="parameter-filters.default.example"></a>

서비스 템플릿의 다음 참조를 사용하면 서비스 인스턴스에 직접 정의된 (기본) 구성 요소가 첨부되어 있지 않거나 연결된 구성 요소에 이름이 지정된 `test` 출력이 없는 경우 템플릿 렌더링이 실패합니다.

```
# ...
  {{ service_instance.components.default.outputs.test }}
```

이 문제를 방지하려면 `default` 필터를 추가합니다.

```
# ...
  {{ service_instance.components.default.outputs.test | default("[optional-value]") }}
```

# CodeBuild 프로비저닝 파라미터 세부 정보 및 예제
<a name="parameters-codebuild"></a>

템플릿에서 CodeBuild 기반 AWS Proton 리소스에 대한 파라미터를 정의하고 프로비저닝 코드에서 이러한 파라미터를 참조할 수 있습니다. AWS Proton 파라미터, 파라미터 유형, 파라미터 네임스페이스 및 IaC 파일에서 파라미터를 사용하는 방법에 대한 자세한 설명은 섹션을 참조하세요[AWS Proton 파라미터](parameters.md).

**참고**  
CodeBuild 프로비저닝을 환경 및 서비스와 함께 사용할 수 있습니다. 현재로서는 이 방법으로 구성 요소를 프로비저닝할 수 없습니다.

## 입력 파라미터
<a name="parameters-codebuild.input"></a>

환경 또는 서비스와 같은 AWS Proton 리소스를 생성할 때 템플릿의 [스키마 파일에](ag-schema.md) 정의된 입력 파라미터 값을 제공합니다. 생성한 리소스가를 사용하는 경우 [CodeBuild 프로비저닝](ag-works-prov-methods.md#ag-works-prov-methods-codebuild)는 이러한 입력 값을 입력 파일로 AWS Proton 렌더링합니다. 프로비저닝 코드는 이 파일에서 파라미터 값을 가져오고 가져올 수 있습니다.

CodeBuild 템플릿의 예는 [CodeBuild 프로비저닝 템플릿 번들](ag-infrastructure-tmp-files-codebuild.md)을 참조하세요. 매니페스트 파일에 대한 자세한 내용은 [에 대한 템플릿 파일 정리 AWS Proton](ag-wrap-up.md) 단원을 참조하세요.

다음 예제는 서비스 인스턴스의 CodeBuild 기반 프로비저닝 중에 생성된 JSON 입력 파일입니다.

### 예: CodeBuild 프로비저닝과 AWS CDK 함께 사용
<a name="parameters-codebuild.example"></a>

```
{
  "service_instance": {
    "name": "my-service-staging",
    "inputs": {
      "port": "8080",
      "task_size": "medium"
    }
  },
  "service": {
    "name": "my-service"
  },
  "environment": {
    "account_id": "123456789012",
    "name": "my-env-staging",
    "outputs": {
      "vpc-id": "hdh2323423"
    }
  }
}
```

## 출력 파라미터
<a name="parameters-codebuild.output"></a>

리소스 프로비저닝 출력을에 다시 전달하기 위해 AWS Proton프로비저닝 코드는 템플릿의 스키마 파일에 정의된 출력 파라미터 값을 `proton-outputs.json` 사용하여 라는 JSON 파일을 생성할 수 있습니다. [스키마 파일](ag-schema.md) 예를 들어 `cdk deploy` 명령에는 프로비저닝 출력이 있는 JSON 파일을 생성 AWS CDK 하도록에 지시하는 `--outputs-file` 인수가 있습니다. 리소스가를 사용하는 경우 CodeBuild 템플릿 매니페스트에 다음 명령을 AWS CDK지정합니다.

```
aws proton notify-resource-deployment-status-change
```

AWS Proton 는이 JSON 파일을 찾습니다. 프로비저닝 코드가 성공적으로 완료된 후 파일이 있는 경우는 파일에서 출력 파라미터 값을 AWS Proton 읽습니다.

# Terraform 코드형 인프라(IaC) 파일 파라미터 세부 정보 및 예제
<a name="env-parameters-tform"></a>

템플릿 번들의 `variable.tf` 파일에 Terraform 입력 변수를 포함할 수 있습니다. 스키마를 생성하여 관리형 변수를 생성할 AWS Proton 수도 있습니다.는 스키마 파일`.tf files`에서 변수를 AWS Proton 생성합니다. 자세한 내용은 [Terraform IaC 파일](ag-infrastructure-tmp-files-terraform.md) 단원을 참조하십시오.

인프라에서 스키마 정의 AWS Proton 변수를 참조하려면 Terraform IaC 테이블의 파라미터 및 네임스페이스에 AWS Proton 표시된 네임스페이스를 `.tf files`사용합니다. * IaC* 예를 들어 `var.environment.inputs.vpc_cidr`를 사용할 수 있습니다. 따옴표 안에 이러한 변수를 대괄호로 묶고 첫 번째 중괄호 앞에 달러 기호를 추가합니다(예: `“${var.environment.inputs.vpc_cidr}”`).

다음 예제에서는 네임스페이스를 사용하여 환경에 AWS Proton 파라미터를 포함하는 방법을 보여줍니다`.tf file`.

```
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
  // This tells terraform to store the state file in s3 at the location
  // s3://terraform-state-bucket/tf-os-sample/terraform.tfstate
  backend "s3" {
    bucket = "terraform-state-bucket"
    key    = "tf-os-sample/terraform.tfstate"
    region = "us-east-1"
  }
}

// Configure the AWS Provider
provider "aws" {
  region = "us-east-1"
  default_tags {
    tags = var.proton_tags
  }
}

resource "aws_ssm_parameter" "my_ssm_parameter" {
  name  = "my_ssm_parameter"
  type  = "String"
  // Use the Proton environment.inputs. namespace
  value = var.environment.inputs.ssm_parameter_value
}
```

# AWS Proton 코드형 인프라 파일
<a name="ag-infrastructure-tmp-files"></a>

템플릿 번들의 주요 부분은 프로비저닝하려는 인프라 리소스 및 속성을 정의하는 *코드형 인프라(IaC) 파일*입니다. 코드형 인프라 엔진 AWS CloudFormation 은 이러한 유형의 파일을 사용하여 인프라 리소스를 프로비저닝합니다.

**참고**  
IaC 파일은 템플릿 번들과 독립적으로 *직접 정의된 구성 요소*에 대한 직접 입력으로 사용할 수도 있습니다. 구성 요소에 대한 자세한 내용은 [AWS Proton 구성 요소](ag-components.md)를 참조하세요.

AWS Proton 는 현재 두 가지 유형의 IaC 파일을 지원합니다.
+ *[CloudFormation](ag-infrastructure-tmp-files-cloudformation.md) 파일* — *AWS관리형 프로비저닝*에 사용됩니다. AWS Proton 는 파라미터화를 위해 CloudFormation 템플릿 파일 형식 위에 Jinja를 사용합니다.
+ *[Terraform HCL](ag-infrastructure-tmp-files-terraform.md)* - *자체 관리형 프로비저닝*에 사용됩니다. HCL은 기본적으로 파라미터화를 지원합니다.

프로비저닝 방법 조합을 사용하여 AWS Proton 리소스를 프로비저닝할 수 없습니다. 단, 둘 중 하나만 사용해야 합니다. 자체 AWS관리형 프로비저닝 환경에는 관리형 프로비저닝 서비스를 배포할 수 없으며, 그 반대의 경우도 마찬가지입니다.

자세한 내용은 [가 인프라를 AWS Proton 프로비저닝하는 방법](ag-works-prov-methods.md), [AWS Proton 환경](ag-environments.md), [AWS Proton 서비스](ag-services.md) 및 [AWS Proton 구성 요소](ag-components.md) 부분을 참조하세요.

# CloudFormation IaC 파일
<a name="ag-infrastructure-tmp-files-cloudformation"></a>

에서 코드 파일로 AWS CloudFormation 인프라를 사용하는 방법을 알아봅니다 AWS Proton. CloudFormation 는 AWS 리소스를 모델링하고 설정하는 데 도움이 되는 코드형 인프라(IaC) 서비스입니다. parametrization. AWS Proton expands 파라미터에 대한 CloudFormation 템플릿 파일 형식 위에 Jinja를 사용하여 템플릿에서 인프라 리소스를 정의하고 전체 CloudFormation 템플릿을 렌더링합니다. CloudFormation은 정의된 리소스를 CloudFormation 스택으로 프로비저닝합니다. 자세한 정보는 CloudFormation 사용 설명서*의 [CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)(이)란 무엇입니까?* 를 참조하세요.

AWS Proton 는 CloudFormation IaC에 대한 [AWS관리형 프로비저닝을](ag-works-prov-methods.md#ag-works-prov-methods-direct) 지원합니다.

## 기존 인프라를 코드 파일로 사용하여 시작하세요.
<a name="iac-tmp-files"></a>

와 함께 사용할 *기존 코드형* 인프라(IaC) 파일을 조정할 수 있습니다 AWS Proton.

다음 CloudFormation 예제인 [예제 1](#ag-env-cfn-example)과 [예제 2](#ag-svc-cfn-example)는 *기존* CloudFormation IaC 파일을 나타냅니다. CloudFormation은 이러한 파일을 사용하여 두 개의 서로 다른 CloudFormation 스택을 생성할 수 있습니다.

[예제 1](#ag-env-cfn-example)에서 CloudFormation IaC 파일은 컨테이너 애플리케이션 간에 공유할 인프라를 프로비저닝하도록 구성되어 있습니다. 이 예시에서는 동일한 IaC 파일을 사용하여 프로비저닝된 인프라 세트를 여러 개 생성할 수 있도록 입력 파라미터가 추가되었습니다. 각 세트는 서로 다른 VPC 및 서브넷 CIDR 값 세트와 함께 서로 다른 이름을 가질 수 있습니다. 관리자 또는 개발자는 IaC 파일을 사용하여 CloudFormation으로 인프라 리소스를 프로비저닝할 때 이러한 파라미터에 값을 제공합니다. 편의를 위해 이 예제에서는 이러한 입력 파라미터가 주석으로 표시되고 여러 번 참조됩니다. *출력*은 템플릿 끝에 정의됩니다. 다른 CloudFormation IaC 파일에서 참조할 수 있습니다.

[예제 2](#ag-svc-cfn-example)에서 CloudFormation IaC 파일은 *예제 1*에서 프로비저닝된 인프라에 애플리케이션을 배포하도록 구성되어 있습니다. 편의를 위해 파라미터가 주석 처리되어 있습니다.

### 예제 1: CloudFormation IaC 파일
<a name="ag-env-cfn-example"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS Fargate cluster running containers in a public subnet. Only supports
             public facing load balancer, and public service discovery namespaces.
Parameters:
   VpcCIDR:       # input parameter
        Description: CIDR for VPC
        Type: String
        Default: "10.0.0.0/16"
   SubnetOneCIDR: # input parameter
        Description: CIDR for SubnetOne
        Type: String
        Default: "10.0.0.0/24"
   SubnetTwoCIDR: # input parameters
        Description: CIDR for SubnetTwo
        Type: String
        Default: "10.0.1.0/24"
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      EnableDnsSupport: true
      EnableDnsHostnames: true
      CidrBlock: 
        Ref: 'VpcCIDR'

  # Two public subnets, where containers will have public IP addresses
  PublicSubnetOne:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone:
         Fn::Select:
         - 0
         - Fn::GetAZs: {Ref: 'AWS::Region'}
      VpcId: !Ref 'VPC'
      CidrBlock:
         Ref: 'SubnetOneCIDR'
      MapPublicIpOnLaunch: true

  PublicSubnetTwo:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone:
         Fn::Select:
         - 1
         - Fn::GetAZs: {Ref: 'AWS::Region'}
      VpcId: !Ref 'VPC'
      CidrBlock:
        Ref: 'SubnetTwoCIDR'
      MapPublicIpOnLaunch: true

  # Setup networking resources for the public subnets. Containers
  # in the public subnets have public IP addresses and the routing table
  # sends network traffic via the internet gateway.
  InternetGateway:
    Type: AWS::EC2::InternetGateway
  GatewayAttachement:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref 'VPC'
      InternetGatewayId: !Ref 'InternetGateway'
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref 'VPC'
  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: GatewayAttachement
    Properties:
      RouteTableId: !Ref 'PublicRouteTable'
      DestinationCidrBlock: '0.0.0.0/0'
      GatewayId: !Ref 'InternetGateway'
  PublicSubnetOneRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetOne
      RouteTableId: !Ref PublicRouteTable
  PublicSubnetTwoRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetTwo
      RouteTableId: !Ref PublicRouteTable

  # ECS Resources
  ECSCluster:
    Type: AWS::ECS::Cluster

  # A security group for the containers we will run in Fargate.
  # Rules are added to this security group based on what ingress you
  # add for the cluster.
  ContainerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Access to the Fargate containers
      VpcId: !Ref 'VPC'

  # This is a role which is used by the ECS tasks themselves.
  ECSTaskExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: [ecs-tasks.amazonaws.com]
          Action: ['sts:AssumeRole']
      Path: /
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'

# These output values will be available to other templates to use.
Outputs:
  ClusterName:                                               # output
    Description: The name of the ECS cluster
    Value: !Ref 'ECSCluster'
    Export:
      Name:
        Fn::Sub: "${AWS::StackName}-ECSCluster"
  ECSTaskExecutionRole:                                       # output
    Description: The ARN of the ECS role
    Value: !GetAtt 'ECSTaskExecutionRole.Arn'
    Export: 
      Name:
        Fn::Sub: "${AWS::StackName}-ECSTaskExecutionRole"
  VpcId:                                                      # output
    Description: The ID of the VPC that this stack is deployed in
    Value: !Ref 'VPC'
    Export: 
      Name: 
        Fn::Sub: "${AWS::StackName}-VPC"
  PublicSubnetOne:                                            # output
    Description: Public subnet one
    Value: !Ref 'PublicSubnetOne'
    Export: 
      Name:
        Fn::Sub: "${AWS::StackName}-PublicSubnetOne"
  PublicSubnetTwo:                                            # output
    Description: Public subnet two
    Value: !Ref 'PublicSubnetTwo'
    Export: 
      Name:
        Fn::Sub: "${AWS::StackName}-PublicSubnetTwo"
  ContainerSecurityGroup:                                     # output
    Description: A security group used to allow Fargate containers to receive traffic
    Value: !Ref 'ContainerSecurityGroup'
    Export: 
      Name:
        Fn::Sub: "${AWS::StackName}-ContainerSecurityGroup"
```

### 예제 2: CloudFormation IaC 파일
<a name="ag-svc-cfn-example"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy a service on AWS Fargate, hosted in a public subnet, and accessible via a public load balancer.
Parameters:
    ContainerPortInput:  # input parameter
        Description: The port to route traffic to
        Type: Number
        Default: 80
    TaskCountInput:      # input parameter
        Description: The default number of Fargate tasks you want running
        Type: Number
        Default: 1
    TaskSizeInput:       # input parameter
        Description: The size of the task you want to run
        Type: String
        Default: x-small
    ContainerImageInput: # input parameter
        Description: The name/url of the container image
        Type: String
        Default: "public.ecr.aws/z9d2n7e1/nginx:1.19.5"
    TaskNameInput:       # input parameter
        Description: Name for your task
        Type: String
        Default: "my-fargate-instance"
    StackName:           # input parameter
        Description: Name of the environment stack to deploy to
        Type: String
        Default: "my-fargate-environment"
Mappings:
  TaskSizeMap:
    x-small:
      cpu: 256
      memory: 512
    small:
      cpu: 512
      memory: 1024
    medium:
      cpu: 1024
      memory: 2048
    large:
      cpu: 2048
      memory: 4096
    x-large:
      cpu: 4096
      memory: 8192
Resources:
  # A log group for storing the stdout logs from this service's containers
  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName:
        Ref: 'TaskNameInput' # input parameter

  # The task definition. This is a simple metadata description of what
  # container to run, and what resource requirements it has.
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: !Ref 'TaskNameInput'
      Cpu: !FindInMap [TaskSizeMap, !Ref 'TaskSizeInput', cpu]
      Memory: !FindInMap [TaskSizeMap, !Ref 'TaskSizeInput', memory]
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      ExecutionRoleArn:
        Fn::ImportValue:
          !Sub "${StackName}-ECSTaskExecutionRole"    # output parameter from another CloudFormation template
              awslogs-region: !Ref 'AWS::Region'
              awslogs-stream-prefix: !Ref 'TaskNameInput'
                

  # The service_instance. The service is a resource which allows you to run multiple
  # copies of a type of task, and gather up their logs and metrics, as well
  # as monitor the number of running tasks and replace any that have crashed
  Service:
    Type: AWS::ECS::Service
    DependsOn: LoadBalancerRule
    Properties:
      ServiceName: !Ref 'TaskNameInput'
      Cluster:
        Fn::ImportValue:
          !Sub "${StackName}-ECSCluster"  # output parameter from another CloudFormation template
      LaunchType: FARGATE
      DeploymentConfiguration:
        MaximumPercent: 200
        MinimumHealthyPercent: 75
      DesiredCount: !Ref 'TaskCountInput'
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
            - Fn::ImportValue:
                !Sub "${StackName}-ContainerSecurityGroup"    # output parameter from another CloudFormation template
          Subnets:
            - Fn::ImportValue:r CloudFormation template
      TaskRoleArn: !Ref "AWS::NoValue"
      ContainerDefinitions:        
        - Name: !Ref 'TaskNameInput'
          Cpu: !FindInMap [TaskSizeMap, !Ref 'TaskSizeInput', cpu]
          Memory: !FindInMap [TaskSizeMap, !Ref 'TaskSizeInput', memory]
          Image: !Ref 'ContainerImageInput'             # input parameter
          PortMappings:
            - ContainerPort: !Ref 'ContainerPortInput'  # input parameter
          
          LogConfiguration:
            LogDriver: 'awslogs'
            Options:
              awslogs-group: !Ref 'TaskNameInput'
                !Sub "${StackName}-PublicSubnetOne"    # output parameter from another CloudFormation template
            - Fn::ImportValue:
                !Sub "${StackName}-PublicSubnetTwo"    # output parameter from another CloudFormation template
      TaskDefinition: !Ref 'TaskDefinition'
      LoadBalancers:
        - ContainerName: !Ref 'TaskNameInput'
          ContainerPort: !Ref 'ContainerPortInput'  # input parameter
          TargetGroupArn: !Ref 'TargetGroup'

  # A target group. This is used for keeping track of all the tasks, and
  # what IP addresses / port numbers they have. You can query it yourself,
  # to use the addresses yourself, but most often this target group is just
  # connected to an application load balancer, or network load balancer, so
  # it can automatically distribute traffic across all the targets.
  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 6
      HealthCheckPath: /
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 2
      TargetType: ip
      Name: !Ref 'TaskNameInput'
      Port: !Ref 'ContainerPortInput'
      Protocol: HTTP
      UnhealthyThresholdCount: 2
      VpcId:
        Fn::ImportValue:
          !Sub "${StackName}-VPC"    # output parameter from another CloudFormation template

  # Create a rule on the load balancer for routing traffic to the target group
  LoadBalancerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - TargetGroupArn: !Ref 'TargetGroup'
          Type: 'forward'
      Conditions:
        - Field: path-pattern
          Values:
            - '*'
      ListenerArn: !Ref PublicLoadBalancerListener
      Priority: 1

  # Enable autoscaling for this service
  ScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    DependsOn: Service
    Properties:
      ServiceNamespace: 'ecs'
      ScalableDimension: 'ecs:service:DesiredCount'
      ResourceId:
        Fn::Join:
          - '/'
          - - service
            - Fn::ImportValue:
                !Sub "${StackName}-ECSCluster"
            - !Ref 'TaskNameInput'
      MinCapacity: 1
      MaxCapacity: 10
      RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService

  # Create scaling policies for the service
  ScaleDownPolicy:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    DependsOn: ScalableTarget
    Properties:
      PolicyName:
        Fn::Join:
          - '/'
          - - scale
            - !Ref 'TaskNameInput'
            - down
      PolicyType: StepScaling
      ResourceId:
        Fn::Join:
          - '/'
          - - service
            - Fn::ImportValue:
                !Sub "${StackName}-ECSCluster"  # output parameter from another CloudFormation template
            - !Ref 'TaskNameInput'
      ScalableDimension: 'ecs:service:DesiredCount'
      ServiceNamespace: 'ecs'
      StepScalingPolicyConfiguration:
        AdjustmentType: 'ChangeInCapacity'
        StepAdjustments:
          - MetricIntervalUpperBound: 0
            ScalingAdjustment: -1
        MetricAggregationType: 'Average'
        Cooldown: 60

  ScaleUpPolicy:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    DependsOn: ScalableTarget
    Properties:
      PolicyName:
        Fn::Join:
          - '/'
          - - scale
            - !Ref 'TaskNameInput'
            - up
      PolicyType: StepScaling
      ResourceId:
        Fn::Join:
          - '/'
          - - service
            - Fn::ImportValue:
                !Sub "${StackName}-ECSCluster"
            - !Ref 'TaskNameInput'
      ScalableDimension: 'ecs:service:DesiredCount'
      ServiceNamespace: 'ecs'
      StepScalingPolicyConfiguration:
        AdjustmentType: 'ChangeInCapacity'
        StepAdjustments:
          - MetricIntervalLowerBound: 0
            MetricIntervalUpperBound: 15
            ScalingAdjustment: 1
          - MetricIntervalLowerBound: 15
            MetricIntervalUpperBound: 25
            ScalingAdjustment: 2
          - MetricIntervalLowerBound: 25
            ScalingAdjustment: 3
        MetricAggregationType: 'Average'
        Cooldown: 60

  # Create alarms to trigger these policies
  LowCpuUsageAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName:
        Fn::Join:
          - '-'
          - - low-cpu
            - !Ref 'TaskNameInput'
      AlarmDescription:
        Fn::Join:
          - ' '
          - - "Low CPU utilization for service"
            - !Ref 'TaskNameInput'
      MetricName: CPUUtilization
      Namespace: AWS/ECS
      Dimensions:
        - Name: ServiceName
          Value: !Ref 'TaskNameInput'
        - Name: ClusterName
          Value:
            Fn::ImportValue:
              !Sub "${StackName}-ECSCluster"
      Statistic: Average
      Period: 60
      EvaluationPeriods: 1
      Threshold: 20
      ComparisonOperator: LessThanOrEqualToThreshold
      AlarmActions:
        - !Ref ScaleDownPolicy

  HighCpuUsageAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName:
        Fn::Join:
          - '-'
          - - high-cpu
            - !Ref 'TaskNameInput'
      AlarmDescription:
        Fn::Join:
          - ' '
          - - "High CPU utilization for service"
            - !Ref 'TaskNameInput'
      MetricName: CPUUtilization
      Namespace: AWS/ECS
      Dimensions:
        - Name: ServiceName
          Value: !Ref 'TaskNameInput'
        - Name: ClusterName
          Value:
            Fn::ImportValue:
              !Sub "${StackName}-ECSCluster"
      Statistic: Average
      Period: 60
      EvaluationPeriods: 1
      Threshold: 70
      ComparisonOperator: GreaterThanOrEqualToThreshold
      AlarmActions:
        - !Ref ScaleUpPolicy

  EcsSecurityGroupIngressFromPublicALB:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      Description: Ingress from the public ALB
      GroupId:
        Fn::ImportValue:
          !Sub "${StackName}-ContainerSecurityGroup"
      IpProtocol: -1
      SourceSecurityGroupId: !Ref 'PublicLoadBalancerSG'

  # Public load balancer, hosted in public subnets that is accessible
  # to the public, and is intended to route traffic to one or more public
  # facing services. This is used for accepting traffic from the public
  # internet and directing it to public facing microservices
  PublicLoadBalancerSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Access to the public facing load balancer
      VpcId:
        Fn::ImportValue:
          !Sub "${StackName}-VPC"
      SecurityGroupIngress:
          # Allow access to ALB from anywhere on the internet
          - CidrIp: 0.0.0.0/0
            IpProtocol: -1

  PublicLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Scheme: internet-facing
      LoadBalancerAttributes:
      - Key: idle_timeout.timeout_seconds
        Value: '30'
      Subnets:
        # The load balancer is placed into the public subnets, so that traffic
        # from the internet can reach the load balancer directly via the internet gateway
        - Fn::ImportValue:
            !Sub "${StackName}-PublicSubnetOne"
        - Fn::ImportValue:
            !Sub "${StackName}-PublicSubnetTwo"
      SecurityGroups: [!Ref 'PublicLoadBalancerSG']

  PublicLoadBalancerListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    DependsOn:
      - PublicLoadBalancer
    Properties:
      DefaultActions:
        - TargetGroupArn: !Ref 'TargetGroup'
          Type: 'forward'
      LoadBalancerArn: !Ref 'PublicLoadBalancer'
      Port: 80
      Protocol: HTTP
# These output values will be available to other templates to use.
Outputs:
  ServiceEndpoint:        # output
    Description: The URL to access the service
    Value: !Sub "http://${PublicLoadBalancer.DNSName}"
```

이러한 파일을와 함께 사용하도록 조정할 수 있습니다 AWS Proton.

## 코드형 인프라를 로 가져오기 AWS Proton
<a name="proton-tmp-files"></a>

약간 수정하면 [가 환경을 배포하는 데 사용하는 환경 템플릿 번들의 코드형 인프라(IaC) 파일로 예제 1](#ag-env-cfn-example)을 사용할 수 있습니다([예제 3](#ag-proton-env-cfn-example) 참조).IaC AWS Proton 

CloudFormation 파라미터를 사용하는 대신 [Jinja](https://jinja.palletsprojects.com/en/2.11.x/templates/) 구문을 사용하여 [Open API](https://swagger.io/docs/specification/data-models/) 기반 [스키마 파일](ag-schema.md)에 정의한 파라미터를 참조하세요. 이러한 입력 파라미터는 편의를 위해 주석 처리되며 IaC 파일에서 여러 번 참조됩니다. 이렇게 하면가 파라미터 값을 감사하고 확인할 AWS Proton 수 있습니다. 또한 한 IaC 파일의 출력 파라미터 값을 다른 IaC 파일의 파라미터와 일치시키고 삽입할 수 있습니다.

관리자는 입력 파라미터에 AWS Proton `environment.inputs.` 네임스페이스를 추가할 수 있습니다. 서비스 IaC 파일의 환경 IaC 파일 출력을 참조하는 경우 출력에 `environment.outputs.` 네임스페이스를 추가할 수 있습니다 (예: `environment.outputs.ClusterName`). 마지막으로 중괄호와 따옴표로 묶습니다.

이러한 수정을 통해에서 CloudFormation IaC 파일을 사용할 수 있습니다 AWS Proton.

### 예제 3: 코드 파일로서의 AWS Proton 환경 인프라
<a name="ag-proton-env-cfn-example"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS Fargate cluster running containers in a public subnet. Only supports
             public facing load balancer, and public service discovery prefixes.
Mappings:
  # The VPC and subnet configuration is passed in via the environment spec.
  SubnetConfig:
    VPC:
      CIDR: '{{ environment.inputs.vpc_cidr}}'        # input parameter
    PublicOne:
      CIDR: '{{ environment.inputs.subnet_one_cidr}}' # input parameter
    PublicTwo:
      CIDR: '{{ environment.inputs.subnet_two_cidr}}' # input parameter
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      EnableDnsSupport: true
      EnableDnsHostnames: true
      CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR']

  # Two public subnets, where containers will have public IP addresses
  PublicSubnetOne:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone:
         Fn::Select:
         - 0
         - Fn::GetAZs: {Ref: 'AWS::Region'}
      VpcId: !Ref 'VPC'
      CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR']
      MapPublicIpOnLaunch: true

  PublicSubnetTwo:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone:
         Fn::Select:
         - 1
         - Fn::GetAZs: {Ref: 'AWS::Region'}
      VpcId: !Ref 'VPC'
      CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR']
      MapPublicIpOnLaunch: true

  # Setup networking resources for the public subnets. Containers
  # in the public subnets have public IP addresses and the routing table
  # sends network traffic via the internet gateway.
  InternetGateway:
    Type: AWS::EC2::InternetGateway
  GatewayAttachement:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref 'VPC'
      InternetGatewayId: !Ref 'InternetGateway'
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref 'VPC'
  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: GatewayAttachement
    Properties:
      RouteTableId: !Ref 'PublicRouteTable'
      DestinationCidrBlock: '0.0.0.0/0'
      GatewayId: !Ref 'InternetGateway'
  PublicSubnetOneRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetOne
      RouteTableId: !Ref PublicRouteTable
  PublicSubnetTwoRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetTwo
      RouteTableId: !Ref PublicRouteTable

  # ECS Resources
  ECSCluster:
    Type: AWS::ECS::Cluster

  # A security group for the containers we will run in Fargate.
  # Rules are added to this security group based on what ingress you
  # add for the cluster.
  ContainerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Access to the Fargate containers
      VpcId: !Ref 'VPC'

  # This is a role which is used by the ECS tasks themselves.
  ECSTaskExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: [ecs-tasks.amazonaws.com]
          Action: ['sts:AssumeRole']
      Path: /
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'

# These output values are available to service infrastructure as code files as outputs, when given the 
# the 'service_instance.environment.outputs.' namespace, for example, service_instance.environment.outputs.ClusterName.

Outputs:
  ClusterName:                                            # output
    Description: The name of the ECS cluster
    Value: !Ref 'ECSCluster'
  ECSTaskExecutionRole:                                   # output
    Description: The ARN of the ECS role
    Value: !GetAtt 'ECSTaskExecutionRole.Arn'
  VpcId:                                                  # output
    Description: The ID of the VPC that this stack is deployed in
    Value: !Ref 'VPC'
  PublicSubnetOne:                                        # output
    Description: Public subnet one
    Value: !Ref 'PublicSubnetOne'
  PublicSubnetTwo:                                        # output
    Description: Public subnet two
    Value: !Ref 'PublicSubnetTwo'
  ContainerSecurityGroup:                                 # output
    Description: A security group used to allow Fargate containers to receive traffic
    Value: !Ref 'ContainerSecurityGroup'
```

[예제 1](#ag-env-cfn-example)과 [예제 3](#ag-proton-env-cfn-example) IaC 파일은 약간 다른 CloudFormation 스택을 생성합니다. 스택 템플릿 파일에서는 파라미터가 다르게 표시됩니다. *예제 1* CloudFormation 스택 템플릿 파일은 스택 템플릿 보기에 파라미터 레이블(키)을 표시합니다. *예제 3* AWS Proton CloudFormation 인프라 스택 템플릿 파일에는 파라미터 값이 표시됩니다. AWS Proton 입력 파라미터는 콘솔 CloudFormation 스택 파라미터 보기에 표시되지 *않습니다*.

[예제 4](#ag-proton-svc-cfn-example)에서 AWS Proton 서비스 IaC 파일은 [예제 2](#ag-svc-cfn-example)에 해당합니다.

### 예제 4: AWS Proton 서비스 인스턴스 IaC 파일
<a name="ag-proton-svc-cfn-example"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy a service on AWS Fargate, hosted in a public subnet, and accessible via a public load balancer.
Mappings:
  TaskSize:
    x-small:
      cpu: 256
      memory: 512
    small:
      cpu: 512
      memory: 1024
    medium:
      cpu: 1024
      memory: 2048
    large:
      cpu: 2048
      memory: 4096
    x-large:
      cpu: 4096
      memory: 8192
Resources:
  # A log group for storing the stdout logs from this service's containers
  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: '{{service_instance.name}}' # resource parameter

  # The task definition. This is a simple metadata description of what
  # container to run, and what resource requirements it has.
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: '{{service_instance.name}}'
      Cpu: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, cpu] # input parameter
      Memory: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, memory] 
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      ExecutionRoleArn: '{{environment.outputs.ECSTaskExecutionRole}}' # output from an environment infrastructure as code file
      TaskRoleArn: !Ref "AWS::NoValue"
      ContainerDefinitions:
        - Name: '{{service_instance.name}}'
          Cpu: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, cpu]
          Memory: !FindInMap [TaskSize, {{service_instance.inputs.task_size}}, memory]
          Image: '{{service_instance.inputs.image}}'
          PortMappings:
            - ContainerPort: '{{service_instance.inputs.port}}' # input parameter
          LogConfiguration:
            LogDriver: 'awslogs'
            Options:
              awslogs-group: '{{service_instance.name}}'
              awslogs-region: !Ref 'AWS::Region'
              awslogs-stream-prefix: '{{service_instance.name}}'

  # The service_instance. The service is a resource which allows you to run multiple
  # copies of a type of task, and gather up their logs and metrics, as well
  # as monitor the number of running tasks and replace any that have crashed
  Service:
    Type: AWS::ECS::Service
    DependsOn: LoadBalancerRule
    Properties:
      ServiceName: '{{service_instance.name}}'
      Cluster: '{{environment.outputs.ClusterName}}' # output from an environment infrastructure as code file
      LaunchType: FARGATE
      DeploymentConfiguration:
        MaximumPercent: 200
        MinimumHealthyPercent: 75
      DesiredCount: '{{service_instance.inputs.desired_count}}'       # input parameter
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          SecurityGroups:
            - '{{environment.outputs.ContainerSecurityGroup}}' # output from an environment infrastructure as code file
          Subnets:
            - '{{environment.outputs.PublicSubnetOne}}'        # output from an environment infrastructure as code file
            - '{{environment.outputs.PublicSubnetTwo}}'
      TaskDefinition: !Ref 'TaskDefinition'
      LoadBalancers:
        - ContainerName: '{{service_instance.name}}'
          ContainerPort: '{{service_instance.inputs.port}}'
          TargetGroupArn: !Ref 'TargetGroup'

  # A target group. This is used for keeping track of all the tasks, and
  # what IP addresses / port numbers they have. You can query it yourself,
  # to use the addresses yourself, but most often this target group is just
  # connected to an application load balancer, or network load balancer, so
  # it can automatically distribute traffic across all the targets.
  TargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 6
      HealthCheckPath: /
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 2
      TargetType: ip
      Name: '{{service_instance.name}}'
      Port: '{{service_instance.inputs.port}}'
      Protocol: HTTP
      UnhealthyThresholdCount: 2
      VpcId: '{{environment.outputs.VpcId}}' # output from an environment infrastructure as code file

  # Create a rule on the load balancer for routing traffic to the target group
  LoadBalancerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - TargetGroupArn: !Ref 'TargetGroup'
          Type: 'forward'
      Conditions:
        - Field: path-pattern
          Values:
            - '*'
      ListenerArn: !Ref PublicLoadBalancerListener
      Priority: 1

  # Enable autoscaling for this service
  ScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    DependsOn: Service
    Properties:
      ServiceNamespace: 'ecs'
      ScalableDimension: 'ecs:service:DesiredCount'
      ResourceId:
        Fn::Join:
          - '/'
          - - service
            - '{{environment.outputs.ClusterName}}' # output from an environment infrastructure as code file
            - '{{service_instance.name}}'
      MinCapacity: 1
      MaxCapacity: 10
      RoleARN: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService

  # Create scaling policies for the service
  ScaleDownPolicy:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    DependsOn: ScalableTarget
    Properties:
      PolicyName:
        Fn::Join:
          - '/'
          - - scale
            - '{{service_instance.name}}'
            - down
      PolicyType: StepScaling
      ResourceId:
        Fn::Join:
          - '/'
          - - service
            - '{{environment.outputs.ClusterName}}'
            - '{{service_instance.name}}'
      ScalableDimension: 'ecs:service:DesiredCount'
      ServiceNamespace: 'ecs'
      StepScalingPolicyConfiguration:
        AdjustmentType: 'ChangeInCapacity'
        StepAdjustments:
          - MetricIntervalUpperBound: 0
            ScalingAdjustment: -1
        MetricAggregationType: 'Average'
        Cooldown: 60

  ScaleUpPolicy:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    DependsOn: ScalableTarget
    Properties:
      PolicyName:
        Fn::Join:
          - '/'
          - - scale
            - '{{service_instance.name}}'
            - up
      PolicyType: StepScaling
      ResourceId:
        Fn::Join:
          - '/'
          - - service
            - '{{environment.outputs.ClusterName}}'
            - '{{service_instance.name}}'
      ScalableDimension: 'ecs:service:DesiredCount'
      ServiceNamespace: 'ecs'
      StepScalingPolicyConfiguration:
        AdjustmentType: 'ChangeInCapacity'
        StepAdjustments:
          - MetricIntervalLowerBound: 0
            MetricIntervalUpperBound: 15
            ScalingAdjustment: 1
          - MetricIntervalLowerBound: 15
            MetricIntervalUpperBound: 25
            ScalingAdjustment: 2
          - MetricIntervalLowerBound: 25
            ScalingAdjustment: 3
        MetricAggregationType: 'Average'
        Cooldown: 60

  # Create alarms to trigger these policies
  LowCpuUsageAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName:
        Fn::Join:
          - '-'
          - - low-cpu
            - '{{service_instance.name}}'
      AlarmDescription:
        Fn::Join:
          - ' '
          - - "Low CPU utilization for service"
            - '{{service_instance.name}}'
      MetricName: CPUUtilization
      Namespace: AWS/ECS
      Dimensions:
        - Name: ServiceName
          Value: '{{service_instance.name}}'
        - Name: ClusterName
          Value:
            '{{environment.outputs.ClusterName}}'
      Statistic: Average
      Period: 60
      EvaluationPeriods: 1
      Threshold: 20
      ComparisonOperator: LessThanOrEqualToThreshold
      AlarmActions:
        - !Ref ScaleDownPolicy

  HighCpuUsageAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName:
        Fn::Join:
          - '-'
          - - high-cpu
            - '{{service_instance.name}}'
      AlarmDescription:
        Fn::Join:
          - ' '
          - - "High CPU utilization for service"
            - '{{service_instance.name}}'
      MetricName: CPUUtilization
      Namespace: AWS/ECS
      Dimensions:
        - Name: ServiceName
          Value: '{{service_instance.name}}'
        - Name: ClusterName
          Value:
            '{{environment.outputs.ClusterName}}'
      Statistic: Average
      Period: 60
      EvaluationPeriods: 1
      Threshold: 70
      ComparisonOperator: GreaterThanOrEqualToThreshold
      AlarmActions:
        - !Ref ScaleUpPolicy

  EcsSecurityGroupIngressFromPublicALB:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      Description: Ingress from the public ALB
      GroupId: '{{environment.outputs.ContainerSecurityGroup}}'
      IpProtocol: -1
      SourceSecurityGroupId: !Ref 'PublicLoadBalancerSG'

  # Public load balancer, hosted in public subnets that is accessible
  # to the public, and is intended to route traffic to one or more public
  # facing services. This is used for accepting traffic from the public
  # internet and directing it to public facing microservices
  PublicLoadBalancerSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Access to the public facing load balancer
      VpcId: '{{environment.outputs.VpcId}}'
      SecurityGroupIngress:
          # Allow access to ALB from anywhere on the internet
          - CidrIp: 0.0.0.0/0
            IpProtocol: -1

  PublicLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Scheme: internet-facing
      LoadBalancerAttributes:
      - Key: idle_timeout.timeout_seconds
        Value: '30'
      Subnets:
        # The load balancer is placed into the public subnets, so that traffic
        # from the internet can reach the load balancer directly via the internet gateway
        - '{{environment.outputs.PublicSubnetOne}}'
        - '{{environment.outputs.PublicSubnetTwo}}'
      SecurityGroups: [!Ref 'PublicLoadBalancerSG']

  PublicLoadBalancerListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    DependsOn:
      - PublicLoadBalancer
    Properties:
      DefaultActions:
        - TargetGroupArn: !Ref 'TargetGroup'
          Type: 'forward'
      LoadBalancerArn: !Ref 'PublicLoadBalancer'
      Port: 80
      Protocol: HTTP
Outputs:
  ServiceEndpoint:         # output
    Description: The URL to access the service
    Value: !Sub "http://${PublicLoadBalancer.DNSName}"
```

[예제 5](#ag-proton-pipeline-cfn-example)에서 AWS Proton 파이프라인 IaC 파일은 [예제 4](#ag-proton-svc-cfn-example)에서 프로비저닝된 서비스 인스턴스를 지원하도록 파이프라인 인프라를 프로비저닝합니다.

### 예제 5: AWS Proton 서비스 파이프라인 IaC 파일
<a name="ag-proton-pipeline-cfn-example"></a>

```
Resources:
  ECRRepo:
    Type: AWS::ECR::Repository
    DeletionPolicy: Retain
  BuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Artifacts:
        Type: CODEPIPELINE
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
        PrivilegedMode: true
        Type: LINUX_CONTAINER
        EnvironmentVariables:
        - Name: repo_name
          Type: PLAINTEXT
          Value: !Ref ECRRepo
        - Name: service_name
          Type: PLAINTEXT
          Value: '{{ service.name }}'    # resource parameter
      ServiceRole:
        Fn::GetAtt:
          - PublishRole
          - Arn
      Source:
        BuildSpec:
          Fn::Join:
            - ""
            - - >-
                {
                  "version": "0.2",
                  "phases": {
                    "install": {
                      "runtime-versions": {
                        "docker": 18
                      },
                      "commands": [
                        "pip3 install --upgrade --user awscli",
                        "echo 'f6bd1536a743ab170b35c94ed4c7c4479763356bd543af5d391122f4af852460  yq_linux_amd64' > yq_linux_amd64.sha",
                        "wget https://github.com/mikefarah/yq/releases/download/3.4.0/yq_linux_amd64",
                        "sha256sum -c yq_linux_amd64.sha",
                        "mv yq_linux_amd64 /usr/bin/yq",
                        "chmod +x /usr/bin/yq"
                      ]
                    },
                    "pre_build": {
                      "commands": [
                        "cd $CODEBUILD_SRC_DIR",
                        "$(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)",
                        "{{ pipeline.inputs.unit_test_command }}",    # input parameter
                      ]
                    },
                    "build": {
                      "commands": [
                        "IMAGE_REPO_NAME=$repo_name",
                        "IMAGE_TAG=$CODEBUILD_BUILD_NUMBER",
                        "IMAGE_ID=
              - Ref: AWS::AccountId
              - >-
                .dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG",
                        "docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG -f {{ pipeline.inputs.dockerfile }} .",     # input parameter
                        "docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $IMAGE_ID;",
                        "docker push $IMAGE_ID"
                      ]
                    },
                    "post_build": {
                      "commands": [
                        "aws proton --region $AWS_DEFAULT_REGION get-service --name $service_name | jq -r .service.spec > service.yaml",
                        "yq w service.yaml 'instances[*].spec.image' \"$IMAGE_ID\" > rendered_service.yaml"
                      ]
                    }
                  },
                  "artifacts": {
                    "files": [
                      "rendered_service.yaml"
                    ]
                  }
                }
        Type: CODEPIPELINE
      EncryptionKey:
        Fn::GetAtt:
          - PipelineArtifactsBucketEncryptionKey
          - Arn
{% for service_instance in service_instances %}
  Deploy{{loop.index}}Project:
    Type: AWS::CodeBuild::Project
    Properties:
      Artifacts:
        Type: CODEPIPELINE
      Environment:
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
        PrivilegedMode: false
        Type: LINUX_CONTAINER
        EnvironmentVariables:
        - Name: service_name
          Type: PLAINTEXT
          Value:  '{{service.name}}'          # resource parameter
        - Name: service_instance_name
          Type: PLAINTEXT
          Value: '{{service_instance.name}}'  # resource parameter
      ServiceRole:
        Fn::GetAtt:
          - DeploymentRole
          - Arn
      Source:
        BuildSpec: >-
          {
            "version": "0.2",
            "phases": {
              "build": {
                "commands": [
                  "pip3 install --upgrade --user awscli",
                  "aws proton --region $AWS_DEFAULT_REGION update-service-instance --deployment-type CURRENT_VERSION --name $service_instance_name --service-name $service_name --spec file://rendered_service.yaml",
                  "aws proton --region $AWS_DEFAULT_REGION wait service-instance-deployed --name $service_instance_name --service-name $service_name"
                ]
              }
            }
          }
        Type: CODEPIPELINE
      EncryptionKey:
        Fn::GetAtt:
          - PipelineArtifactsBucketEncryptionKey
          - Arn
{% endfor %}
  # This role is used to build and publish an image to ECR
  PublishRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
        Version: "2012-10-17"		 	 	 
  PublishRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - logs:CreateLogGroup
              - logs:CreateLogStream
              - logs:PutLogEvents
            Effect: Allow
            Resource:
              - Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":logs:"
                    - Ref: AWS::Region
                    - ":"
                    - Ref: AWS::AccountId
                    - :log-group:/aws/codebuild/
                    - Ref: BuildProject
              - Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":logs:"
                    - Ref: AWS::Region
                    - ":"
                    - Ref: AWS::AccountId
                    - :log-group:/aws/codebuild/
                    - Ref: BuildProject
                    - :*
          - Action:
              - codebuild:CreateReportGroup
              - codebuild:CreateReport
              - codebuild:UpdateReport
              - codebuild:BatchPutTestCases
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - "arn:"
                  - Ref: AWS::Partition
                  - ":codebuild:"
                  - Ref: AWS::Region
                  - ":"
                  - Ref: AWS::AccountId
                  - :report-group/
                  - Ref: BuildProject
                  - -*
          - Action:
              - ecr:GetAuthorizationToken
            Effect: Allow
            Resource: "*"
          - Action:
              - ecr:BatchCheckLayerAvailability
              - ecr:CompleteLayerUpload
              - ecr:GetAuthorizationToken
              - ecr:InitiateLayerUpload
              - ecr:PutImage
              - ecr:UploadLayerPart
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - ECRRepo
                - Arn
          - Action:
              - proton:GetService
            Effect: Allow
            Resource: "*"
          - Action:
              - s3:GetObject*
              - s3:GetBucket*
              - s3:List*
              - s3:DeleteObject*
              - s3:PutObject*
              - s3:Abort*
            Effect: Allow
            Resource:
              - Fn::GetAtt:
                  - PipelineArtifactsBucket
                  - Arn
              - Fn::Join:
                  - ""
                  - - Fn::GetAtt:
                        - PipelineArtifactsBucket
                        - Arn
                    - /*
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineArtifactsBucketEncryptionKey
                - Arn
          - Action:
              - kms:Decrypt
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineArtifactsBucketEncryptionKey
                - Arn
        Version: "2012-10-17"		 	 	 
      PolicyName: PublishRoleDefaultPolicy
      Roles:
        - Ref: PublishRole

  DeploymentRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
        Version: "2012-10-17"		 	 	 
  DeploymentRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - logs:CreateLogGroup
              - logs:CreateLogStream
              - logs:PutLogEvents
            Effect: Allow
            Resource:
              - Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":logs:"
                    - Ref: AWS::Region
                    - ":"
                    - Ref: AWS::AccountId
                    - :log-group:/aws/codebuild/Deploy*Project*
              - Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":logs:"
                    - Ref: AWS::Region
                    - ":"
                    - Ref: AWS::AccountId
                    - :log-group:/aws/codebuild/Deploy*Project:*
          - Action:
              - codebuild:CreateReportGroup
              - codebuild:CreateReport
              - codebuild:UpdateReport
              - codebuild:BatchPutTestCases
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - "arn:"
                  - Ref: AWS::Partition
                  - ":codebuild:"
                  - Ref: AWS::Region
                  - ":"
                  - Ref: AWS::AccountId
                  - :report-group/Deploy*Project
                  - -*
          - Action:
              - proton:UpdateServiceInstance
              - proton:GetServiceInstance
            Effect: Allow
            Resource: "*"
          - Action:
              - s3:GetObject*
              - s3:GetBucket*
              - s3:List*
            Effect: Allow
            Resource:
              - Fn::GetAtt:
                  - PipelineArtifactsBucket
                  - Arn
              - Fn::Join:
                  - ""
                  - - Fn::GetAtt:
                        - PipelineArtifactsBucket
                        - Arn
                    - /*
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineArtifactsBucketEncryptionKey
                - Arn
          - Action:
              - kms:Decrypt
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineArtifactsBucketEncryptionKey
                - Arn
        Version: "2012-10-17"		 	 	 
      PolicyName: DeploymentRoleDefaultPolicy
      Roles:
        - Ref: DeploymentRole
  PipelineArtifactsBucketEncryptionKey:
    Type: AWS::KMS::Key
    Properties:
      KeyPolicy:
        Statement:
          - Action:
              - kms:Create*
              - kms:Describe*
              - kms:Enable*
              - kms:List*
              - kms:Put*
              - kms:Update*
              - kms:Revoke*
              - kms:Disable*
              - kms:Get*
              - kms:Delete*
              - kms:ScheduleKeyDeletion
              - kms:CancelKeyDeletion
              - kms:GenerateDataKey
              - kms:TagResource
              - kms:UntagResource
            Effect: Allow
            Principal:
              AWS:
                Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":iam::"
                    - Ref: AWS::AccountId
                    - :root
            Resource: "*"
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Principal:
              AWS:
                Fn::GetAtt:
                  - PipelineRole
                  - Arn
            Resource: "*"
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Principal:
              AWS:
                Fn::GetAtt:
                  - PublishRole
                  - Arn
            Resource: "*"
          - Action:
              - kms:Decrypt
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Principal:
              AWS:
                Fn::GetAtt:
                  - PublishRole
                  - Arn
            Resource: "*"
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
            Effect: Allow
            Principal:
              AWS:
                Fn::GetAtt:
                  - DeploymentRole
                  - Arn
            Resource: "*"
          - Action:
              - kms:Decrypt
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Principal:
              AWS:
                Fn::GetAtt:
                  - DeploymentRole
                  - Arn
            Resource: "*"
        Version: "2012-10-17"		 	 	 
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
  PipelineArtifactsBucket:
    Type: AWS::S3::Bucket
    Properties:
      VersioningConfiguration:
        Status: Enabled
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              KMSMasterKeyID:
                Fn::GetAtt:
                  - PipelineArtifactsBucketEncryptionKey
                  - Arn
              SSEAlgorithm: aws:kms
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
  PipelineArtifactsBucketEncryptionKeyAlias:
    Type: AWS::KMS::Alias
    Properties:
      AliasName: 'alias/codepipeline-encryption-key-{{ service.name }}'
      TargetKeyId:
        Fn::GetAtt:
          - PipelineArtifactsBucketEncryptionKey
          - Arn
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
  PipelineRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: codepipeline.amazonaws.com
        Version: "2012-10-17"		 	 	 
  PipelineRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - s3:GetObject*
              - s3:GetBucket*
              - s3:List*
              - s3:DeleteObject*
              - s3:PutObject*
              - s3:Abort*
            Effect: Allow
            Resource:
              - Fn::GetAtt:
                  - PipelineArtifactsBucket
                  - Arn
              - Fn::Join:
                  - ""
                  - - Fn::GetAtt:
                        - PipelineArtifactsBucket
                        - Arn
                    - /*
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineArtifactsBucketEncryptionKey
                - Arn
          - Action: codestar-connections:*
            Effect: Allow
            Resource: "*"
          - Action: sts:AssumeRole
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineBuildCodePipelineActionRole
                - Arn
          - Action: sts:AssumeRole
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineDeployCodePipelineActionRole
                - Arn
        Version: "2012-10-17"		 	 	 
      PolicyName: PipelineRoleDefaultPolicy
      Roles:
        - Ref: PipelineRole
  Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn:
        Fn::GetAtt:
          - PipelineRole
          - Arn
      Stages:
        - Actions:
            - ActionTypeId:
                Category: Source
                Owner: AWS
                Provider: CodeStarSourceConnection
                Version: "1"
              Configuration:
                ConnectionArn: '{{ service.repository_connection_arn }}'
                FullRepositoryId: '{{ service.repository_id }}'
                BranchName: '{{ service.branch_name }}'
              Name: Checkout
              OutputArtifacts:
                - Name: Artifact_Source_Checkout
              RunOrder: 1
          Name: Source
        - Actions:
            - ActionTypeId:
                Category: Build
                Owner: AWS
                Provider: CodeBuild
                Version: "1"
              Configuration:
                ProjectName:
                  Ref: BuildProject
              InputArtifacts:
                - Name: Artifact_Source_Checkout
              Name: Build
              OutputArtifacts:
                - Name: BuildOutput
              RoleArn:
                Fn::GetAtt:
                  - PipelineBuildCodePipelineActionRole
                  - Arn
              RunOrder: 1
          Name: Build {%- for service_instance in service_instances %}
        - Actions:
            - ActionTypeId:
                Category: Build
                Owner: AWS
                Provider: CodeBuild
                Version: "1"
              Configuration:
                ProjectName:
                  Ref: Deploy{{loop.index}}Project
              InputArtifacts:
                - Name: BuildOutput
              Name: Deploy
              RoleArn:
                Fn::GetAtt:
                  - PipelineDeployCodePipelineActionRole
                  - Arn
              RunOrder: 1
          Name: 'Deploy{{service_instance.name}}'
{%- endfor %}
      ArtifactStore:
        EncryptionKey:
          Id:
            Fn::GetAtt:
              - PipelineArtifactsBucketEncryptionKey
              - Arn
          Type: KMS
        Location:
          Ref: PipelineArtifactsBucket
        Type: S3
    DependsOn:
      - PipelineRoleDefaultPolicy
      - PipelineRole
  PipelineBuildCodePipelineActionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              AWS:
                Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":iam::"
                    - Ref: AWS::AccountId
                    - :root
        Version: "2012-10-17"		 	 	 
  PipelineBuildCodePipelineActionRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - codebuild:BatchGetBuilds
              - codebuild:StartBuild
              - codebuild:StopBuild
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - BuildProject
                - Arn
        Version: "2012-10-17"		 	 	 
      PolicyName: PipelineBuildCodePipelineActionRoleDefaultPolicy
      Roles:
        - Ref: PipelineBuildCodePipelineActionRole
  PipelineDeployCodePipelineActionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              AWS:
                Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":iam::"
                    - Ref: AWS::AccountId
                    - :root
        Version: "2012-10-17"		 	 	 
  PipelineDeployCodePipelineActionRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - codebuild:BatchGetBuilds
              - codebuild:StartBuild
              - codebuild:StopBuild
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - "arn:"
                  - Ref: AWS::Partition
                  - ":codebuild:"
                  - Ref: AWS::Region
                  - ":"
                  - Ref: AWS::AccountId
                  - ":project/Deploy*"
        Version: "2012-10-17"		 	 	 
      PolicyName: PipelineDeployCodePipelineActionRoleDefaultPolicy
      Roles:
        - Ref: PipelineDeployCodePipelineActionRole
Outputs:
  PipelineEndpoint:
    Description: The URL to access the pipeline
    Value: !Sub "https://${AWS::Region}.console.aws.amazon.com/codesuite/codepipeline/pipelines/${Pipeline}/view?region=${AWS::Region}"

                ]
              }
            }
          }
        Type: CODEPIPELINE
      EncryptionKey:
        Fn::GetAtt:
          - PipelineArtifactsBucketEncryptionKey
          - Arn
{% endfor %}
  # This role is used to build and publish an image to ECR
  PublishRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
        Version: "2012-10-17"		 	 	 
  PublishRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - logs:CreateLogGroup
              - logs:CreateLogStream
              - logs:PutLogEvents
            Effect: Allow
            Resource:
              - Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":logs:"
                    - Ref: AWS::Region
                    - ":"
                    - Ref: AWS::AccountId
                    - :log-group:/aws/codebuild/
                    - Ref: BuildProject
              - Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":logs:"
                    - Ref: AWS::Region
                    - ":"
                    - Ref: AWS::AccountId
                    - :log-group:/aws/codebuild/
                    - Ref: BuildProject
                    - :*
          - Action:
              - codebuild:CreateReportGroup
              - codebuild:CreateReport
              - codebuild:UpdateReport
              - codebuild:BatchPutTestCases
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - "arn:"
                  - Ref: AWS::Partition
                  - ":codebuild:"
                  - Ref: AWS::Region
                  - ":"
                  - Ref: AWS::AccountId
                  - :report-group/
                  - Ref: BuildProject
                  - -*
          - Action:
              - ecr:GetAuthorizationToken
            Effect: Allow
            Resource: "*"
          - Action:
              - ecr:BatchCheckLayerAvailability
              - ecr:CompleteLayerUpload
              - ecr:GetAuthorizationToken
              - ecr:InitiateLayerUpload
              - ecr:PutImage
              - ecr:UploadLayerPart
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - ECRRepo
                - Arn
          - Action:
              - proton:GetService
            Effect: Allow
            Resource: "*"
          - Action:
              - s3:GetObject*
              - s3:GetBucket*
              - s3:List*
              - s3:DeleteObject*
              - s3:PutObject*
              - s3:Abort*
            Effect: Allow
            Resource:
              - Fn::GetAtt:
                  - PipelineArtifactsBucket
                  - Arn
              - Fn::Join:
                  - ""
                  - - Fn::GetAtt:
                        - PipelineArtifactsBucket
                        - Arn
                    - /*
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineArtifactsBucketEncryptionKey
                - Arn
          - Action:
              - kms:Decrypt
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineArtifactsBucketEncryptionKey
                - Arn
        Version: "2012-10-17"		 	 	 
      PolicyName: PublishRoleDefaultPolicy
      Roles:
        - Ref: PublishRole

  DeploymentRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: codebuild.amazonaws.com
        Version: "2012-10-17"		 	 	 
  DeploymentRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - logs:CreateLogGroup
              - logs:CreateLogStream
              - logs:PutLogEvents
            Effect: Allow
            Resource:
              - Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":logs:"
                    - Ref: AWS::Region
                    - ":"
                    - Ref: AWS::AccountId
                    - :log-group:/aws/codebuild/Deploy*Project*
              - Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":logs:"
                    - Ref: AWS::Region
                    - ":"
                    - Ref: AWS::AccountId
                    - :log-group:/aws/codebuild/Deploy*Project:*
          - Action:
              - codebuild:CreateReportGroup
              - codebuild:CreateReport
              - codebuild:UpdateReport
              - codebuild:BatchPutTestCases
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - "arn:"
                  - Ref: AWS::Partition
                  - ":codebuild:"
                  - Ref: AWS::Region
                  - ":"
                  - Ref: AWS::AccountId
                  - :report-group/Deploy*Project
                  - -*
          - Action:
              - proton:UpdateServiceInstance
              - proton:GetServiceInstance
            Effect: Allow
            Resource: "*"
          - Action:
              - s3:GetObject*
              - s3:GetBucket*
              - s3:List*
            Effect: Allow
            Resource:
              - Fn::GetAtt:
                  - PipelineArtifactsBucket
                  - Arn
              - Fn::Join:
                  - ""
                  - - Fn::GetAtt:
                        - PipelineArtifactsBucket
                        - Arn
                    - /*
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineArtifactsBucketEncryptionKey
                - Arn
          - Action:
              - kms:Decrypt
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineArtifactsBucketEncryptionKey
                - Arn
        Version: "2012-10-17"		 	 	 
      PolicyName: DeploymentRoleDefaultPolicy
      Roles:
        - Ref: DeploymentRole
  PipelineArtifactsBucketEncryptionKey:
    Type: AWS::KMS::Key
    Properties:
      KeyPolicy:
        Statement:
          - Action:
              - kms:Create*
              - kms:Describe*
              - kms:Enable*
              - kms:List*
              - kms:Put*
              - kms:Update*
              - kms:Revoke*
              - kms:Disable*
              - kms:Get*
              - kms:Delete*
              - kms:ScheduleKeyDeletion
              - kms:CancelKeyDeletion
              - kms:GenerateDataKey
              - kms:TagResource
              - kms:UntagResource
            Effect: Allow
            Principal:
              AWS:
                Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":iam::"
                    - Ref: AWS::AccountId
                    - :root
            Resource: "*"
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Principal:
              AWS:
                Fn::GetAtt:
                  - PipelineRole
                  - Arn
            Resource: "*"
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Principal:
              AWS:
                Fn::GetAtt:
                  - PublishRole
                  - Arn
            Resource: "*"
          - Action:
              - kms:Decrypt
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Principal:
              AWS:
                Fn::GetAtt:
                  - PublishRole
                  - Arn
            Resource: "*"
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
            Effect: Allow
            Principal:
              AWS:
                Fn::GetAtt:
                  - DeploymentRole
                  - Arn
            Resource: "*"
          - Action:
              - kms:Decrypt
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Principal:
              AWS:
                Fn::GetAtt:
                  - DeploymentRole
                  - Arn
            Resource: "*"
        Version: "2012-10-17"		 	 	 
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
  PipelineArtifactsBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              KMSMasterKeyID:
                Fn::GetAtt:
                  - PipelineArtifactsBucketEncryptionKey
                  - Arn
              SSEAlgorithm: aws:kms
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
  PipelineArtifactsBucketEncryptionKeyAlias:
    Type: AWS::KMS::Alias
    Properties:
      AliasName: 'alias/codepipeline-encryption-key-{{ service.name }}'     # resource parameter
      TargetKeyId:
        Fn::GetAtt:
          - PipelineArtifactsBucketEncryptionKey
          - Arn
    UpdateReplacePolicy: Delete
    DeletionPolicy: Delete
  PipelineRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: codepipeline.amazonaws.com
        Version: "2012-10-17"		 	 	 
  PipelineRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - s3:GetObject*
              - s3:GetBucket*
              - s3:List*
              - s3:DeleteObject*
              - s3:PutObject*
              - s3:Abort*
            Effect: Allow
            Resource:
              - Fn::GetAtt:
                  - PipelineArtifactsBucket
                  - Arn
              - Fn::Join:
                  - ""
                  - - Fn::GetAtt:
                        - PipelineArtifactsBucket
                        - Arn
                    - /*
          - Action:
              - kms:Decrypt
              - kms:DescribeKey
              - kms:Encrypt
              - kms:ReEncrypt*
              - kms:GenerateDataKey*
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineArtifactsBucketEncryptionKey
                - Arn
          - Action: codestar-connections:*
            Effect: Allow
            Resource: "*"
          - Action: sts:AssumeRole
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineBuildCodePipelineActionRole
                - Arn
          - Action: sts:AssumeRole
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - PipelineDeployCodePipelineActionRole
                - Arn
        Version: "2012-10-17"		 	 	 
      PolicyName: PipelineRoleDefaultPolicy
      Roles:
        - Ref: PipelineRole
  Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn:
        Fn::GetAtt:
          - PipelineRole
          - Arn
      Stages:
        - Actions:
            - ActionTypeId:
                Category: Source
                Owner: AWS
                Provider: CodeStarSourceConnection
                Version: "1"
              Configuration:
                ConnectionArn: '{{ service.repository_connection_arn }}'   # resource parameter
                FullRepositoryId: '{{ service.repository_id }}'            # resource parameter
                BranchName: '{{ service.branch_name }}'                    # resource parameter
              Name: Checkout
              OutputArtifacts:
                - Name: Artifact_Source_Checkout
              RunOrder: 1
          Name: Source
        - Actions:
            - ActionTypeId:
                Category: Build
                Owner: AWS
                Provider: CodeBuild
                Version: "1"
              Configuration:
                ProjectName:
                  Ref: BuildProject
              InputArtifacts:
                - Name: Artifact_Source_Checkout
              Name: Build
              OutputArtifacts:
                - Name: BuildOutput
              RoleArn:
                Fn::GetAtt:
                  - PipelineBuildCodePipelineActionRole
                  - Arn
              RunOrder: 1
          Name: Build {%- for service_instance in service_instances %}
        - Actions:
            - ActionTypeId:
                Category: Build
                Owner: AWS
                Provider: CodeBuild
                Version: "1"
              Configuration:
                ProjectName:
                  Ref: Deploy{{loop.index}}Project
              InputArtifacts:
                - Name: BuildOutput
              Name: Deploy
              RoleArn:
                Fn::GetAtt:
                  - PipelineDeployCodePipelineActionRole
                  - Arn
              RunOrder: 1
          Name: 'Deploy{{service_instance.name}}'         # resource parameter
{%- endfor %}
      ArtifactStore:
        EncryptionKey:
          Id:
            Fn::GetAtt:
              - PipelineArtifactsBucketEncryptionKey
              - Arn
          Type: KMS
        Location:
          Ref: PipelineArtifactsBucket
        Type: S3
    DependsOn:
      - PipelineRoleDefaultPolicy
      - PipelineRole
  PipelineBuildCodePipelineActionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              AWS:
                Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":iam::"
                    - Ref: AWS::AccountId
                    - :root
        Version: "2012-10-17"		 	 	 
  PipelineBuildCodePipelineActionRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - codebuild:BatchGetBuilds
              - codebuild:StartBuild
              - codebuild:StopBuild
            Effect: Allow
            Resource:
              Fn::GetAtt:
                - BuildProject
                - Arn
        Version: "2012-10-17"		 	 	 
      PolicyName: PipelineBuildCodePipelineActionRoleDefaultPolicy
      Roles:
        - Ref: PipelineBuildCodePipelineActionRole
  PipelineDeployCodePipelineActionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              AWS:
                Fn::Join:
                  - ""
                  - - "arn:"
                    - Ref: AWS::Partition
                    - ":iam::"
                    - Ref: AWS::AccountId
                    - :root
        Version: "2012-10-17"		 	 	 
  PipelineDeployCodePipelineActionRoleDefaultPolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyDocument:
        Statement:
          - Action:
              - codebuild:BatchGetBuilds
              - codebuild:StartBuild
              - codebuild:StopBuild
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - "arn:"
                  - Ref: AWS::Partition
                  - ":codebuild:"
                  - Ref: AWS::Region
                  - ":"
                  - Ref: AWS::AccountId
                  - ":project/Deploy*"
        Version: "2012-10-17"		 	 	 
      PolicyName: PipelineDeployCodePipelineActionRoleDefaultPolicy
      Roles:
        - Ref: PipelineDeployCodePipelineActionRole
Outputs:
  PipelineEndpoint:
    Description: The URL to access the pipeline
    Value: !Sub "https://${AWS::Region}.console.aws.amazon.com/codesuite/codepipeline/pipelines/${Pipeline}/view?region=${AWS::Region}"
```

# CodeBuild 프로비저닝 템플릿 번들
<a name="ag-infrastructure-tmp-files-codebuild"></a>

CodeBuild 프로비저닝을 사용하면 IaC 템플릿을 사용하여 IaC 파일을 렌더링하고 IaC 프로비저닝 엔진을 사용하여 실행하는 대신 셸 명령을 AWS Proton 간단히 실행할 수 있습니다. 이를 위해 AWS Proton 는 환경 계정에서 환경에 대한 AWS CodeBuild 프로젝트를 생성하고 각 AWS Proton 리소스 생성 또는 업데이트에 대해 명령을 실행하는 작업을 시작합니다. 템플릿 번들을 작성할 때는 인프라 프로비저닝 및 프로비저닝 해제 명령과 이러한 명령에 필요할 수 있는 모든 프로그램, 스크립트 및 기타 파일을 지정하는 매니페스트를 제공합니다. 명령은 AWS Proton 이 제공하는 입력을 읽을 수 있으며, 인프라를 프로비저닝 또는 프로비저닝 해제하고 출력 값을 생성할 수 있습니다.

또한 매니페스트는가 코드가 입력하고 입력 값을 가져올 수 있는 입력 파일을 AWS Proton 렌더링하는 방법을 지정합니다. JSON 또는 HCL로 렌더링할 수 있습니다. 파라미터에 대한 자세한 내용은 [CodeBuild 프로비저닝 파라미터 세부 정보 및 예제](parameters-codebuild.md)를 참조하세요. 매니페스트 파일에 대한 자세한 내용은 [에 대한 템플릿 파일 정리 AWS Proton](ag-wrap-up.md) 단원을 참조하세요.

**참고**  
CodeBuild 프로비저닝을 환경 및 서비스와 함께 사용할 수 있습니다. 현재로서는 이 방법으로 구성 요소를 프로비저닝할 수 없습니다.

## 예: CodeBuild 프로비저닝과 AWS CDK 함께 사용
<a name="ag-infrastructure-tmp-files-codebuild.example"></a>

CodeBuild 프로비저닝을 사용하는 예로를 사용하여 AWS 리소스를 AWS Cloud Development Kit (AWS CDK) 프로비저닝(*배포*) 및 프로비저닝 해제(*파기*)하는 코드와 CDK를 설치하고 CDK 코드를 실행하는 매니페스트를 포함할 수 있습니다.

다음 섹션에는 AWS CDK를 사용하여 환경을 프로비저닝하는 CodeBuild 프로비저닝 템플릿 번들에 포함할 수 있는 예제 파일이 나열되어 있습니다.

### 매니페스트
<a name="ag-infrastructure-tmp-files-codebuild.example.manifest"></a>

다음 매니페스트 파일은 CodeBuild 프로비저닝을 지정하며를 설치하고 사용하는 데 필요한 명령 AWS CDK, 출력 파일 처리 및 출력을에 다시 보고하는 명령을 포함합니다 AWS Proton.

**Example infrastructure/manifest.yaml**  

```
infrastructure:
  templates:
    - rendering_engine: codebuild
      settings:
        image: aws/codebuild/amazonlinux2-x86_64-standard:4.0
        runtimes:
          nodejs: 16
        provision:
          - npm install
          - npm run build
          - npm run cdk bootstrap
          - npm run cdk deploy -- --require-approval never --outputs-file proton-outputs.json
          - jq 'to_entries | map_values(.value) | add | to_entries | map({key:.key, valueString:.value})' < proton-outputs.json > outputs.json
          - aws proton notify-resource-deployment-status-change --resource-arn $RESOURCE_ARN --status IN_PROGRESS --outputs file://./outputs.json
        deprovision:
          - npm install
          - npm run build
          - npm run cdk destroy
        project_properties:
          VpcConfig:
            VpcId: "{{ environment.inputs.codebuild_vpc_id }}"
            Subnets: "{{ environment.inputs.codebuild_subnets }}"
            SecurityGroupIds: "{{ environment.inputs.codebuild_security_groups }}"
```

### Schema
<a name="ag-infrastructure-tmp-files-codebuild.example.schema"></a>

다음 스키마 파일은 환경 파라미터를 정의합니다. AWS CDK 코드는 배포 중에 이러한 파라미터의 값을 참조할 수 있습니다.

**Example schema/schema.yaml**  

```
schema:
  format:
    openapi: "3.0.0"
  environment_input_type: "MyEnvironmentInputType"
  types:
    MyEnvironmentInputType:
      type: object
      description: "Input properties for my environment"
      properties:
        my_sample_input:
          type: string
          description: "This is a sample input"
          default: "hello world"
        my_other_sample_input:
          type: string
          description: "Another sample input"
      required:
        - my_other_sample_input
```

### AWS CDK 파일
<a name="ag-infrastructure-tmp-files-codebuild.example.cdkcode"></a>

다음 파일은 Node.js CDK 프로젝트의 예제입니다.

**Example infrastructure/package.json**  

```
{
  "name": "ProtonEnvironment",
  "version": "0.1.0",
  "bin": {
    "ProtonEnvironmente": "bin/ProtonEnvironment.js"
  },
  "scripts": {
    "build": "tsc",
    "watch": "tsc -w",
    "test": "jest",
    "cdk": "cdk"
  },
  "devDependencies": {
    "@types/jest": "^28.1.7",
    "@types/node": "18.7.6",
    "jest": "^28.1.3",
    "ts-jest": "^28.0.8",
    "aws-cdk": "2.37.1",
    "ts-node": "^10.9.1",
    "typescript": "~4.7.4"
  },
  "dependencies": {
    "aws-cdk-lib": "2.37.1",
    "constructs": "^10.1.77",
    "source-map-support": "^0.5.21"
  }
}
```

**Example infrastructure/tsconfig.json**  

```
{
  "compilerOptions": {
    "target": "ES2018",
    "module": "commonjs",
    "lib": [
      "es2018"
    ],
    "declaration": true,
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": false,
    "inlineSourceMap": true,
    "inlineSources": true,
    "experimentalDecorators": true,
    "strictPropertyInitialization": false,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "typeRoots": [
      "./node_modules/@types"
    ]
  },
  "exclude": [
    "node_modules",
    "cdk.out"
  ]
}
```

**Example infrastructure/cdk.json**  

```
{
  "app": "npx ts-node --prefer-ts-exts bin/ProtonEnvironment.ts",
  "outputsFile": "proton-outputs.json",
  "watch": {
    "include": [
      "**"
    ],
    "exclude": [
      "README.md",
      "cdk*.json",
      "**/*.d.ts",
      "**/*.js",
      "tsconfig.json",
      "package*.json",
      "yarn.lock",
      "node_modules",
      "test"
    ]
  },
  "context": {
    "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
    "@aws-cdk/core:stackRelativeExports": true,
    "@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
    "@aws-cdk/aws-lambda:recognizeVersionProps": true,
    "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
    "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
    "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
    "@aws-cdk/core:target-partitions": [
      "aws",
      "aws-cn"
    ]
  }
}
```

**Example infrastructure/bin/ProtonEnvironment.ts**  

```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { ProtonEnvironmentStack } from '../lib/ProtonEnvironmentStack';

const app = new cdk.App();
new ProtonEnvironmentStack(app, 'ProtonEnvironmentStack', {});
```

**Example infrastructure/lib/ProtonEnvironmentStack.ts**  

```
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as cdk from 'aws-cdk-lib';
import * as ssm from 'aws-cdk-lib/aws-ssm';
import input from '../proton-inputs.json';

export class ProtonEnvironmentStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, { ...props, stackName: process.env.STACK_NAME });

    const ssmParam = new ssm.StringParameter(this, "ssmParam", {
      stringValue: input.environment.inputs.my_sample_input,
      parameterName: `${process.env.STACK_NAME}-Param`,
      tier: ssm.ParameterTier.STANDARD
    })

    new cdk.CfnOutput(this, 'ssmParamOutput', {
      value: ssmParam.parameterName,
      description: 'The name of the ssm parameter',
      exportName: `${process.env.STACK_NAME}-Param`
    });
  }
}
```

### 렌더링된 입력 파일
<a name="ag-infrastructure-tmp-files-codebuild.example.manifest"></a>

CodeBuild 기반 프로비저닝 템플릿을 사용하여 환경을 만들면 AWS Proton 은 사용자가 제공한 [입력 파라미터 값](https://docs.aws.amazon.com/proton/latest/userguide/parameters.html)이 포함된 입력 파일을 렌더링합니다. 코드에서 이러한 값을 참조할 수 있습니다. 다음 파일은 렌더링된 입력 파일의 예제입니다.

**Example infrastructure/proton-inputs.json**  

```
{
  "environment": {
    "name": "myenv",
    "inputs": {
      "my_sample_input": "10.0.0.0/16",
      "my_other_sample_input": "11.0.0.0/16"
    }
  }
}
```

# Terraform IaC 파일
<a name="ag-infrastructure-tmp-files-terraform"></a>

Terraform 코드형 인프라(IaC) 파일을와 함께 사용하는 방법을 알아봅니다 AWS Proton. [Terraform은](https://www.terraform.io/) [HashiCorp](https://www.hashicorp.com/)에서 개발한 널리 사용되는 오픈 소스 IaC 엔진입니다. Terraform 모듈은 HashiCorp의 HCL 언어로 개발되었으며 Web Services를 비롯한 여러 백엔드 인프라 제공업체를 지원합니다.

AWS Proton 는 Terraform IaC[에 대한 자체 관리형 프로비저닝을](ag-works-prov-methods.md#ag-works-prov-methods-self) 지원합니다.

풀 리퀘스트에 응답하고 인프라 프로비저닝을 구현하는 프로비저닝 리포지토리의 전체 예시는 GitHub의 [AWS Proton용 Terraform 오픈 소스 GitHub 작업 자동화 템플릿](https://github.com/aws-samples/aws-proton-terraform-github-actions-sample)을 참조하세요.

**Terraform IAC 템플릿 번들 파일에서 자체 관리형 프로비저닝이 작동하는 방식:**

1. Terraform 템플릿 번들에서 [환경을 생성](ag-create-env.md)하면가 콘솔 또는 `spec file` 입력 파라미터로 `.tf` 파일을 AWS Proton 컴파일합니다.

1. 컴파일된 IaC 파일을 [AWS Proton에 등록한 리포지토리](ag-create-repo.md)에 병합하기 위해 풀 리퀘스트를 생성합니다.

1. 요청이 승인되면는 사용자가 제공한 프로비저닝 상태를 AWS Proton 기다립니다.

1. 요청이 거부되면 환경 생성이 취소됩니다.

1. 풀 리퀘스트 제한 시간이 초과되면 환경 생성이 완료되지 *않습니다*.

**AWS Proton Terraform IaC 고려 사항 포함:**
+ AWS Proton 는 Terraform 프로비저닝을 관리하지 않습니다.
+ [프로비저닝 리포지토리를에 등록](ag-create-repo.md)해야 합니다 AWS Proton.이 리포지토리에 대한 풀 요청을 AWS Proton 수행합니다.
+ 프로비저닝 리포지토리 AWS Proton 에 연결하려면 [ CodeStar 연결을 생성](setting-up-for-service.md#setting-up-vcontrol)해야 합니다.
+  AWS Proton 컴파일된 IaC 파일에서를 프로비저닝하려면 AWS Proton 풀 요청에 응답해야 합니다. AWS Proton 는 환경 및 서비스 생성 및 업데이트 작업 후 풀 요청을 수행합니다. 자세한 내용은 [AWS Proton 환경](ag-environments.md) 및 [AWS Proton 서비스](ag-services.md) 섹션을 참조하세요.
+  AWS Proton 컴파일된 IaC 파일에서 파이프라인을 프로비저닝하려면 [CI/CD 파이프라인 리포지토리를 생성](setting-up-for-service.md#setting-up-pr-repo)해야 합니다.
+ 풀 요청 기반 프로비저닝 자동화에는 AWS Proton 프로비저닝된 AWS Proton 리소스 상태 변경을 알리는 단계가 포함되어야 합니다. AWS Proton [NotifyResourceDeploymentStatusChange API](https://docs.aws.amazon.com/proton/latest/APIReference/API_NotifyResourceDeploymentStatusChange.html)를 사용할 수 있습니다.
+ CloudFormation IaC 파일에서 생성된 서비스, 파이프라인 및 구성 요소를 Terraform IaC 파일로 만든 환경에 배포할 수 없습니다.
+ Terraform IaC 파일에서 생성된 서비스, 파이프라인 및 구성 요소를 CloudFormation IaC 파일로 만든 환경에 배포할 수 없습니다.

Terraform IaC 파일을 준비 AWS Proton할 때 다음 예제와 같이 네임스페이스를 입력 변수에 연결합니다. 자세한 내용은 [파라미터](parameters.md)를 참조하세요.

## 예제 1: AWS Proton environment Terraform IaC 파일
<a name="ag-env-tform-example"></a>

```
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
  // This tells terraform to store the state file in s3 at the location
  // s3://terraform-state-bucket/tf-os-sample/terraform.tfstate
  backend "s3" {
    bucket = "terraform-state-bucket"
    key    = "tf-os-sample/terraform.tfstate"
    region = "us-east-1"
  }
}

// Configure the AWS Provider
provider "aws" {
  region = "us-east-1"
  default_tags {
    tags = var.proton_tags
  }
}

resource "aws_ssm_parameter" "my_ssm_parameter" {
  name  = "my_ssm_parameter"
  type  = "String"
  // Use the Proton environment.inputs. namespace
  value = var.environment.inputs.ssm_parameter_value
}
```

## 컴파일된 코드형 인프라
<a name="compiled-tform"></a>

환경 또는 서비스를 생성할 때는 콘솔 또는 `spec file` 입력을 사용하여 코드 파일로 인프라를 AWS Proton 컴파일합니다. 다음 예시와 같이 입력에 대한 `proton.resource-type.variables.tf` 및 `proton.auto.tfvars.json` 파일을 생성하여 Terraform에서 사용할 수 있습니다. 이러한 파일은 환경 또는 서비스 인스턴스 이름과 일치하는 폴더의 지정된 리포지토리에 있습니다.

이 예제에서는가 변수 정의 및 변수 값에 태그를 AWS Proton 포함하는 방법과 이러한 AWS Proton 태그를 프로비저닝된 리소스에 전파하는 방법을 보여줍니다. 자세한 내용은 [프로비저닝된 리소스에 태그 전파](resources.md#auto-tags-prop) 단원을 참조하십시오.

### 예 2: 이름이 "dev"인 환경을 위해 컴파일된 IaC 파일.
<a name="ag-compiled-example"></a>

**dev/environment.tf:**

```
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
  // This tells terraform to store the state file in s3 at the location
  // s3://terraform-state-bucket/tf-os-sample/terraform.tfstate
  backend "s3" {
    bucket = "terraform-state-bucket"
    key    = "tf-os-sample/terraform.tfstate"
    region = "us-east-1"
  }
}

// Configure the AWS Provider
provider "aws" {
  region = "us-east-1"
  default_tags {
    tags = var.proton_tags
  }
}

resource "aws_ssm_parameter" "my_ssm_parameter" {
  name  = "my_ssm_parameter"
  type  = "String"
  // Use the Proton environment.inputs. namespace
  value = var.environment.inputs.ssm_parameter_value
}
```

**dev/proton.environment.variables.tf:**

```
variable "environment" {
  type = object({
    inputs = map(string)
    name = string
  })
}

variable "proton_tags" {
  type = map(string)
  default = null
}
```

**dev/proton.auto.tfvars.json:**

```
{
  "environment": {
    "name": "dev",
    "inputs": {
      "ssm_parameter_value": "MyNewParamValue"
    }
  }

  "proton_tags" : {
    "proton:account" : "123456789012",
    "proton:template" : "arn:aws:proton:us-east-1:123456789012:environment-template/fargate-env",
    "proton:environment" : "arn:aws:proton:us-east-1:123456789012:environment/dev"
  }
}
```

## 리포지토리 경로
<a name="repo-dir"></a>

AWS Proton 는 환경 또는 서비스 생성 작업의 콘솔 또는 사양 입력을 사용하여 컴파일된 IaC 파일을 찾을 리포지토리와 경로를 찾습니다. 입력 값은 [네임스페이스 입력 파라미터](parameters.md)에 전달됩니다.

AWS Proton 는 두 개의 리포지토리 경로 레이아웃을 지원합니다. 다음 예제에서는 두 환경의 네임스페이스 리소스 파라미터로 경로의 이름을 지정합니다. 각 환경에는 두 서비스의 서비스 인스턴스가 있으며, 이 중 하나의 서비스 인스턴스에는 구성 요소가 직접 정의되어 있습니다.

<a name="limits-table"></a>[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/proton/latest/userguide/ag-infrastructure-tmp-files-terraform.html)

------
#### [ Layout 1 ]

가 `environments` 폴더가 있는 지정된 리포지토리를 AWS Proton 찾으면 컴파일된 IaC 파일을 포함하고 로 이름이 지정된 폴더가 생성됩니다`environment.name`.

에서 서비스 인스턴스 호환 환경 이름과 일치하는 `environments` 폴더 이름이 포함된 폴더가 있는 지정된 리포지토리를 AWS Proton 찾으면 컴파일된 인스턴스 IaC 파일을 포함하고 로 이름이 지정된 폴더가 생성됩니다`service_instance.name`.

```
/repo
    /environments
        /env-prod                             # environment folder
            main.tf
            proton.environment.variables.tf
            proton.auto.tfvars.json
          
            /service-one-instance-one-prod    # instance folder
                main.tf
                proton.service_instance.variables.tf
                proton.auto.tfvars.json
              
            /service-two-instance-two-prod    # instance folder
                main.tf
                proton.service_instance.variables.tf
                proton.auto.tfvars.json
              
            /component-prod                   # component folder
                main.tf
                proton.component.variables.tf
                proton.auto.tfvars.json
              
        /env-staged                           # environment folder
            main.tf
            proton.variables.tf
            proton.auto.tfvars.json         
          
            /service-one-instance-one-staged  # instance folder
                main.tf
                proton.service_instance.variables.tf
                proton.auto.tfvars.json
              
            /service-two-instance-two-staged  # instance folder
                main.tf
                proton.service_instance.variables.tf
                proton.auto.tfvars.json
              
            /component-staged                 # component folder
                main.tf
                proton.component.variables.tf
                proton.auto.tfvars.json
```

------
#### [ Layout 2 ]

가 `environments` 폴더 없이 지정된 리포지토리를 AWS Proton 찾으면 컴파일된 환경 IaC 파일을 찾을 수 있는 `environment.name` 폴더가 생성됩니다.

가 서비스 인스턴스 호환 환경 이름과 일치하는 폴더 이름을 가진 지정된 리포지토리를 AWS Proton 찾으면 컴파일된 인스턴스 IaC 파일을 찾을 `service_instance.name` 폴더를 생성합니다.

```
/repo
    /env-prod                             # environment folder
        main.tf
        proton.environment.variables.tf
        proton.auto.tfvars.json
      
        /service-one-instance-one-prod    # instance folder
            main.tf
            proton.service_instance.variables.tf
            proton.auto.tfvars.json
          
        /service-two-instance-two-prod    # instance folder
            main.tf
            proton.service_instance.variables.tf
            proton.auto.tfvars.json
          
        /component-prod                   # component folder
            main.tf
            proton.component.variables.tf
            proton.auto.tfvars.json
          
    /env-staged                           # environment folder
        main.tf
        proton.variables.tf
        proton.auto.tfvars.json         
      
        /service-one-instance-one-staged  # instance folder
            main.tf
            proton.service_instance.variables.tf
            proton.auto.tfvars.json
          
        /service-two-instance-two-staged  # instance folder
            main.tf
            proton.service_instance.variables.tf
            proton.auto.tfvars.json
          
        /component-staged                 # component folder
            main.tf
            proton.component.variables.tf
            proton.auto.tfvars.json
```

------

# 스키마 파일
<a name="ag-schema"></a>

관리자는 Open API [Data Models(스키마) 섹션을](https://swagger.io/docs/specification/data-models/) 사용하여 템플릿 번들에 대한 파라미터 스키마 YAML 파일을 정의할 때 AWS Proton 에서 스키마에 정의한 요구 사항을 기준으로 파라미터 값 입력을 검증할 수 있습니다.

형식 및 사용 가능한 키워드에 대한 자세한 내용은 OpenAPI의 [스키마 개체](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#schemaObject) 단원을 참조하세요.

## 환경 템플릿 번들에 대한 스키마 요구 사항
<a name="schema-req-env"></a>

스키마는 OpenAPI의 YAML 형식의 [데이터 모델 (스키마) 섹션](https://swagger.io/docs/specification/data-models/)을 따라야 합니다. 또한 환경 템플릿 번들의 일부여야 합니다.

환경 스키마의 경우 Open API의 데이터 모델 (스키마) 섹션을 사용하고 있음을 확인하기 위해 형식이 지정된 헤더를 포함해야 합니다. 다음 환경 스키마 예제에서 이러한 헤더는 처음 세 줄에 표시됩니다.

`environment_input_type`은 반드시 사용자가 제공한 이름과 함께 포함되고 정의되어야 합니다. 다음 예제에서는 5번 줄에 정의되어 있습니다. 이 파라미터를 정의하면 AWS Proton 환경 리소스와 연결됩니다.

Open API 스키마 모델을 따르려면 `types`을 포함해야 합니다. 다음 예제에서는 6번 줄입니다.

`types` 다음으로 `environment_input_type` 유형을 정의해야 합니다. 환경의 입력 파라미터를 `environment_input_type`의 속성으로 정의합니다. 환경 인프라에 스키마와 연결된 코드 (IaC) 파일로 나열된 하나 이상의 파라미터와 일치하는 이름을 가진 속성을 하나 이상 포함해야 합니다.

환경을 생성하고 사용자 지정 파라미터 값을 제공하면는 스키마 파일을 AWS Proton 사용하여 일치하는지 확인하고 연결된 CloudFormation IaC 파일의 중괄호로 묶인 파라미터에 삽입합니다. 각 속성(파라미터)에 대해 `name`와 `type`를 입력합니다. 선택적으로 `description`, `default` 및 `pattern`도 제공합니다.

다음 예제 *표준* 환경 템플릿 스키마의 정의된 파라미터에는 `default` 키워드 및 기본값과 함께 `vpc_cidr`, `subnet_one_cidr` 및 `subnet_two_cidr`이 포함됩니다. 이 환경 템플릿 번들 스키마를 사용하여 환경을 만들 때 기본값을 그대로 사용하거나 사용자 고유의 값을 제공할 수 있습니다. 파라미터가 기본값이 *없고* `required` 속성(파라미터)으로 나열되어 있는 경우 환경을 만들 때 파라미터에 대한 값을 제공해야 합니다.

두 번째 예제 *표준* 환경 템플릿 스키마는 `required` 파라미터 `my_other_sample_input`을 나열합니다.

두 가지 환경 템플릿 유형에 대한 스키마를 생성할 수 있습니다. 자세한 내용은 [템플릿 등록 및 게시](template-create.md) 단원을 참조하세요.
+ ***표준* 환경 템플릿**

  다음 예제에서는 환경 입력 유형이 설명과 입력 속성으로 정의됩니다. 이 스키마 예제는 [예제 3](ag-infrastructure-tmp-files-cloudformation.md#ag-proton-env-cfn-example)에 표시된 AWS Proton CloudFormation IaC 파일과 함께 사용할 수 있습니다.

  *표준* 환경 템플릿의 예제 스키마:

  ```
  schema:                            # required
    format:                          # required
      openapi: "3.0.0"               # required
    # required              defined by administrator
    environment_input_type: "PublicEnvironmentInput"
    types:                           # required
      # defined by administrator
      PublicEnvironmentInput:
        type: object
        description: "Input properties for my environment"
        properties:
          vpc_cidr:                   # parameter
            type: string
            description: "This CIDR range for your VPC"
            default: 10.0.0.0/16
            pattern: ([0-9]{1,3}\.){3}[0-9]{1,3}($|/(16|24))
          subnet_one_cidr:            # parameter
            type: string
            description: "The CIDR range for subnet one"
            default: 10.0.0.0/24
            pattern: ([0-9]{1,3}\.){3}[0-9]{1,3}($|/(16|24))
          subnet_two_cidr:            # parameter
            type: string
            description: "The CIDR range for subnet one"
            default: 10.0.1.0/24
            pattern: ([0-9]{1,3}\.){3}[0-9]{1,3}($|/(16|24))
  ```

  `required` 파라미터가 포함된 *표준* 환경 템플릿의 스키마 예시:

  ```
  schema:                            # required
    format:                          # required
      openapi: "3.0.0"               # required
    # required              defined by administrator
    environment_input_type: "MyEnvironmentInputType"
    types:                           # required
      # defined by administrator
      MyEnvironmentInputType:
        type: object
        description: "Input properties for my environment"
        properties:
          my_sample_input:           # parameter
            type: string
            description: "This is a sample input"
            default: "hello world"
          my_other_sample_input:     # parameter
            type: string
            description: "Another sample input"
          another_optional_input:    # parameter
            type: string
            description: "Another optional input"
            default: "!"
        required:
          - my_other_sample_input
  ```
+ ***고객 관리형* 환경 템플릿**

  다음 예제의 스키마에는 *고객 관리형* 인프라를 프로비저닝하는 데 사용한 IaC의 출력을 복제하는 출력 목록만 포함되어 있습니다. 출력 값 유형은 *문자열로만* 정의해야 합니다(목록, 배열 또는 기타 유형은 정의하지 *않아야* 함). 예를 들어, 다음 코드 스니펫은 외부 CloudFormation 템플릿의 출력 섹션을 보여줍니다. [예제 1](ag-infrastructure-tmp-files-cloudformation.md#ag-env-cfn-example) 에 표시된 템플릿에서 가져온 것입니다. 예제 4에서 생성된 AWS Proton Fargate 서비스에 대한 외부 *고객 관리*형 인프라를 생성하는 데 사용할 수 있습니다. [예제 4: AWS Proton 서비스 인스턴스 IaC 파일](ag-infrastructure-tmp-files-cloudformation.md#ag-proton-svc-cfn-example) 
**중요**  
관리자는 프로비저닝 및 관리형 인프라와 모든 출력 파라미터가 연결된 *고객 관리*형 환경 템플릿과 호환되는지 확인해야 합니다. 이러한 변경 사항은 표시되지 않으므로는 사용자를 대신하여 변경 사항을 AWS Proton 설명할 수 없습니다 AWS Proton. 불일치로 인해 장애가 발생합니다.

  *고객 관리형* 환경 템플릿에 대한 CloudFormation IAC 파일 출력 예시:

  ```
  // Cloudformation Template Outputs
  [...]
  Outputs:
    ClusterName:
      Description: The name of the ECS cluster
      Value: !Ref 'ECSCluster'
    ECSTaskExecutionRole:
      Description: The ARN of the ECS role
      Value: !GetAtt 'ECSTaskExecutionRole.Arn'
    VpcId:
      Description: The ID of the VPC that this stack is deployed in
      Value: !Ref 'VPC'
  [...]
  ```

  해당 AWS Proton *고객 관리*형 환경 템플릿 번들의 스키마는 다음 예제에 나와 있습니다. 각 출력 값은 문자열로 정의됩니다.

  *고객 관리형* 환경 템플릿의 예제 스키마:

  ```
  schema:                            # required
    format:                          # required
      openapi: "3.0.0"               # required
    # required              defined by administrator
    environment_input_type: "EnvironmentOutput"
    types:                           # required
      # defined by administrator
      EnvironmentOutput:
        type: object
        description: "Outputs of the environment"
        properties:
          ClusterName:               # parameter
            type: string
            description: "The name of the ECS cluster"
          ECSTaskExecutionRole:      # parameter
            type: string
            description: "The ARN of the ECS role"
          VpcId:                     # parameter
            type: string
            description: "The ID of the VPC that this stack is deployed in"
  [...]
  ```

## 서비스 템플릿 번들에 대한 스키마 요구 사항
<a name="schema-req-svc"></a>

스키마는 다음 예시와 같이 YAML 형식의 OpenAPI의 [데이터 모델(스키마) 섹션](https://swagger.io/docs/specification/data-models/)을 따라야 합니다. 서비스 템플릿 번들에 스키마 파일을 제공해야 합니다.

다음 서비스 스키마 예제에는 형식이 지정된 헤더를 포함해야 합니다. 다음 예제에서는 처음 세 줄에 해당합니다. 이는 Open API의 데이터 모델 (스키마) 섹션을 사용하고 있음을 확인하기 위한 것입니다.

`service_input_type`은 반드시 사용자가 제공한 이름과 함께 포함되고 정의되어야 합니다. 다음 예제에서는 5번 줄입니다. 이렇게 하면 파라미터가 AWS Proton 서비스 리소스와 연결됩니다.

서비스 AWS Proton 파이프라인은 콘솔 또는 CLI를 사용하여 서비스를 생성할 때 기본적으로 포함됩니다. 서비스에 대한 서비스 파이프라인을 포함할 때는 제공한 이름과 `pipeline_input_type`를 포함해야 합니다. 다음 예제에서는 7번 줄입니다. AWS Proton 서비스 파이프라인을 포함하지 않는 경우이 파라미터를 ** 포함하지 *마십시오*. 자세한 내용은 [템플릿 등록 및 게시](template-create.md) 단원을 참조하십시오.

Open API 스키마 모델을 따르려면 `types`을 포함해야 합니다. 다음 예제에서는 9번째 줄에 있습니다.

`types` 다음으로 `service_input_type` 유형을 정의해야 합니다. 서비스의 입력 파라미터를 `service_input_type`의 속성으로 정의합니다. 스키마와 연결된 서비스 코드형 인프라(IaC) 파일에 나열된 하나 이상의 파라미터와 일치하는 이름의 속성을 하나 이상 포함해야 합니다.

서비스 파이프라인을 정의하려면 `service_input_type` 정의 아래에 `pipeline_input_type`를 정의해야 합니다. 스키마와 연결된 파이프라인 코드형 인프라(IaC) 파일에 나열된 하나 이상의 파라미터와 일치하는 이름의 속성을 하나 이상 포함해야 합니다. AWS Proton 서비스 파이프라인을 포함하지 않는 경우이 정의를 ** 포함하지 *마십시오*.

관리자 또는 개발자가 서비스를 생성하고 사용자 지정 파라미터 값을 제공하는 경우는 스키마 파일을 AWS Proton 사용하여 일치하는지 확인하고 연결된 CloudFormation IaC 파일의 중괄호로 묶인 파라미터에 삽입합니다. 각 속성(파라미터)에 대해 `name`와 `type`를 입력합니다. 선택적으로 `description`, `default` 및 `pattern`도 제공합니다.

예제 스키마에 정의된 파라미터에는 키워드 및 기본값과 `port`, `desired_count`, `task_size`, `image` 및 `default`이 포함됩니다. 이 서비스 템플릿 번들 스키마를 사용하여 서비스를 만들 때 기본값을 사용하거나 고유한 값을 제공할 수 있습니다. 파라미터 `unique_name`도 예제에 포함되어 있으며 기본값이 *없습니다*. `required` 속성(파라미터)으로 나열됩니다. 관리자 또는 개발자는 서비스를 생성할 때 `required` 파라미터 값을 제공해야 합니다.

서비스 파이프라인이 포함된 서비스 템플릿을 생성하려면 스키마에 `pipeline_input_type`를 포함합니다.

**서비스 파이프라인이 포함된 서비스에 대한 AWS Proton 서비스 스키마 파일의 예입니다.**

 이 스키마 예제는 예제 [4 및 예제 ](ag-infrastructure-tmp-files-cloudformation.md#ag-proton-svc-cfn-example)5에 표시된 AWS Proton IaC 파일과 함께 사용할 수 있습니다. [예제 5: AWS Proton 서비스 파이프라인 IaC 파일](ag-infrastructure-tmp-files-cloudformation.md#ag-proton-pipeline-cfn-example) 서비스 파이프라인이 포함됩니다.

```
schema:                            # required
  format:                          # required
    openapi: "3.0.0"               # required
  # required           defined by administrator
  service_input_type: "LoadBalancedServiceInput"
  # only include if including AWS Proton service pipeline, defined by administrator
  pipeline_input_type: "PipelineInputs"

  types:                           # required
    # defined by administrator
    LoadBalancedServiceInput:
      type: object
      description: "Input properties for a loadbalanced Fargate service"
      properties:
        port:                      # parameter
          type: number
          description: "The port to route traffic to"
          default: 80
          minimum: 0
          maximum: 65535
        desired_count:             # parameter
          type: number
          description: "The default number of Fargate tasks you want running"
          default: 1
          minimum: 1
        task_size:                 # parameter
          type: string
          description: "The size of the task you want to run"
          enum: ["x-small", "small", "medium", "large", "x-large"]
          default: "x-small"
        image:                     # parameter
          type: string
          description: "The name/url of the container image"
          default: "public.ecr.aws/z9d2n7e1/nginx:1.19.5"
          minLength: 1
          maxLength: 200
        unique_name:               # parameter
          type: string
          description: "The unique name of your service identifier. This will be used to name your log group, task definition and ECS service"
          minLength: 1
          maxLength: 100
      required:
        - unique_name
    # defined by administrator
    PipelineInputs:
      type: object
      description: "Pipeline input properties"
      properties:
        dockerfile:                # parameter
          type: string
          description: "The location of the Dockerfile to build"
          default: "Dockerfile"
          minLength: 1
          maxLength: 100
        unit_test_command:         # parameter
          type: string
          description: "The command to run to unit test the application code"
          default: "echo 'add your unit test command here'"
          minLength: 1
          maxLength: 200
```

서비스 파이프라인 없이 서비스 템플릿을 만들려면 다음 예시와 같이 스키마에 `pipeline_input_type`를 포함하지 *마십시오*.

**서비스 파이프라인이 포함되지 *않은* 서비스에 대한 AWS Proton 서비스 스키마 파일의 예**

```
schema:                            # required
  format:                          # required
    openapi: "3.0.0"               # required
  # required            defined by administrator  
  service_input_type: "MyServiceInstanceInputType"

  types:                           # required
    # defined by administrator
    MyServiceInstanceInputType:
      type: object
      description: "Service instance input properties"
      required:
        - my_sample_service_instance_required_input
      properties:
        my_sample_service_instance_optional_input:   # parameter
          type: string
          description: "This is a sample input"
          default: "hello world"
        my_sample_service_instance_required_input:   # parameter
          type: string
          description: "Another sample input"
```

# 에 대한 템플릿 파일 정리 AWS Proton
<a name="ag-wrap-up"></a>

환경 및 서비스 코드형 인프라(IaC) 파일과 해당 스키마 파일을 준비한 후에는 디렉토리로 구성해야 합니다. 또한 매니페스트 YAML 파일을 만들어야 합니다. 매니페스트 파일에는 디렉토리의 IaC 파일, 렌더링 엔진 및 이 템플릿의 IaC를 개발하는 데 사용된 템플릿 언어가 나열됩니다.

**참고**  
매니페스트 파일은 템플릿 번들과 매니페스트독립적으로 *직접 정의된 구성 요소*에 대한 직접 입력으로 사용할 수도 있습니다. 이 경우 클라우드포메이션과 테라폼 모두에 대해 항상 단일 IaC 템플릿 파일을 지정합니다. 구성 요소에 대한 자세한 내용은 [AWS Proton 구성 요소](ag-components.md)를 참조하세요.

매니페스트 파일은 다음 예제와 일치해야 합니다.

**CloudFormation 매니페스트 파일 형식:**

CloudFormation을 사용하면 하나의 파일을 나열할 수 있습니다.

```
infrastructure:
  templates:
    - file: "cloudformation.yaml"
      rendering_engine: jinja
      template_language: cloudformation
```

**Terraform 매니페스트 파일 형식:**

Terraform을 사용하면 단일 파일을 명시적으로 나열하거나 와일드카드 `*`를 사용하여 디렉터리의 각 파일을 나열할 수 있습니다.

**참고**  
와일드카드에는 이름이 `.tf`로 끝나는 파일만 포함됩니다. 다른 파일은 무시됩니다.

```
infrastructure:
  templates:
    - file: "*"
      rendering_engine: hcl
      template_language: terraform
```

**CodeBuild 기반 프로비저닝 매니페스트 파일 형식:**

CodeBuild 기반 프로비저닝을 사용하면 프로비저닝 및 디프로비저닝 쉘 명령을 지정할 수 있습니다.

**참고**  
번들에는 매니페스트 외에도 명령이 의존하는 모든 파일이 포함되어야 합니다.

다음 예제 매니페스트는 CodeBuild 기반 프로비저닝을 사용하여 AWS Cloud Development Kit (AWS CDK) ()를 사용하여 리소스를 프로비저닝(*배포*) 및 프로비저닝 해제(*파기*)합니다AWS CDK. 템플릿 번들에는 CDK 코드도 포함되어야 합니다.

프로비저닝 중에 AWS Proton은 템플릿의 스키마에 `proton-input.json` 이름으로 정의한 입력 파라미터 값이 포함된 입력 파일을 생성합니다.

```
infrastructure:
  templates:
    - rendering_engine: codebuild
      settings:
        image: aws/codebuild/amazonlinux2-x86_64-standard:4.0
        runtimes:
          nodejs: 16
        provision:
          - npm install
          - npm run build
          - npm run cdk bootstrap
          - npm run cdk deploy -- --require-approval never --outputs-file proton-outputs.json
          - jq 'to_entries | map_values(.value) | add | to_entries | map({key:.key, valueString:.value})' < proton-outputs.json > outputs.json
          - aws proton notify-resource-deployment-status-change --resource-arn $RESOURCE_ARN --status IN_PROGRESS --outputs file://./outputs.json
        deprovision:
          - npm install
          - npm run build
          - npm run cdk destroy
        project_properties:
          VpcConfig:
            VpcId: "{{ environment.inputs.codebuild_vpc_id }}"
            Subnets: "{{ environment.inputs.codebuild_subnets }}"
            SecurityGroupIds: "{{ environment.inputs.codebuild_security_groups }}"
```

환경 또는 서비스 템플릿 번들에 대한 디렉터리 및 매니페스트 파일을 설정한 후 디렉터리를 tar 볼에 압축하여가 검색할 AWS Proton 수 있는 Amazon Simple Storage Service(Amazon S3) 버킷 또는 [템플릿 동기화 Git 리포지토리](ag-template-sync-configs.md)에 업로드합니다.

환경의 마이너 버전 또는 등록한 서비스 템플릿을 생성할 때 S3 버킷에 있는 환경 또는 서비스 템플릿 번들 tar 볼의 경로를 AWS Proton제공합니다. 새 템플릿 마이너 버전으로 AWS Proton 저장합니다. 환경 또는 서비스를 생성하거나 업데이트할 새 템플릿 마이너 버전을 선택할 수 있습니다 AWS Proton.

## 환경 템플릿 번들 마무리
<a name="environment-wrap-up"></a>

생성하는 환경 템플릿 번들에는 두 가지 유형이 있습니다 AWS Proton.
+ *표준* 환경 템플릿용 환경 템플릿 번들을 만들려면 다음 환경 템플릿 번들 디렉터리 구조와 같이 스키마, 코드형 인프라(IaC) 파일 및 매니페스트 파일을 디렉터리에 구성하세요.
+ *고객 관리형* 환경 템플릿용 환경 템플릿 번들을 만들려면 스키마 파일과 디렉토리만 제공하세요. 인프라 디렉터리와 파일을 포함하지 *마십시오*. 인프라 디렉터리와 파일이 포함된 경우 오류가 AWS Proton 발생합니다.

자세한 내용은 [템플릿 등록 및 게시](template-create.md) 단원을 참조하십시오.

CloudFormation 환경 템플릿 번들 디렉토리 구조:

```
 /schema
   schema.yaml
 /infrastructure
   manifest.yaml
   cloudformation.yaml
```

Terraform 환경 템플릿 번들 디렉토리 구조:

```
 /schema
   schema.yaml
 /infrastructure
   manifest.yaml
   environment.tf
```

## 서비스 템플릿 번들 마무리
<a name="service-wrap-up"></a>

서비스 템플릿 번들을 생성하려면 서비스 템플릿 번들 디렉터리 구조 예제와 같이 스키마, 코드형 인프라(IaC) 파일 및 매니페스트 파일을 디렉터리로 구성해야 합니다.

템플릿 번들에 서비스 파이프라인을 포함하지 *않는* 경우에는 이 템플릿 번들에 연결할 서비스 템플릿을 만들 때 파이프라인 디렉토리와 파일을 포함하지 *말고* `"pipelineProvisioning": "CUSTOMER_MANAGED"`을 설정합니다.

**참고**  
서비스 그룹을 생성한 후에는 `pipelineProvisioning`을 변경할 수 없습니다.

자세한 내용은 [템플릿 등록 및 게시](template-create.md) 단원을 참조하세요.

CloudFormation 서비스 템플릿 번들 디렉토리 구조:

```
 /schema
   schema.yaml
 /instance_infrastructure
   manifest.yaml
   cloudformation.yaml
 /pipeline_infrastructure
   manifest.yaml
   cloudformation.yaml
```

Terraform 서비스 템플릿 번들 디렉토리 구조:

```
 /schema
   schema.yaml
 /instance_infrastructure
   manifest.yaml
   instance.tf
 /pipeline_infrastructure
   manifest.yaml
   pipeline.tf
```

# 템플릿 번들 고려 사항
<a name="template-considerations"></a>


+ **코드형 인프라(IaC) 파일**

  AWS Proton 는 템플릿에서 올바른 파일 형식을 감사합니다. 그러나 AWS Proton 는 템플릿 개발, 종속성 및 로직 오류를 확인하지 않습니다. 예를 들어 서비스 또는 환경 템플릿의 일부로 CloudFormation IaC 파일에 Amazon S3 버킷 생성을 지정했다고 가정합니다. 서비스는 이러한 템플릿을 기반으로 생성됩니다. 이제 어느 시점에서 서비스를 삭제하고 싶다고 가정해 보겠습니다. 지정된 S3 버킷*이 비어 있지* 않고 CloudFormation IaC 파일이 `Retain`에서 해당 버킷을 로 표시*하지 않으면* 서비스 삭제 작업에 `DeletionPolicy` AWS Proton 실패합니다.
+ **번들 파일 크기 제한 및 형식**
  + 번들 파일 크기, 개수 및 이름 크기 제한은 [AWS Proton 할당량](ag-limits.md)에서 확인할 수 있습니다.
  + 템플릿 번들 파일 디렉토리는 타르 볼에 압축되어 S3(Simple Storage Service) 버킷에 위치합니다.
  + 번들의 각 파일은 유효한 형식의 YAML 파일이어야 합니다.
+ **S3 버킷 템플릿 번들 암호화**

  S3 버킷의 템플릿 번들에 저장된 민감한 데이터를 암호화하려면 SSE-S3 또는 SSE-KMS 키를 사용하여가 이를 AWS Proton 검색할 수 있도록 허용합니다.