

Amazon CodeCatalyst는 더 이상 신규 고객에게 공개되지 않습니다. 기존 고객은 정상적으로 서비스를 계속 이용할 수 있습니다. 자세한 내용은 [CodeCatalyst에서 마이그레이션하는 방법](migration.md) 단원을 참조하십시오.

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

# 자습서: 서버리스 애플리케이션 배포
<a name="deploy-tut-lambda"></a>

이 자습서에서는 워크플로를 사용하여 CloudFormation 스택으로 서버리스 애플리케이션을 빌드, 테스트 및 배포하는 방법을 알아봅니다.

이 자습서의 애플리케이션은 'Hello World' 메시지를 출력하는 간단한 웹 애플리케이션입니다. AWS Lambda 함수와 Amazon API Gateway로 구성되며의 확장인 [AWS Serverless Application Model (AWS SAM)](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html)를 사용하여 빌드합니다[CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html).

**Topics**
+ [사전 조건](#deploy-tut-lambda-cfn-prereqs)
+ [1단계: 소스 리포지토리 생성](#deploy-tut-lambda-cfn-source)
+ [2단계: AWS 역할 생성](#deploy-tut-lambda-cfn-roles)
+ [3단계: CodeCatalyst에 AWS 역할 추가](#deploy-tut-lambda-cfn-roles-add)
+ [4단계: Amazon S3 버킷 생성](#deploy-tut-lambda-cfn-s3)
+ [5단계: 소스 파일 추가](#deploy-tut-lambda-cfn-files)
+ [6단계: 워크플로 생성 및 실행](#deploy-tut-lambda-cfn-workflow)
+ [7단계: 변경](#deploy-tut-lambda-cfn-change)
+ [정리](#deploy-tut-lambda-cfn-clean-up)

## 사전 조건
<a name="deploy-tut-lambda-cfn-prereqs"></a>

시작하기 전:
+ 연결된 AWS 계정이 있는 CodeCatalyst **스페이스**가 필요합니다. 자세한 내용은 [스페이스 생성](spaces-create.md) 단원을 참조하십시오.
+ 스페이스에는 다음과 같은 빈 프로젝트가 필요합니다.

  ```
  codecatalyst-cfn-project
  ```

  **처음부터 시작** 옵션을 사용하여 이 프로젝트를 생성합니다.

  자세한 내용은 [Amazon CodeCatalyst에서 빈 프로젝트 생성](projects-create.md#projects-create-empty) 섹션을 참조하세요.
+ 프로젝트에는 다음과 같은 CodeCatalyst **환경**이 필요합니다.

  ```
  codecatalyst-cfn-environment
  ```

  다음과 같이 이 환경을 구성합니다.
  + **비프로덕션**과 같은 유형을 선택합니다.
  +  AWS 계정에 연결합니다.
  + **기본 IAM 역할**의 경우 아무 역할이나 선택합니다. 나중에 다른 역할을 지정합니다.

  자세한 내용은 [AWS 계정 및 VPCs에 배포](deploy-environments.md) 섹션을 참조하세요.

## 1단계: 소스 리포지토리 생성
<a name="deploy-tut-lambda-cfn-source"></a>

이 단계에서는 CodeCatalyst에 소스 리포지토리를 생성합니다. 이 리포지토리는 Lambda 함수 파일과 같은 자습서의 소스 파일을 저장하는 데 사용됩니다.

소스 리포지토리에 대한 자세한 정보는 [소스 리포지토리 생성](source-repositories-create.md) 섹션을 참조하세요.

**소스 리포지토리를 생성하려면**

1. CodeCatalyst의 탐색 창에서 **코드**를 선택한 다음 **소스 리포지토리**를 선택합니다.

1. **리포지토리 추가**를 선택하고 **리포지토리 생성**을 선택합니다.

1. **리포지토리 이름**에 다음과 같이 입력합니다.

   ```
   codecatalyst-cfn-source-repository
   ```

1. **생성(Create)**을 선택합니다.

이제 `codecatalyst-cfn-source-repository` 리포지토리를 생성했습니다.

## 2단계: AWS 역할 생성
<a name="deploy-tut-lambda-cfn-roles"></a>

이 단계에서는 다음 AWS IAM 역할을 생성합니다.
+ **역할 배포** - CodeCatalyst ** CloudFormation 스택 배포** 작업에 서버리스 애플리케이션을 배포할 AWS 계정 및 CloudFormation 서비스에 액세스할 수 있는 권한을 부여합니다. ** CloudFormation 스택 배포** 작업은 워크플로의 일부입니다.
+ **빌드 역할** - CodeCatalyst 빌드 작업에 AWS 계정에 액세스하고 서버리스 애플리케이션 패키지가 저장될 Amazon S3에 쓸 수 있는 권한을 부여합니다. 빌드 작업은 워크플로의 일부입니다.
+ **스택 역할** - 나중에 제공할 AWS SAM 템플릿에 지정된 리소스를 읽고 수정할 수 있는 CloudFormation 권한을 부여합니다. 또한 CloudWatch에 권한을 부여합니다.

IAM 역할에 대한 자세한 내용은 *AWS Identity and Access Management 사용 설명서*의 [IAM 역할](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) 섹션을 참조하세요.

**참고**  
시간을 절약하기 위해 이전에 나열한 세 가지 역할 대신 `CodeCatalystWorkflowDevelopmentRole-spaceName` 역할이라는 단일 역할을 생성할 수 있습니다. 자세한 내용은 [계정 및 스페이스의 **CodeCatalystWorkflowDevelopmentRole-*spaceName*** 역할 생성](ipa-iam-roles.md#ipa-iam-roles-service-create) 섹션을 참조하세요. `CodeCatalystWorkflowDevelopmentRole-spaceName` 역할에는 보안 위험을 초래할 수 있는 매우 광범위한 권한이 있음을 이해합니다. 보안에 대한 우려가 적은 자습서 및 시나리오에서만 이 역할을 사용하는 것이 좋습니다. 이 자습서에서는 이전에 나열된 세 가지 역할을 생성하고 있다고 가정합니다.

**참고**  
[Lambda 실행 역할](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)도 필요하지만 5단계에서 워크플로를 실행할 때 `sam-template.yml` 파일이 생성하므로 지금 생성할 필요가 없습니다.



**배포 역할을 생성하려면**

1. 역할에 대한 정책을 다음과 같이 생성합니다.

   1. 에 로그인합니다 AWS.

   1. [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)에서 IAM 콘솔을 엽니다.

   1. 탐색 창에서 **Policies**를 선택합니다.

   1. **정책 생성**을 선택합니다.

   1. **JSON** 탭을 선택합니다.

   1. 기존 코드를 삭제합니다.

   1. 다음 코드를 붙여넣습니다.
**참고**  
역할을 처음 사용하여 워크플로 작업을 실행할 때 리소스 정책 문에서 와일드카드를 사용한 다음, 사용 가능한 리소스 이름으로 정책 범위를 좁힙니다.  

      ```
      "Resource": "*"
      ```

   1. **다음: 태그**를 선택합니다.

   1. **다음: 검토**를 선택합니다.

   1. **이름**에 다음과 같이 입력합니다.

      ```
      codecatalyst-deploy-policy
      ```

   1. **정책 생성**을 선택합니다.

      이제 권한 정책을 생성했습니다.

1. 다음과 같이 배포 역할을 생성합니다.

   1. 탐색 창에서 **역할**을 선택한 후 **역할 생성**을 선택합니다.

   1. **사용자 지정 신뢰 정책**을 선택합니다.

   1. 기존 사용자 지정 신뢰 정책을 삭제합니다.

   1. 다음 사용자 지정 신뢰 정책을 추가합니다.

   1. **다음**을 선택합니다.

   1. **권한 정책**에서 `codecatalyst-deploy-policy`를 검색하고 해당 확인란을 선택합니다.

   1. **다음**을 선택합니다.

   1. **역할 이름**에 다음과 같이 입력합니다.

      ```
      codecatalyst-deploy-role
      ```

   1. **역할 설명**에 다음과 같이 입력합니다.

      ```
      CodeCatalyst deploy role
      ```

   1. **역할 생성**을 선택합니다.

   이제 신뢰 정책 및 권한 정책으로 배포 역할을 생성했습니다.

1. 다음과 같이 배포 역할 ARN을 가져옵니다.

   1. 탐색 창에서 **Roles**를 선택합니다.

   1. 검색 상자에 방금 생성한 역할의 이름을 입력합니다(`codecatalyst-deploy-role`).

   1. 목록에서 역할을 선택합니다.

      역할의 **요약** 페이지가 나타납니다.

   1. 상단에서 **ARN** 값을 복사합니다.

   이제 적절한 권한으로 배포 역할을 생성하고 ARN을 획득했습니다.

**빌드 역할을 생성하려면**

1. 역할에 대한 정책을 다음과 같이 생성합니다.

   1. 에 로그인합니다 AWS.

   1. [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)에서 IAM 콘솔을 엽니다.

   1. 탐색 창에서 **Policies**를 선택합니다.

   1. **정책 생성**을 선택합니다.

   1. **JSON** 탭을 선택합니다.

   1. 기존 코드를 삭제합니다.

   1. 다음 코드를 붙여넣습니다.
**참고**  
역할을 처음 사용하여 워크플로 작업을 실행할 때 리소스 정책 문에서 와일드카드를 사용한 다음, 사용 가능한 리소스 이름으로 정책 범위를 좁힙니다.  

      ```
      "Resource": "*"
      ```

   1. **다음: 태그**를 선택합니다.

   1. **다음: 검토**를 선택합니다.

   1. **이름**에 다음과 같이 입력합니다.

      ```
      codecatalyst-build-policy
      ```

   1. **정책 생성**을 선택합니다.

      이제 권한 정책을 생성했습니다.

1. 다음과 같이 빌드 역할을 생성합니다.

   1. 탐색 창에서 **역할**을 선택한 후 **역할 생성**을 선택합니다.

   1. **사용자 지정 신뢰 정책**을 선택합니다.

   1. 기존 사용자 지정 신뢰 정책을 삭제합니다.

   1. 다음 사용자 지정 신뢰 정책을 추가합니다.

   1. **다음**을 선택합니다.

   1. **권한 정책**에서 `codecatalyst-build-policy`를 검색하고 해당 확인란을 선택합니다.

   1. **다음**을 선택합니다.

   1. **역할 이름**에 다음과 같이 입력합니다.

      ```
      codecatalyst-build-role
      ```

   1. **역할 설명**에 다음과 같이 입력합니다.

      ```
      CodeCatalyst build role
      ```

   1. **역할 생성**을 선택합니다.

   이제 신뢰 정책 및 권한 정책으로 빌드 역할을 생성했습니다.

1. 다음과 같이 빌드 역할 ARN을 가져옵니다.

   1. 탐색 창에서 **Roles**를 선택합니다.

   1. 검색 상자에 방금 생성한 역할의 이름을 입력합니다(`codecatalyst-build-role`).

   1. 목록에서 역할을 선택합니다.

      역할의 **요약** 페이지가 나타납니다.

   1. 상단에서 **ARN** 값을 복사합니다.

   이제 적절한 권한으로 빌드 역할을 생성하고 ARN을 획득했습니다.<a name="deploy-tut-lambda-cfn-roles-stack"></a>

**스택 역할을 생성하려면**

1. 스택을 배포하려는 계정을 AWS 사용하여에 로그인합니다.

1. IAM 콘솔([https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/))을 엽니다.

1. 다음과 같이 스택 역할을 생성합니다.

   1. 탐색 창에서 **Roles**를 선택합니다.

   1. **역할 생성(Create role)**을 선택합니다.

   1. **AWS 서비스**를 선택합니다.

   1. **사용 사례** 섹션의 드롭다운 목록에서 **CloudFormation**을 선택합니다.

   1. **CloudFormation** 라디오 버튼을 선택합니다.

   1. 하단에서 **다음**을 선택합니다.

   1. 검색 상자를 사용하여 다음 권한 정책을 찾은 다음 해당 확인란을 선택합니다.
**참고**  
정책을 검색했지만 표시되지 않는 경우 **필터 지우기**를 선택하고 다시 시도해야 합니다.
      + **CloudWatchFullAccess**
      + **AWS CloudFormationFullAccess**
      + **IAMFullAccess**
      + **AWS Lambda\$1FullAccess**
      + **AmazonAPIGatewayAdministrator**
      + **AmazonS3FullAccess**
      + **AmazonEC2ContainerRegistryFullAccess**

      첫 번째 정책은 경보가 발생할 때 스택 롤백을 활성화하기 위해 CloudWatch에 대한 액세스를 허용합니다.

      나머지 정책은가이 자습서에서 배포할 스택의 서비스 및 리소스에 AWS SAM 액세스할 수 있도록 허용합니다. 자세한 내용은 *AWS Serverless Application Model 개발자 안내서*의 [권한](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-permissions.html) 섹션을 참조하세요.

   1. **다음**을 선택합니다.

   1. **역할 이름**에 다음과 같이 입력합니다.

      ```
      codecatalyst-stack-role
      ```

   1. **역할 생성**을 선택합니다.

1. 다음과 같이 스택 역할 ARN을 가져옵니다.

   1. 탐색 창에서 **Roles**를 선택합니다.

   1. 검색 상자에 방금 생성한 역할의 이름을 입력합니다(`codecatalyst-stack-role`).

   1. 목록에서 역할을 선택합니다.

   1. **요약** 섹션에 표시된 **ARN** 값을 복사합니다. 나중에 필요합니다.

   이제 적절한 권한으로 스택 역할을 생성했으며 ARN을 획득했습니다.

## 3단계: CodeCatalyst에 AWS 역할 추가
<a name="deploy-tut-lambda-cfn-roles-add"></a>

이 단계에서는 빌드 역할(`codecatalyst-build-role`)을 추가하고 스페이스의 CodeCatalyst 계정 연결에 역할(`codecatalyst-deploy-role`)을 배포합니다.

**참고**  
스택 역할(`codecatalyst-stack-role`)을 연결에 추가할 필요가 없습니다. 이는 배포 역할을 사용하여 CodeCatalyst와 AWS 간에 연결이 이미 설정된 *후* *CloudFormation*(CodeCatalyst 아님)에서 스택 역할을 사용하기 때문입니다. 스택 역할은 CodeCatalyst에서 AWS에 대한 액세스 권한을 얻는 데 사용되지 않으므로 계정 연결과 연결할 필요가 없습니다.

**계정 연결에 빌드 및 배포 역할을 추가하려면**

1. CodeCatalyst에서 스페이스로 이동합니다.

1. **AWS 계정**을 선택합니다. 계정 연결 목록이 나타납니다.

1. 빌드 및 배포 역할을 생성한 계정을 나타내는 AWS 계정 연결을 선택합니다.

1. **관리 콘솔에서 역할 AWS 관리를** 선택합니다.

   **Amazon CodeCatalyst 스페이스에 IAM 역할 추가** 페이지가 나타납니다. 페이지에 액세스하려면 로그인해야 할 수 있습니다.

1. **IAM에서 생성한 기존 역할 추가**를 선택합니다.

   드롭다운 목록이 나타납니다. 목록에는 `codecatalyst-runner.amazonaws.com` 및 `codecatalyst.amazonaws.com` 서비스 위탁자가 포함된 신뢰 정책이 있는 모든 IAM 역할이 표시됩니다.

1. 드롭다운 목록에서 `codecatalyst-build-role`을 선택하고 **역할 추가**를 선택합니다.

1. **IAM 역할 추가**를 선택하고 **IAM에서 생성한 기존 역할 추가**를 선택한 다음 드롭다운 목록에서 `codecatalyst-deploy-role`을 선택합니다. [**Add role**]을 선택합니다.

   이제 스페이스에 빌드 및 배포 역할을 추가했습니다.

1. **Amazon CodeCatalyst 표시 이름**의 값을 복사합니다. 워크플로를 생성할 때 나중에 이 값이 필요합니다.

## 4단계: Amazon S3 버킷 생성
<a name="deploy-tut-lambda-cfn-s3"></a>

이 단계에서는 서버리스 애플리케이션의 배포 패키지 .zip 파일을 저장하는 Amazon S3 버킷을 생성합니다.

**Amazon S3 버킷을 생성하려면**

1. [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)에서 S3 콘솔을 엽니다.

1. 기본 창에서 **버킷 생성**을 선택합니다.

1. **버킷 이름**에 다음과 같이 입력합니다.

   ```
   codecatalyst-cfn-s3-bucket
   ```

1. **AWS 리전**에서 리전을 선택합니다. 이 자습서에서는 **미국 서부(오리건) us-west-2**를 선택했다고 가정합니다. Amazon S3에서 지원되는 리전에 대한 자세한 내용은 *AWS 일반 참조*의 [Amazon Simple Storage Service 엔드포인트 및 할당량](https://docs.aws.amazon.com/general/latest/gr/s3.html)을 참조하세요.

1. 페이지 맨 아래에 있는 **버킷 생성** 버튼을 선택합니다.

이제 미국 서부(오리건) us-west-2 리전에 **codecatalyst-cfn-s3-bucket** 버킷을 생성했습니다.

## 5단계: 소스 파일 추가
<a name="deploy-tut-lambda-cfn-files"></a>

이 단계에서는 CodeCatalyst 소스 리포지토리에 여러 애플리케이션 소스 파일을 추가합니다. `hello-world` 폴더에는 배포할 애플리케이션 파일이 포함되어 있습니다. `tests` 폴더에는 단위 테스트가 포함되어 있습니다. 폴더의 구조는 다음과 같습니다.

```
.
|— hello-world
|  |— tests
|     |— unit
|        |— test-handler.js
|  |— app.js
|— .npmignore
|— package.json
|— sam-template.yml
|— setup-sam.sh
```

### .npmignore 파일
<a name="deploy-tut-lambda-cfn-files-npmignore"></a>

`.npmignore` 파일은 npm이 애플리케이션 패키지에서 제외해야 하는 파일 및 폴더를 나타냅니다. 이 자습서에서는 npm이 애플리케이션의 일부가 아니기 때문에 `tests` 폴더를 제외합니다.

**.npmignore 파일을 추가하려면**

1. [https://codecatalyst.aws/](https://codecatalyst.aws/)에서 CodeCatalyst 콘솔을 엽니다.

1. `codecatalyst-cfn-project` 프로젝트를 선택합니다.

1. 탐색 창에서 **코드**를 선택한 다음 **소스 리포지토리**를 선택합니다.

1. 소스 리포지토리 목록에서 `codecatalyst-cfn-source-repository` 리포지토리를 선택합니다.

1. **파일**에서 **파일 생성**을 선택합니다.

1. **파일 이름**에 다음과 같이 입력합니다.

   ```
   .npmignore
   ```

1. 다음 코드를 텍스트 상자에 입력합니다.

   ```
   tests/*
   ```

1. **커밋**을 선택한 다음 **커밋**을 다시 선택합니다.

   이제 리포지토리 루트에서 `.npmignore` 파일을 생성했습니다.

### package.json 파일
<a name="deploy-tut-lambda-cfn-files-package-json"></a>

`package.json` 파일에는 프로젝트 이름, 버전 번호, 설명, 종속성 및 애플리케이션과 상호 작용하고 실행하는 방법을 설명하는 기타 세부 정보와 같은 노드 프로젝트에 대한 중요한 메타데이터가 포함되어 있습니다.

`package.json` 이 자습서의 `test` 에는 종속성 목록과 스크립트가 포함되어 있습니다. 테스트 스크립트는 다음 작업을 수행합니다.
+ [mocha](https://mochajs.org/)를 사용하여 테스트 스크립트는 `hello-world/tests/unit/`에 지정된 단위 테스트를 실행하고 [xunit]() 리포터를 사용하여 `junit.xml` 파일에 결과를 기록합니다.
+ [이스탄불(nyc)](https://istanbul.js.org/)을 사용하면 테스트 스크립트가 [클로버](https://openclover.org/doc/manual/4.2.0/general--about-openclover.html) 리포터를 사용하여 코드 적용 범위 보고서(`clover.xml`)를 생성합니다. 자세한 내용은 이스탄불 설명서의 [대체 리포터 사용을](https://istanbul.js.org/docs/advanced/alternative-reporters/#clover) 참조하세요.

**package.json 파일을 추가하려면**

1. 리포지토리의 **파일**에서 **파일 생성**을 선택합니다.

1. **파일 이름**에 다음과 같이 입력합니다.

   ```
   package.json
   ```

1. 다음 코드를 텍스트 상자에 입력합니다.

   ```
   {
     "name": "hello_world",
     "version": "1.0.0",
     "description": "hello world sample for NodeJS",
     "main": "app.js",
     "repository": "https://github.com/awslabs/aws-sam-cli/tree/develop/samcli/local/init/templates/cookiecutter-aws-sam-hello-nodejs",
     "author": "SAM CLI",
     "license": "MIT",
     "dependencies": {
       "axios": "^0.21.1",
       "nyc": "^15.1.0"
     },
     "scripts": {
       "test": "nyc --reporter=clover mocha hello-world/tests/unit/ --reporter xunit --reporter-option output=junit.xml"
     },
     "devDependencies": {
       "aws-sdk": "^2.815.0",
       "chai": "^4.2.0",
       "mocha": "^8.2.1"
     }
   }
   ```

1. **커밋**을 선택한 다음 **커밋**을 다시 선택합니다.

   이제 리포지토리 루트에서 `package.json` 파일을 생성했습니다.

### sam-template.yml 파일
<a name="deploy-tut-lambda-cfn-files-sam-template-yml"></a>

`sam-template.yml` 파일에는 Lambda 함수 및 API Gateway를 배포하고 함께 구성하는 지침이 포함되어 있습니다. [AWS Serverless Application Model 템플릿 사양을](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification.html) 따르는 템플릿 CloudFormation 사양을 따릅니다.

는 유용한 [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html) 리소스 유형을 AWS SAM 제공하기 때문에이 자습서 AWS SAM 에서는 일반 템플릿 대신 CloudFormation 템플릿을 사용합니다. 이 유형은 기본 CloudFormation 구문을 사용하기 위해 일반적으로 작성해야 하는 보이지 않는 구성을 다수 수행합니다. 예를 들어 `AWS::Serverless::Function`은 Lambda 함수, Lambda 실행 역할 및 함수를 시작하는 이벤트 소스 매핑을 생성합니다. 기본 CloudFormation 을 사용하여 작성하려면 이 모든 것을 코딩해야 합니다.

이 자습서에서는 미리 작성된 템플릿을 사용하지만 빌드 작업을 사용하여 워크플로의 일부로 템플릿을 생성할 수 있습니다. 자세한 내용은 [CloudFormation 스택 배포](deploy-action-cfn.md) 섹션을 참조하세요.

**sam-template.yml 파일을 추가하려면**

1. 리포지토리의 **파일**에서 **파일 생성**을 선택합니다.

1. **파일 이름**에 다음과 같이 입력합니다.

   ```
   sam-template.yml
   ```

1. 다음 코드를 텍스트 상자에 입력합니다.

   ```
   AWSTemplateFormatVersion: '2010-09-09'
   Transform: AWS::Serverless-2016-10-31
   Description: >
     serverless-api
   
     Sample SAM Template for serverless-api
     
   # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
   Globals:
     Function:
       Timeout: 3
   
   Resources:
     HelloWorldFunction:
       Type: AWS::Serverless::Function # For details on this resource type, see https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
       Properties:
         CodeUri: hello-world/
         Handler: app.lambdaHandler
         Runtime: nodejs12.x
         Events:
           HelloWorld:
             Type: Api # For details on this event source type, see https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
             Properties:
               Path: /hello
               Method: get
   
   Outputs:
     # ServerlessRestApi is an implicit API created out of the events key under Serverless::Function
     # Find out about other implicit resources you can reference within AWS SAM at
     # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
     HelloWorldApi:
       Description: "API Gateway endpoint URL for the Hello World function"
       Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
     HelloWorldFunction:
       Description: "Hello World Lambda function ARN"
       Value: !GetAtt HelloWorldFunction.Arn
     HelloWorldFunctionIamRole:
       Description: "Implicit Lambda execution role created for the Hello World function"
       Value: !GetAtt HelloWorldFunctionRole.Arn
   ```

1. **커밋**을 선택한 다음 **커밋**을 다시 선택합니다.

   이제 리포지토리의 루트 폴더 아래에 `sam-template.yml` 파일을 추가했습니다.

### setup-sam.sh 파일
<a name="deploy-tut-lambda-cfn-files-setup-sam"></a>

`setup-sam.sh` 파일에는 AWS SAM CLI 유틸리티 다운로드 및 설치 지침이 포함되어 있습니다. 워크플로는 이 유틸리티를 사용하여 `hello-world` 소스를 패키징합니다.

**setup-sam.sh 파일을 추가하려면**

1. 리포지토리의 **파일**에서 **파일 생성**을 선택합니다.

1. **파일 이름**에 다음과 같이 입력합니다.

   ```
   setup-sam.sh
   ```

1. 다음 코드를 텍스트 상자에 입력합니다.

   ```
   #!/usr/bin/env bash
   echo "Setting up sam"
   
   yum install unzip -y
   
   curl -LO https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip
   unzip -qq aws-sam-cli-linux-x86_64.zip -d sam-installation-directory
   
   ./sam-installation-directory/install; export AWS_DEFAULT_REGION=us-west-2
   ```

   앞의 코드에서 *us-west-2*를 AWS 리전으로 바꿉니다.

1. **커밋**을 선택한 다음 **커밋**을 다시 선택합니다.

   이제 리포지토리 루트에서 `setup-sam.sh` 파일을 생성했습니다.

### app.js 파일
<a name="deploy-tut-lambda-cfn-files-app-js"></a>

`app.js`는 Lambda 함수 코드를 포함합니다. 이 자습서에서는 코드가 `hello world` 텍스트를 반환합니다.

**app.js 파일을 추가하려면**

1. 리포지토리의 **파일**에서 **파일 생성**을 선택합니다.

1. **파일 이름**에 다음과 같이 입력합니다.

   ```
   hello-world/app.js
   ```

1. 다음 코드를 텍스트 상자에 입력합니다.

   ```
   // const axios = require('axios')
   // const url = 'http://checkip.amazonaws.com/';
   let response;
   
   /**
    *
    * Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
    * @param {Object} event - API Gateway Lambda Proxy Input Format
    *
    * Context doc: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html 
    * @param {Object} context
    *
    * Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
    * @returns {Object} object - API Gateway Lambda Proxy Output Format
    * 
    */
   exports.lambdaHandler = async (event, context) => {
       try {
           // const ret = await axios(url);
           response = {
               'statusCode': 200,
               'body': JSON.stringify({
                   message: 'hello world',
                   // location: ret.data.trim()
               })
           }
       } catch (err) {
           console.log(err);
           return err;
       }
   
       return response
   };
   ```

1. **커밋**을 선택한 다음 **커밋**을 다시 선택합니다.

   이제 `hello-world` 폴더와 `app.js` 파일을 생성했습니다.

### test-handler.js 파일
<a name="deploy-tut-lambda-cfn-files-test-handler-js"></a>

`test-handler.js` 파일에는 Lambda 함수에 대한 단위 테스트가 포함되어 있습니다.

**test-handler.js 파일을 추가하려면**

1. 리포지토리의 **파일**에서 **파일 생성**을 선택합니다.

1. **파일 이름**에 다음과 같이 입력합니다.

   ```
   hello-world/tests/unit/test-handler.js
   ```

1. 다음 코드를 텍스트 상자에 입력합니다.

   ```
   'use strict';
   
   const app = require('../../app.js');
   const chai = require('chai');
   const expect = chai.expect;
   var event, context;
   
   describe('Tests index', function () {
       it('verifies successful response', async () => {
           const result = await app.lambdaHandler(event, context)
   
           expect(result).to.be.an('object');
           expect(result.statusCode).to.equal(200);
           expect(result.body).to.be.an('string');
   
           let response = JSON.parse(result.body);
   
           expect(response).to.be.an('object');
           expect(response.message).to.be.equal("hello world");
           // expect(response.location).to.be.an("string");
       });
   });
   ```

1. **커밋**을 선택한 다음 **커밋**을 다시 선택합니다.

   이제 `hello-world/tests/unit` 폴더 아래에 `test-handler.js` 파일을 추가했습니다.

이제 모든 소스 파일을 추가했습니다.

잠시 시간을 내어 작업을 다시 확인하고 모든 파일을 올바른 폴더에 넣었는지 확인하세요. 폴더의 구조는 다음과 같습니다.

```
.
|— hello-world
|  |— tests
|     |— unit
|        |— test-handler.js
|  |— app.js
|— .npmignore
|— README.md
|— package.json
|— sam-template.yml
|— setup-sam.sh
```

## 6단계: 워크플로 생성 및 실행
<a name="deploy-tut-lambda-cfn-workflow"></a>

이 단계에서는 Lambda 소스 코드를 패키징하고 배포하는 워크플로를 생성합니다. 워크플로는 순차적으로 실행되는 다음 구성 요소로 구성됩니다.
+ 트리거 - 이 트리거는 소스 리포지토리에 변경 사항을 푸시할 때 워크플로 실행을 자동으로 시작합니다. 트리거에 대한 자세한 내용은 [트리거를 사용하여 워크플로 실행 자동 시작](workflows-add-trigger.md) 주제를 참조하세요.
+ 테스트 작업(`Test`) - 트리거 시 이 작업은 [노드 패키지 관리자(npm)](https://www.npmjs.com/)를 설치한 다음 `npm run test` 명령을 실행합니다. 이 명령은 `package.json` 파일에 정의된 `test` 스크립트를 실행하도록 npm에 지시합니다. `test` 스크립트는 다시 단위 테스트를 실행하고 테스트 보고서(`junit.xml`)와 코드 적용 범위 보고서(`clover.xml`)의 두 가지 보고서를 생성합니다. 자세한 내용은 [package.json 파일](#deploy-tut-lambda-cfn-files-package-json) 섹션을 참조하세요.

  다음으로 테스트 작업은 XML 보고서를 CodeCatalyst 보고서로 변환하고 테스트 작업의 **보고서** 탭 아래 CodeCatalyst 콘솔에 표시합니다.

  테스트 작업에 대한 자세한 내용은 [워크플로를 사용한 테스트워크플로를 사용한 테스트](test-workflow-actions.md) 섹션을 참조하세요.
+ 빌드 작업(`BuildBackend`) - 테스트 작업이 완료되면 빌드 작업은 AWS SAM CLI를 다운로드하여 설치하고, `hello-world` 소스를 패키징하고, 패키지를 Lambda 서비스가 예상하는 Amazon S3 버킷에 복사합니다. 또한 작업은 라는 새 AWS SAM 템플릿 파일을 출력`sam-template-packaged.yml`하여 라는 출력 아티팩트에 배치합니다`buildArtifact`.

  빌드 작업에 대한 자세한 내용은 [워크플로로 빌드하기](build-workflow-actions.md) 섹션을 참조하세요.
+ 배포 작업(`DeployCloudFormationStack`) - 빌드 작업이 완료되면 배포 작업은 빌드 작업()에서 생성된 출력 아티팩트를 찾고 그 안의 AWS SAM 템플릿을 `buildArtifact`찾은 다음 템플릿을 실행합니다. AWS SAM 템플릿은 서버리스 애플리케이션을 배포하는 스택을 생성합니다.

**워크플로 생성**

1. 탐색 창에서 **CI/CD**를 선택한 다음 **워크플로**를 선택합니다.

1. **워크플로 생성**을 선택합니다.

1. **소스 리포지토리**에서 `codecatalyst-cfn-source-repository`을 선택합니다.

1. **브랜치**에서 `main`을 선택합니다.

1. **생성(Create)**을 선택합니다.

1. YAML 샘플 코드를 삭제합니다.

1. 다음 YAML 코드를 추가합니다.
**참고**  
다음 YAML 코드에서 원하는 경우 `Connections:` 섹션을 생략할 수 있습니다. 이 섹션을 생략하는 경우 환경의 **기본 IAM 역할** 필드에 지정된 역할에 [2단계: AWS 역할 생성](#deploy-tut-lambda-cfn-roles)에 설명된 두 역할의 권한 및 신뢰 정책이 포함되어 있는지 확인해야 합니다. 기본 IAM 역할이 있는 환경 설정에 대한 자세한 내용은 [환경 생성](deploy-environments-creating-environment.md) 섹션을 참조하세요.

   ```
   Name: codecatalyst-cfn-workflow
   SchemaVersion: 1.0
   
   Triggers:
     - Type: PUSH
       Branches:
         - main   
   Actions:
     Test:
       Identifier: aws/managed-test@v1
       Inputs:
         Sources:
           - WorkflowSource
       Outputs:
         Reports:
           CoverageReport:
             Format: CLOVERXML
             IncludePaths:
               - "coverage/*"
           TestReport:
             Format: JUNITXML
             IncludePaths:
               - junit.xml
       Configuration:
         Steps:
           - Run: npm install
           - Run: npm run test  
     BuildBackend:
       Identifier: aws/build@v1
       DependsOn:
         - Test
       Environment:
         Name: codecatalyst-cfn-environment
         Connections:
           - Name: codecatalyst-account-connection
             Role: codecatalyst-build-role
       Inputs:
         Sources:
           - WorkflowSource
       Configuration: 
         Steps:
           - Run: . ./setup-sam.sh
           - Run: sam package --template-file sam-template.yml --s3-bucket codecatalyst-cfn-s3-bucket --output-template-file sam-template-packaged.yml --region us-west-2
       Outputs:
         Artifacts:
           - Name: buildArtifact
             Files:
               - "**/*"
     DeployCloudFormationStack:
       Identifier: aws/cfn-deploy@v1
       DependsOn: 
         - BuildBackend
       Environment:
         Name: codecatalyst-cfn-environment
         Connections:
           - Name: codecatalyst-account-connection
             Role: codecatalyst-deploy-role
       Inputs:
         Artifacts:
           - buildArtifact
         Sources: []
       Configuration:
         name: codecatalyst-cfn-stack
         region: us-west-2
         role-arn: arn:aws:iam::111122223333:role/StackRole
         template: ./sam-template-packaged.yml
         capabilities: CAPABILITY_IAM,CAPABILITY_AUTO_EXPAND
   ```

   앞의 코드에서
   + *codecatalyst-cfn-environment* 인스턴스 두 개를 모두 에서 생성한 환경 이름으로 바꿉니다.
   + *codecatalyst-account-connection* 인스턴스 두 개를 모두 계정 연결의 표시 이름으로 바꿉니다. 표시 이름은 숫자일 수 있습니다. 자세한 내용은 [3단계: CodeCatalyst에 AWS 역할 추가](#deploy-tut-lambda-cfn-roles-add) 섹션을 참조하세요.
   + [2단계: AWS 역할 생성](#deploy-tut-lambda-cfn-roles)에서 생성한 빌드 역할의 이름을 갖는 *codecatalyst-build-role*.
   + [4단계: Amazon S3 버킷 생성](#deploy-tut-lambda-cfn-s3)에서 생성한 Amazon S3 버킷의 이름을 갖는 *codecatalyst-cfn-s3-bucket*입니다.
   + Amazon S3 버킷이 있는 리전(첫 번째 인스턴스)과 스택이 배포될 리전(두 번째 인스턴스)이 있는 *us-west-2*의 두 인스턴스 모두. 이러한 리전은 다를 수 있습니다. 이 자습서에서는 두 리전이 모두 `us-west-2`로 설정되어 있다고 가정합니다. Amazon S3 및에서 지원하는 리전에 대한 자세한 내용은의 서비스 엔드포인트 및 할당량을 CloudFormation참조하세요*AWS 일반 참조*. [https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html) 
   + [2단계: AWS 역할 생성](#deploy-tut-lambda-cfn-roles)에서 생성한 배포 역할의 이름을 갖는 *codecatalyst-deploy-role*.
   + [사전 조건](#deploy-tut-lambda-cfn-prereqs)에서 생성한 환경 이름을 갖는 *codecatalyst-cfn-environment*.
   + [2단계: AWS 역할 생성](#deploy-tut-lambda-cfn-roles)에서 생성한 스택 역할의 Amazon 리소스 이름(ARN)을 갖는 *arn:aws:iam::111122223333:role/StackRole*.
**참고**  
빌드, 배포 및 스택 역할을 생성하지 않기로 결정한 경우 *codecatalyst-build-role*, *codecatalyst-deploy-role*및 *arn:aws:iam::111122223333:role/StackRole*을 `CodeCatalystWorkflowDevelopmentRole-spaceName` 역할의 이름 또는 ARN으로 바꿉니다. 이에 대한 자세한 내용은 [2단계: AWS 역할 생성](#deploy-tut-lambda-cfn-roles) 섹션을 참조하세요.

   이전에 표시된 코드의 속성에 대한 자세한 내용은 섹션을 참조하세요['스 CloudFormation 택 배포' 작업 YAML](deploy-action-ref-cfn.md).

1. (선택 사항) 커밋하기 전에 YAML 코드가 유효한지 확인하려면 **검증**을 선택합니다.

1. **커밋**을 선택합니다.

1. **워크플로 커밋** 대화 상자에서 다음을 입력합니다.

   1. **워크플로 파일 이름**의 경우 기본값인 `codecatalyst-cfn-workflow`를 유지합니다.

   1. **커밋 메시지**에 다음을 입력합니다.

      ```
      add initial workflow file
      ```

   1. **리포지토리**에서 **codecatalyst-cfn-source-repositor **를 선택합니다.

   1. **브랜치 이름**에서 **기본**을 선택합니다.

   1. **커밋**을 선택합니다.

   이제 워크플로를 생성했습니다. 워크플로 상단에 정의된 트리거로 인해 워크플로 실행이 자동으로 시작됩니다. 특히 `codecatalyst-cfn-workflow.yaml` 파일을 소스 리포지토리에 커밋(및 푸시)할 때 트리거가 워크플로 실행을 시작했습니다.

**진행 중인 워크플로 실행을 보려면**

1. 탐색 창에서 **CI/CD**를 선택한 다음 **워크플로**를 선택합니다.

1. 방금 생성한 `codecatalyst-cfn-workflow` 워크플로를 선택합니다.

1. **실행** 탭을 선택합니다.

1. **실행 ID** 열에서 실행 ID를 선택합니다.

1. **테스트**를 선택하여 테스트 진행 상황을 확인합니다.

1. **BuildBackend**를 선택하여 빌드 진행 상황을 확인합니다.

1. **DeployCloudFormationStack**을 선택하여 배포 진행 상황을 확인합니다.

   실행 세부 정보 보기에 대한 자세한 내용은 [워크플로 실행 상태 및 세부 정보 보기](workflows-view-run.md)를 참조하세요.

1. **DeployCloudFormationStack** 작업이 완료되면 다음을 수행합니다.
   + 워크플로 실행에 성공한 경우 다음 절차로 이동합니다.
   + **테스트** 또는 **BuildBackend** 작업에서 워크플로 실행이 실패한 경우 **로그**를 선택하여 문제를 해결합니다.
   + **DeployCloudFormationStack** 작업에서 워크플로 실행이 실패한 경우 배포 작업을 선택한 다음 **요약** 탭을 선택합니다. **CloudFormation 이벤트** 섹션으로 스크롤하여 자세한 오류 메시지를 확인합니다. 롤백이 발생한 경우 워크플로를 다시 실행하기 전에에서 CloudFormation AWS 콘솔을 통해 `codecatalyst-cfn-stack` 스택을 삭제합니다.

**배포를 확인하려면**

1. 성공적으로 배포한 후 상단 근처의 가로 메뉴 모음에서 **변수(7)**를 선택합니다. (오른쪽 창에서 **변수를** 선택하지 마세요.)

1. **HelloWorldApi** 옆에 `https://` URL을 브라우저에 붙여 넣습니다.

   Lambda 함수의 **hello world** JSON 메시지가 표시되며, 이는 워크플로가 Lambda 함수 및 API Gateway를 성공적으로 배포하고 구성했음을 나타냅니다.
**작은 정보**  
CodeCatalyst가 몇 가지 작은 구성으로 워크플로 다이어그램에 이 URL을 표시하도록 할 수 있습니다. 자세한 내용은 [워크플로 다이어그램에 앱 URL 표시](deploy-app-url.md) 섹션을 참조하세요.

**단위 테스트 결과 및 코드 적용 범위를 확인하려면**

1. 워크플로 다이어그램에서 **테스트**를 선택한 다음 **보고서**를 선택합니다.

1. **TestReport**를 선택하여 단위 테스트 결과를 보거나 **CoverageReport**를 선택하여 테스트 중인 파일의 코드 적용 범위 세부 정보를 봅니다. 이 경우 `app.js` 및 `test-handler.js`입니다.

**배포된 리소스를 확인하려면**

1. 에 로그인 AWS Management Console 하고 [https://console.aws.amazon.com/apigateway/](https://console.aws.amazon.com/apigateway/) API Gateway 콘솔을 엽니다.

1.  AWS SAM 템플릿이 생성한 **codecatalyst-cfn-stack** API를 관찰합니다. API 이름은 워크플로 정의 파일(`codecatalyst-cfn-workflow.yaml`)의 `Configuration/name` 값에서 가져옵니다.

1. [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/) AWS Lambda 콘솔을 엽니다.

1. 탐색 창에서 **함수**를 선택합니다.

1. `codecatalyst-cfn-stack-HelloWorldFunction-string` Lambda 함수를 선택합니다.

1. API Gateway가 함수의 트리거인 방법을 확인할 수 있습니다. 이 통합은 리소스 유형에 따라 AWS SAM `AWS::Serverless::Function` 자동으로 구성되었습니다.

## 7단계: 변경
<a name="deploy-tut-lambda-cfn-change"></a>

이 단계에서는 Lambda 소스 코드를 변경하고 커밋합니다. 이 커밋은 새 워크플로 실행을 시작합니다. 이 실행은 Lambda 콘솔에 지정된 기본 트래픽 이동 구성을 사용하는 청록색 체계로 새 Lambda 함수를 배포합니다.

**Lambda 소스를 변경하려면**

1. CodeCatalyst에서 프로젝트로 이동합니다.

1. 탐색 창에서 **코드**를 선택한 다음 **소스 리포지토리**를 선택합니다.

1. `codecatalyst-cfn-source-repository` 소스 리포지토리를 선택합니다.

1. 애플리케이션 파일 변경:

   1. `hello-world` 폴더를 선택합니다.

   1. `app.js` 파일을 선택합니다.

   1. **편집**을 선택합니다.

   1. 23번 줄에서 `hello world`를 **Tutorial complete\$1**로 변경합니다.

   1. **커밋**을 선택한 다음 **커밋**을 다시 선택합니다.

      커밋으로 인해 워크플로 실행이 시작됩니다. 이름 변경을 반영하도록 단위 테스트를 업데이트하지 않았기 때문에 이 실행은 실패합니다.

1. 단위 테스트를 업데이트합니다.

   1. `hello-world\tests\unit\test-handler.js`을 선택합니다.

   1. **편집**을 선택합니다.

   1. 19번 줄에서 `hello world`를 **Tutorial complete\$1**로 변경합니다.

   1. **커밋**을 선택한 다음 **커밋**을 다시 선택합니다.

      커밋으로 인해 다른 워크플로 실행이 시작됩니다. 이 실행이 성공합니다.

1. 탐색 창에서 **CI/CD**를 선택한 다음 **워크플로**를 선택합니다.

1. `codecatalyst-cfn-workflow`를 선택한 다음 **실행**을 선택합니다.

1. 최신 실행의 실행 ID를 선택합니다. 상태는 진행 중이어야 합니다.

1. **테스트,** **BuildBackend** 및 **DeployCloudFormationStack**을 선택하여 워크플로 실행 진행 상황을 확인합니다.

1. 워크플로가 완료되면 상단 근처의 **변수(7)**를 선택합니다.

1. **HelloWorldApi** 옆에 `https://` URL을 브라우저에 붙여 넣습니다.

   새 애플리케이션이 성공적으로 배포되었음을 나타내는 `Tutorial complete!` 메시지가 브라우저에 나타납니다.

## 정리
<a name="deploy-tut-lambda-cfn-clean-up"></a>

요금이 부과되지 않도록 이 자습서에서 사용하는 파일과 서비스를 정리합니다.

**CodeCatalyst 콘솔에서 정리하려면**

1. [https://codecatalyst.aws/](https://codecatalyst.aws/)에서 CodeCatalyst 콘솔을 엽니다.

1. `codecatalyst-cfn-workflow`를 삭제합니다.

1. `codecatalyst-cfn-environment`를 삭제합니다.

1. `codecatalyst-cfn-source-repository`를 삭제합니다.

1. `codecatalyst-cfn-project`를 삭제합니다.

**에서 정리하려면 AWS Management Console**

1. 다음과 같이 CloudFormation에서 정리합니다.

   1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) CloudFormation 콘솔을 엽니다.

   1. `codecatalyst-cfn-stack`를 삭제합니다.

      스택을 삭제하면 API Gateway 및 Lambda 서비스에서 모든 자습서 리소스가 제거됩니다.

1. 다음과 같이 Amazon S3에서 정리합니다.

   1. [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)에서 S3 콘솔을 엽니다.

   1. `codecatalyst-cfn-s3-bucket`을 선택합니다.

   1. 버킷 콘텐츠를 삭제합니다.

   1.  버킷을 삭제합니다.

1. 다음과 같이 IAM에서 정리합니다.

   1. IAM 콘솔([https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/))을 엽니다.

   1. `codecatalyst-deploy-policy`를 삭제합니다.

   1. `codecatalyst-build-policy`를 삭제합니다.

   1. `codecatalyst-stack-policy`를 삭제합니다.

   1. `codecatalyst-deploy-role`를 삭제합니다.

   1. `codecatalyst-build-role`를 삭제합니다.

   1. `codecatalyst-stack-role`를 삭제합니다.

이 자습서에서는 CodeCatalyst 워크플로 및 스택 배포 작업을 사용하여 서버리스 애플리케이션을 CloudFormation ** CloudFormation 스택으로 배포**하는 방법을 배웠습니다.