

# CloudFormation 모듈을 사용하여 템플릿 전체에 포함할 수 있는 재사용 가능한 리소스 구성 생성
<a name="modules"></a>

*모듈*을 사용하면 모든 스택 템플릿에 포함하기 위한 리소스 구성을 투명하고 관리가 편리하면서도 반복적으로 패키징할 수 있습니다. 모듈은 공통적 서비스 구성과 모범 사례를 모듈식 맞춤형 구성 요소로 캡슐화하고 스택 템플릿에 포함할 수 있습니다. 모듈을 사용하면 리소스 구성을 포함할 수 있습니다. 리소스 구현에 대한 복잡한 지식을 심층적으로 배우지 않더라도 리소스 구성을 통해 모범 사례, 전문가 영역 지식, 허용되는 가이드라인(보안, 규정 준수, 거버넌스, 산업 규정 등의 분야)을 템플릿에 포함할 수 있습니다.

예를 들어 네트워킹 영역 전문가는 기본 보안 그룹과 보안 가이드라인을 준수하는 수신/송신 규칙이 포함된 모듈을 만들 수 있습니다. 그런 다음, 템플릿에 모듈을 포함하여 스택에 보안 네트워킹 인프라를 프로비저닝할 수 있습니다. VPC, 서브넷, 보안 그룹, 게이트웨이의 작동 원리를 배우지 않아도 됩니다. 모듈에 버전이 지정되기 때문에 시간이 지나서 보안 가이드라인이 변경될 경우, 모듈 작성자는 이런 변경 사항을 통합하는 새 버전의 모듈을 만들 수 있습니다.

템플릿에서 모듈을 사용하는 방법의 특징은 다음과 같습니다.
+ **예측 가능성** - 모듈은 CloudFormation 레지스트리에 등록하는 스키마를 준수해야 합니다. 그래야 템플릿에 모듈을 포함한 후 어떤 리소스를 해석할 수 있는지 알 수 있습니다.
+ **재사용 가능성** - 여러 템플릿과 계정에서 동일한 모듈을 사용할 수 있습니다.
+ **추적 가능성** - CloudFormation은 모듈에서 스택의 어떤 리소스가 프로비저닝되었는지 알고 있으므로, 리소스 변경 사항의 소스를 쉽게 이해할 수 있습니다.
+ **관리 용이성** - 모듈에 등록하고 나면 버전 관리, 계정 및 리전 가용성을 포함하여 CloudFormation 레지스트리를 통해 모듈을 관리할 수 있습니다.

모듈에는 다음을 포함할 수 있습니다.
+ 모듈에서 프로비저닝되는 하나 이상의 리소스 및 관련 데이터(예: 출력, 조건).
+ 모듈 파라미터(모듈을 사용할 때마다 사용자 지정 값을 지정할 수 있게 됩니다).

모듈 개발에 대한 자세한 내용은 *CloudFormation CLI User Guide*의 [Developing modules](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/modules.html)를 참조하세요.

**Topics**
+ [모듈 사용 시 고려 사항](#module-considerations)
+ [모듈 버전 관리 이해](module-versioning.md)
+ [CloudFormation 프라이빗 레지스트리의 모듈 사용](modules-using.md)
+ [파라미터를 사용하여 모듈 값 지정](module-using-params.md)
+ [CloudFormation 템플릿의 모듈 리소스 참조](module-ref-resources.md)

## 모듈 사용 시 고려 사항
<a name="module-considerations"></a>
+ 모듈을 사용하더라도 추가 요금은 없습니다. 모듈이 스택에서 해석하는 리소스에 대해서만 요금을 지불합니다.
+ CloudFormation 할당량(스택에 허용되는 리소스의 최대 개수, 템플릿 본문의 최대 크기)을 처리된 템플릿에 적용합니다. 이는 해당 템플릿에 포함된 리소스가 모듈의 리소스인지 여부와는 관계가 없습니다. 자세한 내용은 [CloudFormation 할당량 이해](cloudformation-limits.md) 섹션을 참조하세요.
+ 스택 수준에서 지정하는 태그는 모듈에서 파생된 각 리소스에 할당됩니다.
+ CloudFormation이 템플릿을 처리할 때 모듈 수준에서 지정된 도우미 스크립트는 모듈에 포함된 개별 리소스로 전달되지 않습니다.
+ 모듈에 지정된 출력은 템플릿 수준의 출력에 전달됩니다.

  각 출력에는 모듈의 논리적 이름과 모듈에 정의된 출력 이름을 연결하는 논리적 ID가 할당됩니다. 자세한 내용은 [배포된 CloudFormation 스택에서 내보낸 출력 가져오기](using-cfn-stack-exports.md) 섹션을 참조하세요.
+ 모듈에 지정된 파라미터는 템플릿 수준의 파라미터에 전달되지 않습니다.

  그러나 모듈 수준 파라미터를 참조하는 템플릿 수준 파라미터를 생성할 수 있습니다. 자세한 내용은 [파라미터를 사용하여 모듈 값 지정](module-using-params.md) 섹션을 참조하세요.

# 모듈 버전 관리 이해
<a name="module-versioning"></a>

CloudFormation 레지스트리는 AWS 계정과 리전 내에서 사용할 모듈을 등록하고 관리할 수 있는 리포지토리 역할을 합니다. 계정과 리전 내에서 AWS, 서드 파티 게시자 및 사용자 지정 확장 프로그램을 포함한 다양한 소스의 모듈을 등록할 수 있습니다. 자세한 내용은 [CloudFormation 레지스트리를 통해 익스텐션 관리](registry.md) 섹션을 참조하세요.

모듈에는 여러 버전이 있을 수 있으므로 사용하려는 모듈의 버전을 지정할 수 있습니다. 이 버전 관리 기능은 모듈에 종속된 기존 스택을 손상시키지 않고 모듈을 업데이트하거나 수정해야 할 때 특히 유용합니다.

여러 버전의 모듈을 사용할 때는 다음 고려 사항에 유의하세요.
+ 스택 작업 중 CloudFormation은 현재 스택 작업이 수행되는 AWS 계정과 리전에 기본 버전으로 등록된 모듈 버전을 사용합니다. 여기에는 다른 모듈에 중첩된 모듈이 포함됩니다.

  따라서 다른 계정이나 리전에 동일한 모듈의 다른 버전이 기본 버전으로 등록되어 있는 경우 같은 템플릿을 사용하더라도 결과가 다를 수 있습니다.
+ 스택 작업 중에 CloudFormation은 현재 스택 작업이 수행되는 AWS 계정과 리전에 기본 버전으로 등록된 리소스 버전을 사용합니다. 여기에는 모듈을 포함하여 생성된 리소스가 포함됩니다.
+ 모듈의 기본 버전을 바꾸더라도 스택 업데이트 작업이 시작되지 않습니다. 그러나 다음에 해당 모듈을 포함하는 템플릿으로 스택 작업을 실행할 경우(예: 스택 업데이트) CloudFormation은 작업에 새 기본 버전을 사용합니다.

  한 가지 예외는 **이전 템플릿 사용** 옵션을 지정한 스택 업데이트입니다. 자세한 내용은 아래에 설명되어 있습니다.
+ 스택 업데이트 작업에서 **이전 템플릿 사용** 옵션을 지정할 경우, CloudFormation은 이전에 스택 업데이트에서 처리된 템플릿을 사용하고 변경 사항에 대해 모듈을 다시 처리하지 않습니다.
+ 일관된 결과를 보장하려면 스택 세트와 함께 사용할 스택 템플릿에 모듈을 포함할 경우 스택 인스턴스를 배포하고자 하는 모든 계정과 리전에서 동일한 모듈 버전을 기본 버전으로 설정해야 합니다. 여기에는 다른 모듈에 중첩된 모듈의 버전도 포함됩니다. 자세한 내용은 [StackSets를 사용하여 여러 계정 및 리전의 스택 관리](what-is-cfnstacksets.md) 섹션을 참조하세요.

## 서드 파티 퍼블릭 모듈 활성화를 위한 요구 사항
<a name="requirements-for-modules"></a>

계정 및 리전에서 서드 파티 퍼블릭 모듈을 성공적으로 활성화하려면 모듈에 포함된 각 서드 파티 공개 확장 프로그램(리소스 또는 모듈)에 대해 다음 조건이 충족되어야 합니다.
+ **확장 프로그램 활성화** - 확장 프로그램을 사용하려는 계정과 리전에서 확장 프로그램을 활성화해야 합니다. 자세한 내용은 [CloudFormation 레지스트리에서 서드 파티 공개 확장 프로그램 사용](registry-public.md) 섹션을 참조하세요.
+ **별칭 등록** - 모듈의 확장 프로그램이 유형 이름 별칭을 사용하는 경우 확장 프로그램은 동일한 유형 이름 별칭을 사용하여 계정과 리전에 등록되어야 합니다. 자세한 내용은 [별칭을 사용하여 확장 프로그램 참조](registry-public.md#registry-public-enable-alias) 섹션을 참조하세요.
+ **버전 호환성** - 현재 활성화된 확장 프로그램 버전은 모듈에 지정된 해당 확장 프로그램의 지원되는 메이저 버전 중 하나여야 합니다.

올바른 서드 파티 공개 확장 프로그램 및 확장 프로그램 버전을 활성화하지 않은 경우 CloudFormation은 모듈을 성공적으로 활성화하기 전에 활성화해야 하는 확장 프로그램과 버전을 나열하는 오류와 함께 작업에 실패합니다.

# CloudFormation 프라이빗 레지스트리의 모듈 사용
<a name="modules-using"></a>

이 주제에서는 CloudFormation 템플릿에서 모듈을 사용하는 방법을 설명합니다. 모듈은 템플릿에 추가할 수 있는 미리 만들어진 리소스 번들이라고 생각하면 됩니다.

모듈을 사용하려면 다음 단계를 수행하세요.
+ **모듈 등록** - CloudFormation 레지스트리에 모듈을 비공개 확장 프로그램으로 등록할 수 있습니다. 작업 중인 AWS 계정과 리전에 모듈이 등록되어 있는지 확인하세요. 자세한 내용은 [CloudFormation 레지스트리 개념](registry-concepts.md) 섹션을 참조하세요.
+ **템플릿에 포함** - 다른 리소스와 마찬가지로 CloudFormation 템플릿의 [Resources](resources-section-structure.md) 섹션에 모듈을 추가합니다. 모듈에 필요한 속성도 제공해야 합니다.
+ **스택 생성 또는 업데이트** - 스택 작업을 시작하면 CloudFormation이 처리된 템플릿을 생성합니다. 이 템플릿은 포함된 모듈을 적절한 리소스로 해석합니다.
+ **변경 사항 미리 보기** - 변경하기 전에 변경 세트를 사용하여 추가 또는 변경될 리소스를 확인할 수 있습니다. 자세한 내용은 [변경 세트를 사용하여 CloudFormation 스택 업데이트](using-cfn-updating-stacks-changesets.md) 섹션을 참조하세요.

리소스와 모듈을 모두 포함한 템플릿을 예시로 생각해 보세요. 템플릿에는 개별 리소스(`ResourceA`)와 모듈(`ModuleParent`)이 포함되어 있습니다. 이 모듈에는 `ResourceB` 및 `ResourceC` 리소스는 물론 중첩된 모듈인 `ModuleChild`가 포함되어 있습니다. `ModuleChild`에는 단일 리소스인 `ResourceD`가 포함되어 있습니다. 이 템플릿에서 스택을 생성하면 CloudFormation이 템플릿을 처리하고 모듈을 적절한 리소스로 해석합니다. 결과로 나오는 스택에는 `ResourceA`, `ResourceB`, `ResourceC`, `ResourceD`라는 4개의 리소스가 있습니다.

![\[스택 작업 중에 CloudFormation이 스택 템플릿에 포함된 모듈 2개를 적절한 리소스 4개로 해석합니다.\]](http://docs.aws.amazon.com/ko_kr/AWSCloudFormation/latest/UserGuide/images/modules-resource-inclusion.png)


CloudFormation은 스택의 어떤 리소스가 모듈에서 생성되었는지 추적합니다. [**이벤트**], [**리소스**], [**드리프트**] 탭에서 지정된 스택에 대한 정보를 확인할 수 있으며, 이는 변경 세트 미리 보기에도 포함됩니다.

모듈은 템플릿의 리소스와 구별됩니다. 리소스는 일반적으로 세 부분으로 구성된 규칙을 준수하는 것과 달리, 모듈은 네 부분으로 구서된 이름 지정 규칙을 준수하기 때문입니다.

```
organization::service::use-case::MODULE
```

# 파라미터를 사용하여 모듈 값 지정
<a name="module-using-params"></a>

CloudFormation에서 템플릿 파라미터로 스택 생성 또는 업데이트 중 입력 값을 제공하여 스택을 사용자 지정할 수 있습니다. 이러한 파라미터를 사용하면 필요에 따라 스택의 특정 측면을 변경할 수 있습니다. 템플릿 파라미터 정의에 대한 자세한 내용은 [CloudFormation 템플릿 Parameters 구문](parameters-section-structure.md) 섹션을 참조하세요.

마찬가지로 모듈에도 파라미터가 있을 수 있습니다. 이러한 모듈 파라미터를 사용하면 해당 모듈을 사용하는 템플릿 또는 다른 모듈에서 모듈에 사용자 지정 값을 입력할 수 있습니다. 그런 다음 모듈은 이러한 사용자 지정 값을 사용하여 포함된 리소스의 속성 값을 설정할 수 있습니다.

또한 스택 작업 시 모듈에 전달되는 값을 입력할 수 있도록 모듈 속성을 설정하는 템플릿 파라미터를 정의할 수 있습니다.

모듈에 자체 모듈 파라미터가 있는 중첩 모듈이 있는 경우 다음 중 하나를 수행할 수 있습니다.
+ 중첩 모듈 파라미터에 대한 값을 상위 모듈에 직접 지정합니다.
+ 상위 모듈에서 해당 모듈 파라미터를 정의합니다. 상위 모듈이 포함된 템플릿(또는 모듈)에서 중첩 모듈 파라미터를 설정할 수 있습니다.

## 템플릿 파라미터를 사용하여 모듈 파라미터 값 지정
<a name="module-using-params-example-1"></a>

다음 예제는 값을 모듈에 전달하는 템플릿 파라미터를 정의하는 방법을 나타냅니다.

`My::S3::SampleBucket::MODULE`을 포함하는 이 템플릿은 사용자가 스택 작업 중 S3 버킷 이름을 지정할 수 있는 템플릿 파라미터인 `BucketName`을 정의합니다.

```
# Template containing My::S3::SampleBucket::MODULE
Parameters:
  BucketName:
    Description: Name for your sample bucket
    Type: String
Resources:
  MyBucket:
    Type: 'My::S3::SampleBucket::MODULE'
    Properties:
      BucketName: !Ref BucketName
```

## 상위 모듈에서 하위 모듈의 리소스에 대한 속성 지정
<a name="module-using-params-example-2"></a>

다음 예제는 다른 모듈 안에 중첩된 모듈에서 파라미터 값을 지정하는 방법을 나타냅니다.

이 첫 번째 모듈 `My::S3::SampleBucketPrivate::MODULE`이 하위 모듈이 됩니다. 이 하위 모듈이 파라미터 2개(`BucketName`과 `AccessControl`)를 정의합니다. 두 가지 파라미터에 지정된 값을 사용하여 모듈에 포함된 `AWS::S3::Bucket` 리소스의 `BucketName`과 `AccessControl`을 지정합니다. 다음의 `My::S3::SampleBucketPrivate::MODULE`에 대한 템플릿 프래그먼트입니다.

```
# My::S3::SampleBucketPrivate::MODULE
AWSTemplateFormatVersion: 2010-09-09
Description: A sample S3 Bucket with Versioning and DeletionPolicy.
Parameters:
  BucketName:
    Description: Name for the bucket
    Type: String
  AccessControl:
    Description: AccessControl for the bucket
    Type: String
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Ref BucketName
      AccessControl: !Ref AccessControl
      DeletionPolicy: Retain
      VersioningConfiguration:
        Status: Enabled
```

그 다음에는 이전 모듈이 상위 모듈 `My::S3::SampleBucket::MODULE`에 중첩됩니다. 상위 모듈 `My::S3::SampleBucket::MODULE`은 다음과 같은 방법으로 하위 모듈 파라미터를 설정합니다.
+ `My::S3::SampleBucketPrivate::MODULE`의 `AccessControl` 파라미터를 `Private`으로 설정합니다.
+ `BucketName`은 모듈 파라미터를 정의합니다. `My::S3::SampleBucket::MODULE`을 포함하는 템플릿(또는 모듈)에서 버킷 이름을 지정할 수 있게 됩니다.

```
# My::S3::SampleBucket::MODULE
AWSTemplateFormatVersion: 2010-09-09
Description: A sample S3 Bucket. With Private AccessControl.
Parameters:
  BucketName:
    Description: Name for your sample bucket
    Type: String
Resources:
  MyBucket:
    Type: 'My::S3::SampleBucketPrivate::MODULE'
    Properties:
      BucketName: !Ref BucketName
      AccessControl: Private
```

## 모듈 파라미터에 대한 제약 조건 지정
<a name="modules-using-parameters-constraints"></a>

모듈 파라미터는 제약 조건의 적용을 지원하지 않습니다. 모듈 파라미터에 대해 제약 조건 검사를 실행하려면 원하는 제약 조건으로 템플릿 파라미터를 생성합니다. 그런 다음 모듈 파라미터에서 템플릿 파라미터를 참조합니다. 템플릿 파라미터 정의에 대한 자세한 내용은 [CloudFormation 템플릿 Parameters 구문](parameters-section-structure.md) 섹션을 참조하세요.

# CloudFormation 템플릿의 모듈 리소스 참조
<a name="module-ref-resources"></a>

CloudFormation에서 다른 리소스의 이름이나 속성을 기반으로 한 리소스의 속성을 설정해야 하는 경우가 있습니다. 자세한 내용은 [참조 리소스](resources-section-structure.md#using-cross-resource-references) 섹션을 참조하세요.

CloudFormation 템플릿의 모듈에 포함된 리소스를 참조하려면 두 논리명을 결합해야 합니다.
+ 템플릿에 모듈을 포함할 때 모듈 자체에 지정한 논리명입니다.
+ 해당 모듈 내 특정 리소스의 논리명입니다.

이 두 논리명을 마침표(.)를 사용하거나 사용하지 않고 결합할 수 있습니다. 예를 들어, 모듈의 논리명이 `MyModule`이고 리소스의 논리명이 `MyBucket`인 경우 해당 리소스를 `MyModule.MyBucket` 또는 `MyModuleMyBucket`으로 참조할 수 있습니다.

모듈 내부 리소스의 논리명을 찾으려면 CloudFormation 레지스트리에서 사용할 수 있는 모듈 스키마를 참조하거나 [https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeType.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeType.html) 작업을 사용합니다. 스키마에는 모듈의 일부인 모든 리소스와 해당 논리명이 나열됩니다.

전체 논리명을 알면 `GetAtt` 및 `Ref`와 같은 CloudFormation 함수를 사용하여 모듈 리소스의 속성 값에 액세스할 수 있습니다.

예를 들어, 논리명이 `S3Bucket`인 `AWS::S3::Bucket` 리소스를 포함하는 `My::S3::SampleBucket::MODULE` 모듈이 있다고 가정해 보겠습니다. `Ref` 함수를 사용하여 이 버킷의 이름을 참조하려면 템플릿의 모듈 이름(`MyBucket`)과 모듈의 리소스 논리명(`S3Bucket`)을 결합합니다. 전체 논리명은 `MyBucket.S3Bucket` 또는 `MyBucketS3Bucket`입니다.

**예제 템플릿**  
다음 예 템플릿은 `My::S3::SampleBucket::MODULE` 모듈을 사용하여 S3 버킷을 생성합니다. 또한 Amazon SQS 대기열을 생성하고 해당 이름을 모듈의 버킷 이름과 동일하게 설정합니다. 생성된 S3 버킷의 Amazon 리소스 이름(ARN)도 출력합니다.

```
# Template that uses My::S3::SampleBucket::MODULE
Parameters:
  BucketName:
    Description: Name for your sample bucket
    Type: String
Resources:
  MyBucket:
    Type: My::S3::SampleBucket::MODULE
    Properties:
      BucketName: !Ref BucketName
  exampleQueue:
    Type: AWS::SQS::Queue
    Properties:
      QueueName: !Ref MyBucket.S3Bucket
Outputs:
  BucketArn:
    Value: !GetAtt MyBucket.S3Bucket.Arn
```