

CDK AWS v2 개발자 안내서입니다. 이전 CDK v1은 2022년 6월 1일에 유지 관리에 들어갔으며 2023년 6월 1일에 지원이 종료되었습니다.

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

# AWS CDK 시작하기
<a name="getting-started"></a>

 AWS CDK 명령줄 인터페이스(AWS CDK CLI)를 설치하고 구성하여 AWS 클라우드 개발 키트(AWS CDK)를 시작합니다. 그런 다음 CDK CLI를 사용하여 첫 번째 CDK 앱을 생성하고, AWS 환경을 부트스트랩하고, 애플리케이션을 배포합니다.

## 사전 조건
<a name="getting-started-prerequisites"></a>

 AWS CDK를 시작하기 전에 모든 사전 조건을 완료합니다. 이러한 사전 조건은 프로그래밍을 처음 AWS 사용하거나 프로그래밍을 처음 사용하는 경우에 필요합니다. 지침은 [AWS CDK 사전 요구 사항](prerequisites.md)을 참조하세요.

 AWS CDK가 무엇인지 기본적으로 이해하는 것이 좋습니다. 자세한 내용은 [AWS CDK란 무엇입니까? 및 CDK 핵심 개념 알아보기를](home.md) 참조하세요. [AWS](core-concepts.md) 

## AWS CDK CLI 설치
<a name="getting-started-install"></a>

Node 패키지 관리자를 사용하여 CDK CLI를 설치합니다. 다음 명령을 사용하여 전역에 설치하는 것이 좋습니다.

```
$ npm install -g aws-cdk
```

특정 버전의 CDK CLI를 설치하려면 다음 명령 구조를 사용합니다.

```
$ npm install -g aws-cdk@X.YY.Z
```

여러 버전의 AWS CDK를 사용하려면 개별 CDK 프로젝트에 일치하는 버전의 CDK CLI를 설치하는 것이 좋습니다. 이렇게 하려면 `npm install` 명령에서 `-g` 옵션을 제거합니다. 그런 다음 `npx aws-cdk`를 사용하여 CDK CLI를 간접적으로 호출합니다. 로컬 버전이 있는 경우 로컬 버전이 실행됩니다. 그렇지 않으면 전역적으로 설치된 버전이 사용됩니다.<a name="getting-started-install-troubleshoot"></a>

 **CDK CLI 설치 문제 해결**   
권한 오류가 발생하고 시스템에 관리자 액세스 권한이 있는 경우 다음을 실행합니다.  

```
$ sudo npm install -g aws-cdk
```
오류 메시지가 표시되면 다음을 실행하여 CDK CLI를 제거해 보세요.  

```
$ npm uninstall -g aws-cdk
```
그런 다음 단계를 반복하여 CDK CLI를 다시 설치합니다.

## CDK CLI 설치 성공 확인
<a name="getting-started-install-verify"></a>

다음 명령을 실행하여 설치가 성공적으로 완료되었는지 확인하세요. AWS CDK CLI는 버전 번호를 출력해야 합니다.

```
$ cdk --version
```

## AWS CDK CLI 구성
<a name="getting-started-configure"></a>

CDK CLI를 설치한 후 이를 사용하여 로컬 시스템에서 애플리케이션을 개발할 수 있습니다. 애플리케이션 배포 AWS와 같이와 상호 작용하려면 시작한 작업을 수행할 수 있는 권한이 있는 보안 자격 증명이 로컬 시스템에 구성되어 있어야 합니다.

로컬 시스템에서 보안 자격 증명을 구성하려면 AWS CLI를 사용합니다. 보안 자격 증명을 구성하는 방법은 사용자를 관리하는 방법에 따라 달라집니다. 지침은 * AWS 명령줄 인터페이스 사용 설명서*의 [인증 및 액세스 자격 증명을](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-authentication.html) 참조하세요.

CDK CLI는 AWS CLI로 구성한 보안 자격 증명을 자동으로 사용합니다. 예를 들어 IAM Identity Center 사용자인 경우 `aws configure sso` 명령을 사용하여 보안 자격 증명을 구성할 수 있습니다. IAM 사용자인 경우 `aws configure` 명령을 사용할 수 있습니다. AWS CLI는 로컬 시스템에서 보안 자격 증명을 구성하는 방법을 안내하고 필요한 정보를 `config` 및 `credentials` 파일에 저장합니다. 그런 다음 `cdk deploy`를 사용하여 애플리케이션을 배포하는 등 CDK CLI를 사용하는 경우 CDK CLI는 구성된 보안 자격 증명을 사용합니다.

 AWS CLI와 마찬가지로 CDK CLI는 기본적으로 `default` 프로필을 사용합니다. CDK CLI [`--profile`](ref-cli-cmd.md#ref-cli-cmd-options-profile) 옵션을 사용하여 프로파일을 지정할 수 있습니다. CDK CLI에서 보안 자격 증명을 사용하는 방법에 대한 자세한 내용은 [AWS CDK CLI의 보안 자격 증명 구성을 참조하세요](configure-access.md).

## (선택 사항) 추가 AWS CDK 도구 설치
<a name="getting-started-tools"></a>

[AWS Toolkit for Visual Studio Code](https://aws.amazon.com/visualstudiocode/)는 AWS에서 애플리케이션을 생성, 디버깅 및 배포하는 데 도움이 되는 Visual Studio Code용 오픈 소스 플러그인입니다. 도구 키트는 AWS CDK 애플리케이션 개발을 위한 통합 환경을 제공합니다. 여기에는 AWS CDK 프로젝트를 나열하고 AWS CDK 애플리케이션의 다양한 구성 요소를 탐색하는 CDK Explorer 기능이 포함되어 있습니다. 지침은 다음을 참조하세요.
+  [AWS Toolkit for Visual Studio 코드 설치](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/setup-toolkit.html).
+  [AWS VS Code용 CDK](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/cdk-explorer.html).

## 첫 번째 CDK 앱 생성
<a name="getting-started-app"></a>

이제 첫 번째 AWS CDK 앱을 생성하여 CDK 사용을 시작할 준비가 되었습니다. 지침은 [자습서: 첫 번째 AWS CDK 앱 생성을 참조하세요](hello-world.md).

# 자습서: 첫 번째 AWS CDK 앱 생성
<a name="hello-world"></a>

 AWS CDK 명령줄 인터페이스(AWS CDK CLI)를 사용하여 첫 번째 CDK 앱을 개발하고, AWS 환경을 부트스트랩하고, 애플리케이션을 배포하여 AWS 클라우드 개발 키트(AWS CDK) 사용을 시작합니다 AWS.

## 사전 조건
<a name="hello-world-prerequisites"></a>

이 자습서를 시작하기 전에 [AWS CDK 시작하기의](getting-started.md) 모든 설정 단계를 완료합니다.

## 이 자습서 소개
<a name="hello-world-about"></a>

이 자습서에서는 AWS CDK를 AWS 사용하여에 간단한 애플리케이션을 생성하고 배포합니다. 애플리케이션은 간접적으로 호출될 때 `Hello World!` 메시지를 반환하는 [AWS Lambda 함수](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)로 구성됩니다. 함수는 [Lambda 함수 URL](https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html)을 통해 간접적으로 호출됩니다. 이 URL은 Lambda 함수에 대한 전용 HTTP(S) 엔드포인트 역할을 합니다.

이 자습서를 통해 다음을 수행합니다.
+  **프로젝트 생성** - CDK CLI `cdk init` 명령을 사용하여 CDK 프로젝트를 생성합니다.
+  ** AWS 환경 구성** - 애플리케이션을 배포할 AWS 환경을 구성합니다.
+  ** AWS 환경 부트스트랩** - CDK CLI `cdk bootstrap` 명령을 사용하여 환경을 부트스트랩하여 배포할 AWS 환경을 준비합니다.
+  **앱 개발** - AWS Construct Library의 구문을 사용하여 Lambda 함수 및 Lambda 함수 URL 리소스를 정의합니다.
+  **배포를 위한 앱 준비** - CDK CLI를 사용하여 앱을 빌드하고 AWS CloudFormation 템플릿을 합성합니다.
+  **앱 배포** - CDK CLI `cdk deploy` 명령을 사용하여 애플리케이션을 배포하고 AWS 리소스를 프로비저닝합니다.
+  **애플리케이션과 상호 작용** - 배포된 Lambda 함수를 호출하고 응답을 수신 AWS 하여에서 배포된 Lambda 함수와 상호 작용합니다.
+  **앱 수정** - Lambda 함수를 수정하고 배포하여 변경 사항을 구현합니다.
+  **앱 삭제** - CDK CLI `cdk destroy` 명령을 사용하여 생성한 모든 리소스를 삭제합니다.

## 1단계: CDK 프로젝트 생성
<a name="hello-world-create"></a>

이 단계에서는 새 CDK 프로젝트를 생성합니다. CDK 프로젝트는 자체 로컬 모듈 종속성과 함께 자체 디렉터리에 있어야 합니다.

 **CDK 프로젝트를 생성하려면**   

1. 원하는 시작 디렉터리에서 생성하고 `hello-cdk`라는 디렉터리로 이동합니다.

   ```
   $ mkdir hello-cdk && cd hello-cdk
   ```
**중요**  
*여기에 표시된 것과 똑같이* 프로젝트 디렉터리의 이름을 `hello-cdk`로 지정하세요. CDK CLI는 이 디렉터리 이름을 사용하여 CDK 코드 내에서 사물의 이름을 지정합니다. 다른 디렉터리 이름을 사용하는 경우 이 자습서 중 문제가 발생합니다.

1. `hello-cdk` 디렉터리에서 CDK CLI `cdk init` 명령을 사용하여 새 CDK 프로젝트를 초기화합니다. `--language` 옵션을 사용하여 `app` 템플릿과 원하는 프로그래밍 언어를 지정합니다.  
**Example**  

------
#### [ TypeScript ]

   ```
   $ cdk init app --language typescript
   ```

------
#### [ JavaScript ]

   ```
   $ cdk init app --language javascript
   ```

------
#### [ Python ]

   ```
   $ cdk init app --language python
   ```

   앱을 생성한 후 다음 두 명령도 입력합니다. 이렇게 하면 앱의 Python 가상 환경이 활성화되고 AWS CDK 코어 종속성이 설치됩니다.

   ```
   $ source .venv/bin/activate # On Windows, run `.\venv\Scripts\activate` instead
   $ python -m pip install -r requirements.txt
   ```

------
#### [ Java ]

   ```
   $ cdk init app --language java
   ```

   IDE를 사용하는 경우 이제 프로젝트를 열거나 가져올 수 있습니다. 예를 들어, Eclipse에서 **파일** > **가져오기** > **Maven** > **기존 Maven 프로젝트**를 선택합니다. 프로젝트 설정이 Java 8(1.8)을 사용하도록 설정되어 있는지 확인합니다.

------
#### [ C\$1 ]

   ```
   $ cdk init app --language csharp
   ```

   Visual Studio를 사용하는 경우 `src` 디렉터리에서 솔루션 파일을 엽니다.

------
#### [ Go ]

   ```
   $ cdk init app --language go
   ```

   앱을 생성한 후 다음 명령도 입력하여 앱에 필요한 AWS Construct Library 모듈을 설치합니다.

   ```
   $ go get
   ```

------

`cdk init` 명령은 `hello-cdk` 디렉터리 내에 파일 및 폴더 구문을 생성하여 CDK 앱의 소스 코드를 구성하는 데 도움이 됩니다. 이러한 파일 및 폴더 구문을 CDK *프로젝트*라고 합니다. 잠시 시간을 내어 CDK 프로젝트를 살펴보세요.

Git을 설치한 경우 `cdk init`를 사용하여 생성한 각 프로젝트도 Git 리포지토리로 초기화됩니다.

프로젝트 초기화 중 CDK CLI는 단일 CDK 스택이 포함된 CDK 앱을 생성합니다. CDK 앱 인스턴스는 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html) 구문을 사용하여 생성됩니다. 다음은 CDK 애플리케이션 파일에서 이 코드의 일부입니다.

**Example**  
`bin/hello-cdk.ts`에 위치합니다.  

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

const app = new cdk.App();
new HelloCdkStack(app, 'HelloCdkStack', {
});
```
`bin/hello-cdk.js`에 위치합니다.  

```
#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { HelloCdkStack } = require('../lib/hello-cdk-stack');

const app = new cdk.App();
new HelloCdkStack(app, 'HelloCdkStack', {
});
```
`app.py`에 위치합니다.  

```
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from hello_cdk.hello_cdk_stack import HelloCdkStack

app = cdk.App()
HelloCdkStack(app, "HelloCdkStack",)

app.synth()
```
`src/main/java/…​/HelloCdkApp.java`에 위치합니다.  

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;

import java.util.Arrays;

public class HelloCdkApp {
  public static void main(final String[] args) {
    App app = new App();

    new HelloCdkStack(app, "HelloCdkStack", StackProps.builder()
      .build());

    app.synth();
  }
}
```
`src/HelloCdk/Program.cs`에 위치합니다.  

```
using Amazon.CDK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace HelloCdk
{
  sealed class Program
  {
    public static void Main(string[] args)
    {
      var app = new App();
      new HelloCdkStack(app, "HelloCdkStack", new StackProps
      {});
      app.Synth();
    }
  }
}
```
`hello-cdk.go`에 위치합니다.  

```
package main

import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/constructs-go/constructs/v10"
  "github.com/aws/jsii-runtime-go"
)

// ...

func main() {
  defer jsii.Close()

  app := awscdk.NewApp(nil)

  NewHelloCdkStack(app, "HelloCdkStack", &HelloCdkStackProps{
    awscdk.StackProps{
      Env: env(),
    },
  })

  app.Synth(nil)
}

// ...
```

CDK 스택은 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html) 구문을 사용하여 생성됩니다. 다음은 CDK 스택 파일에서 이 코드의 일부입니다.

**Example**  
`lib/hello-cdk-stack.ts`에 위치합니다.  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class HelloCdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Define your constructs here

  }
}
```
`lib/hello-cdk-stack.js`에 위치합니다.  

```
const { Stack } = require('aws-cdk-lib');

class HelloCdkStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define your constructs here

  }
}

module.exports = { HelloCdkStack }
```
`hello_cdk/hello_cdk_stack.py`에 위치합니다.  

```
from aws_cdk import (
  Stack,
)
from constructs import Construct

class HelloCdkStack(Stack):

  def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
    super().__init__(scope, construct_id, **kwargs)

    # Define your constructs here
```
`src/main/java/…​/HelloCdkStack.java`에 위치합니다.  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class HelloCdkStack extends Stack {
  public HelloCdkStack(final Construct scope, final String id) {
    this(scope, id, null);
  }

  public HelloCdkStack(final Construct scope, final String id, final StackProps props) {
    super(scope, id, props);

    // Define your constructs here
  }
}
```
`src/HelloCdk/HelloCdkStack.cs`에 위치합니다.  

```
using Amazon.CDK;
using Constructs;

namespace HelloCdk
{
  public class HelloCdkStack : Stack
  {
    internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
    {
      // Define your constructs here
    }
  }
}
```
`hello-cdk.go`에 위치합니다.  

```
package main

import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/constructs-go/constructs/v10"
  "github.com/aws/jsii-runtime-go"
)

type HelloCdkStackProps struct {
  awscdk.StackProps
}

func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack {
  var sprops awscdk.StackProps
  if props != nil {
    sprops = props.StackProps
  }
  stack := awscdk.NewStack(scope, &id, &sprops)

  return stack
}

// ...
```

## 2단계: AWS 환경 구성
<a name="hello-world-configure"></a>

이 단계에서는 CDK 스택의 AWS 환경을 구성합니다. 이렇게 하면 CDK 스택을 배포할 환경을 지정할 수 있습니다.

먼저 사용할 AWS 환경을 결정합니다. AWS 환경은 AWS 계정과 AWS 리전으로 구성됩니다.

 AWS CLI를 사용하여 로컬 시스템에서 보안 자격 증명을 구성할 때 AWS CLI를 사용하여 특정 프로필에 대한 AWS 환경 정보를 얻을 수 있습니다.

 ** AWS CLI를 사용하여 AWS 계정 ID를 가져오려면**   

1. 다음 AWS CLI 명령을 실행하여 `default` 프로필의 AWS 계정 ID를 가져옵니다.

   ```
   $ aws sts get-caller-identity --query "Account" --output text
   ```

1. 이름이 지정된 프로파일을 사용하려면 `--profile` 옵션을 사용하여 프로파일 이름을 입력합니다.

   ```
   $ aws sts get-caller-identity --profile your-profile-name --query "Account" --output text
   ```

 ** AWS CLI를 사용하여 AWS 리전을 가져오려면**   

1. 다음 AWS CLI 명령을 실행하여 `default` 프로파일에 대해 구성한 리전을 가져옵니다.

   ```
   $ aws configure get region
   ```

1. 이름이 지정된 프로파일을 사용하려면 `--profile` 옵션을 사용하여 프로파일 이름을 입력합니다.

   ```
   $ aws configure get region --profile your-profile-name
   ```

다음으로 *애플리케이션 파일의* `HelloCdkStack` 인스턴스를 수정하여 CDK 스택의 AWS 환경을 구성합니다. 이 자습서에서는 AWS 환경 정보를 하드 코딩합니다. 프로덕션 환경에는 권장되지 않습니다. 환경을 구성하는 다른 방법에 대한 자세한 내용은 [AWS CDK와 함께 사용할 환경 구성을 참조하세요](configure-env.md).

 **CDK 스택의 환경을 구성하려면**   

1. *애플리케이션 파일 *에서 `Stack` 구문의 `env` 속성을 사용하여 환경을 구성합니다. 다음은 예제입니다.  
**Example**  

------
#### [ TypeScript ]

   `bin/hello-cdk.ts`에 위치합니다.

   ```
   #!/usr/bin/env node
   import 'source-map-support/register';
   import * as cdk from 'aws-cdk-lib';
   import { HelloCdkStack } from '../lib/hello-cdk-stack';
   
   const app = new cdk.App();
   new HelloCdkStack(app, 'HelloCdkStack', {
     env: { account: '123456789012', region: 'us-east-1' },
   });
   ```

------
#### [ JavaScript ]

   `bin/hello-cdk.js`에 위치합니다.

   ```
   #!/usr/bin/env node
   
   const cdk = require('aws-cdk-lib');
   const { HelloCdkStack } = require('../lib/hello-cdk-stack');
   
   const app = new cdk.App();
   new HelloCdkStack(app, 'HelloCdkStack', {
     env: { account: '123456789012', region: 'us-east-1' },
   });
   ```

------
#### [ Python ]

   `app.py`에 위치합니다.

   ```
   #!/usr/bin/env python3
   import os
   
   import aws_cdk as cdk
   
   from hello_cdk.hello_cdk_stack import HelloCdkStack
   
   app = cdk.App()
   HelloCdkStack(app, "HelloCdkStack",
     env=cdk.Environment(account='123456789012', region='us-east-1'),
     )
   
   app.synth()
   ```

------
#### [ Java ]

   `src/main/java/…​/HelloCdkApp.java`에 위치합니다.

   ```
   package com.myorg;
   
   import software.amazon.awscdk.App;
   import software.amazon.awscdk.Environment;
   import software.amazon.awscdk.StackProps;
   
   import java.util.Arrays;
   
   public class HelloCdkApp {
       public static void main(final String[] args) {
           App app = new App();
   
           new HelloCdkStack(app, "HelloCdkStack", StackProps.builder()
                   .env(Environment.builder()
                           .account("123456789012")
                           .region("us-east-1")
                           .build())
   
                   .build());
   
           app.synth();
       }
   }
   ```

------
#### [ C\$1 ]

   `src/HelloCdk/Program.cs`에 위치합니다.

   ```
   using Amazon.CDK;
   using System;
   using System.Collections.Generic;
   using System.Linq;
   
   namespace HelloCdk
   {
       sealed class Program
       {
           public static void Main(string[] args)
           {
               var app = new App();
               new HelloCdkStack(app, "HelloCdkStack", new StackProps
               {
                   Env = new Amazon.CDK.Environment
                   {
                       Account = "123456789012",
                       Region = "us-east-1",
                   }
               });
               app.Synth();
           }
       }
   }
   ```

------
#### [ Go ]

   `hello-cdk.go`에 위치합니다.

   ```
   package main
   
   import (
     "github.com/aws/aws-cdk-go/awscdk/v2"
     "github.com/aws/constructs-go/constructs/v10"
     "github.com/aws/jsii-runtime-go"
   )
   
   // ...
   
   func main() {
     defer jsii.Close()
   
     app := awscdk.NewApp(nil)
   
     NewHelloCdkStack(app, "HelloCdkStack", &HelloCdkStackProps{
       awscdk.StackProps{
         Env: env(),
       },
     })
   
     app.Synth(nil)
   }
   
   func env() *awscdk.Environment {
   	return &awscdk.Environment{
   		Account: jsii.String("123456789012"),
   		Region:  jsii.String("us-east-1"),
   	}
   }
   ```

------

## 3단계: AWS 환경 부트스트랩
<a name="hello-world-bootstrap"></a>

이 단계에서는 이전 단계에서 구성한 AWS 환경을 부트스트랩합니다. 이렇게 하면 CDK 배포를 위한 환경이 준비됩니다.

환경을 부트스트래핑하려면 CDK 프로젝트의 루트에서 다음을 실행합니다.

```
$ cdk bootstrap
```

CDK 프로젝트의 루트에서 부트스트래핑하면 추가 정보를 제공할 필요가 없습니다. CDK CLI는 프로젝트에서 환경 정보를 가져옵니다. CDK 프로젝트 외부에서 부트스트래핑할 때는 `cdk bootstrap` 명령과 함께 환경 정보를 제공해야 합니다. 자세한 내용은 [AWS CDK와 함께 사용할 환경 부트스트랩을](bootstrapping-env.md) 참조하세요.

## 4단계: CDK 앱 빌드
<a name="hello-world-build"></a>

대부분의 프로그래밍 환경에서는 변경 후 코드를 빌드하거나 컴파일합니다. AWS CDK CLI가이 단계를 자동으로 수행하므로 CDK에서는이 작업이 필요하지 않습니다. 그러나 구문 및 유형 오류를 포착하려는 경우에도 수동으로 빌드할 수 있습니다. 다음은 예제입니다.

**Example**  

```
$ npm run build

> hello-cdk@0.1.0 build
> tsc
```
빌드 단계는 필요하지 않습니다.
빌드 단계는 필요하지 않습니다.

```
$ mvn compile -q
```
또는 Eclipse에서 `Control-B`를 누릅니다(다른 Java IDE는 다를 수 있음).

```
$ dotnet build src
```
또는 Visual Studio에서 F6을 누릅니다.

```
$ go build
```

## 5단계: 앱의 CDK 스택 나열
<a name="hello-world-list"></a>

이때 단일 CDK 스택이 포함된 CDK 앱이 있어야 합니다. 확인하려면 CDK CLI `cdk list` 명령을 사용하여 스택을 표시합니다. 출력에는 `HelloCdkStack`이라는 단일 스택이 표시되어야 합니다.

```
$ cdk list
HelloCdkStack
```

이 출력이 표시되지 않으면 프로젝트의 올바른 작업 디렉터리에 있는지 확인하고 다시 시도하세요. 그래도 스택이 보이지 않으면 [1단계: CDK 프로젝트 생성](#hello-world-create)을 반복하고 다시 시도하세요.

## 6단계: Lambda 함수 정의
<a name="hello-world-function"></a>

이 단계에서는 AWS Construct Library에서 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html) 모듈을 가져오고 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html) L2 구문을 사용합니다.

다음과 같이 CDK 스택 파일을 수정합니다.

**Example**  
`lib/hello-cdk-stack.ts`에 위치합니다.  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// Import the Lambda module
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class HelloCdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Define the Lambda function resource
    const myFunction = new lambda.Function(this, "HelloWorldFunction", {
      runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime
      handler: "index.handler",
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
    });
  }
}
```
`lib/hello-cdk-stack.js`에 위치합니다.  

```
const { Stack } = require('aws-cdk-lib');
// Import the Lambda module
const lambda = require('aws-cdk-lib/aws-lambda');

class HelloCdkStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define the Lambda function resource
    const myFunction = new lambda.Function(this, "HelloWorldFunction", {
      runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime
      handler: "index.handler",
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
    });

  }
}

module.exports = { HelloCdkStack }
```
`hello_cdk/hello_cdk_stack.py`에 위치합니다.  

```
from aws_cdk import (
  Stack,
  aws_lambda as _lambda, # Import the Lambda module
)
from constructs import Construct

class HelloCdkStack(Stack):

  def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
    super().__init__(scope, construct_id, **kwargs)

    # Define the Lambda function resource
    my_function = _lambda.Function(
      self, "HelloWorldFunction",
      runtime = _lambda.Runtime.NODEJS_20_X, # Provide any supported Node.js runtime
      handler = "index.handler",
      code = _lambda.Code.from_inline(
        """
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        """
      ),
    )
```
`src/main/java/…​/HelloCdkStack.java`에 위치합니다.  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
// Import Lambda function
import software.amazon.awscdk.services.lambda.Code;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;

public class HelloCdkStack extends Stack {
  public HelloCdkStack(final Construct scope, final String id) {
    this(scope, id, null);
  }

  public HelloCdkStack(final Construct scope, final String id, final StackProps props) {
    super(scope, id, props);

    // Define the Lambda function resource
    Function myFunction = Function.Builder.create(this, "HelloWorldFunction")
      .runtime(Runtime.NODEJS_20_X) // Provide any supported Node.js runtime
      .handler("index.handler")
      .code(Code.fromInline(
        "exports.handler = async function(event) {" +
        " return {" +
        " statusCode: 200," +
        " body: JSON.stringify('Hello World!')" +
        " };" +
        "};"))
      .build();

  }
}
```
`src/main/java/…​/HelloCdkStack.java`에 위치합니다.  

```
using Amazon.CDK;
using Constructs;
// Import the Lambda module
using Amazon.CDK.AWS.Lambda;

namespace HelloCdk
{
  public class HelloCdkStack : Stack
  {
    internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
    {
      // Define the Lambda function resource
      var myFunction = new Function(this, "HelloWorldFunction", new FunctionProps
      {
        Runtime = Runtime.NODEJS_20_X, // Provide any supported Node.js runtime
        Handler = "index.handler",
        Code = Code.FromInline(@"
          exports.handler = async function(event) {
            return {
              statusCode: 200,
              body: JSON.stringify('Hello World!'),
            };
          };
        "),
      });
    }
  }
}
```
`hello-cdk.go`에 위치합니다.  

```
package main

import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/constructs-go/constructs/v10"
  "github.com/aws/jsii-runtime-go"
  // Import the Lambda module
  "github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
)

type HelloCdkStackProps struct {
  awscdk.StackProps
}

func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack {
  var sprops awscdk.StackProps
  if props != nil {
    sprops = props.StackProps
  }
  stack := awscdk.NewStack(scope, &id, &sprops)

  // Define the Lambda function resource
  myFunction := awslambda.NewFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.FunctionProps{
    Runtime: awslambda.Runtime_NODEJS_20_X(), // Provide any supported Node.js runtime
    Handler: jsii.String("index.handler"),
    Code: awslambda.Code_FromInline(jsii.String(`
      exports.handler = async function(event) {
        return {
          statusCode: 200,
          body: JSON.stringify('Hello World!'),
        };
      };
    `)),
  })

  return stack
}

// ...
```

`Function` 구문을 좀 더 자세히 살펴보겠습니다. 모든 구문과 마찬가지로 `Function` 클래스는 세 가지 파라미터를 사용합니다.
+  **scope** - `Stack` 인스턴스를 `Function` 구문의 상위로 정의합니다. AWS 리소스를 정의하는 모든 구문은 스택 범위 내에서 생성됩니다. 구문 내부에 구문을 정의하여 계층 구조(트리)를 생성할 수 있습니다. 여기에서 대부분의 경우 scope는 `this`(Python의 `self`)입니다.
+  **Id** - AWS CDK 앱 `Function` 내의 구문 ID입니다. 이 ID와 스택 내 함수의 위치를 기반으로 하는 해시는 배포 중 함수를 고유하게 식별합니다. AWS 또한 CDK는 앱에서 구문을 업데이트하고 다시 배포하여 배포된 리소스를 업데이트할 때이 ID를 참조합니다. 여기서 구문 ID는 `HelloWorldFunction`입니다. 함수에는 `functionName` 속성으로 지정된 이름이 있을 수도 있습니다. 이는 ID 구문과 다릅니다.
+  **props** - 함수의 속성을 정의하는 값 번들입니다. 여기서 `runtime`, `handler` 및 `code` 속성을 정의합니다.

  Props는 AWS CDK에서 지원하는 언어에서 다르게 표현됩니다.
  + TypeScript 및 JavaScript에서 `props`는 단일 인수이며 원하는 속성이 포함된 객체를 전달합니다.
  + Python에서 props는 키워드 인수로 전달됩니다.
  + Java에서는 props를 전달하기 위해 Builder가 제공됩니다. 두 가지가 있습니다. 하나는 `FunctionProps`용이고, 다른 하나는 `Function`용으로, 이를 사용하면 한 단계로 구문과 해당 props 객체를 빌드할 수 있습니다. 이 코드는 후자를 사용합니다.
  + C\$1에서는 객체 이니셜라이저를 사용하여 `FunctionProps` 객체를 인스턴스화하고 이를 세 번째 파라미터로 전달합니다.

    구문의 props가 선택 사항인 경우 `props` 파라미터를 완전히 생략할 수 있습니다.

모든 구문은 이 세 가지 동일한 인수를 취하므로 새 구문에 대해 배울 때 쉽게 방향을 잡을 수 있습니다. 그리고 예상할 수 있듯이, 필요에 따라 또는 기본값을 변경하려는 경우 모든 구문을 서브클래싱하여 확장할 수 있습니다.

## 7단계: Lambda 함수 URL 정의
<a name="hello-world-url"></a>

이 단계에서는 `Function` 구문의 `addFunctionUrl` 도우미 메서드를 사용하여 Lambda 함수 URL을 정의합니다. 배포 시이 URL의 값을 출력하려면 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.CfnOutput.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.CfnOutput.html) 구문을 사용하여 AWS CloudFormation 출력을 생성합니다.

CDK 스택 파일에 다음을 추가합니다.

**Example**  
`lib/hello-cdk-stack.ts`에 위치합니다.  

```
// ...

export class HelloCdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Define the Lambda function resource
    // ...

    // Define the Lambda function URL resource
    const myFunctionUrl = myFunction.addFunctionUrl({
      authType: lambda.FunctionUrlAuthType.NONE,
    });

    // Define a CloudFormation output for your URL
    new cdk.CfnOutput(this, "myFunctionUrlOutput", {
      value: myFunctionUrl.url,
    })

  }
}
```
`lib/hello-cdk-stack.js`에 위치합니다.  

```
const { Stack, CfnOutput } = require('aws-cdk-lib');  // Import CfnOutput

class HelloCdkStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define the Lambda function resource
    // ...

    // Define the Lambda function URL resource
    const myFunctionUrl = myFunction.addFunctionUrl({
      authType: lambda.FunctionUrlAuthType.NONE,
    });

    // Define a CloudFormation output for your URL
    new CfnOutput(this, "myFunctionUrlOutput", {
      value: myFunctionUrl.url,
    })

  }
}

module.exports = { HelloCdkStack }
```
`hello_cdk/hello_cdk_stack.py`에 위치합니다.  

```
from aws_cdk import (
  # ...
  CfnOutput # Import CfnOutput
)
from constructs import Construct

class HelloCdkStack(Stack):

  def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
    super().__init__(scope, construct_id, **kwargs)

    # Define the Lambda function resource
    # ...

    # Define the Lambda function URL resource
    my_function_url = my_function.add_function_url(
      auth_type = _lambda.FunctionUrlAuthType.NONE,
    )

    # Define a CloudFormation output for your URL
    CfnOutput(self, "myFunctionUrlOutput", value=my_function_url.url)
```
`src/main/java/…​/HelloCdkStack.java`에 위치합니다.  

```
package com.myorg;

// ...
// Import Lambda function URL
import software.amazon.awscdk.services.lambda.FunctionUrl;
import software.amazon.awscdk.services.lambda.FunctionUrlAuthType;
import software.amazon.awscdk.services.lambda.FunctionUrlOptions;
// Import CfnOutput
import software.amazon.awscdk.CfnOutput;

public class HelloCdkStack extends Stack {
  public HelloCdkStack(final Construct scope, final String id) {
    this(scope, id, null);
  }

  public HelloCdkStack(final Construct scope, final String id, final StackProps props) {
    super(scope, id, props);

    // Define the Lambda function resource
    // ...

    // Define the Lambda function URL resource
    FunctionUrl myFunctionUrl = myFunction.addFunctionUrl(FunctionUrlOptions.builder()
      .authType(FunctionUrlAuthType.NONE)
      .build());

    // Define a CloudFormation output for your URL
    CfnOutput.Builder.create(this, "myFunctionUrlOutput")
      .value(myFunctionUrl.getUrl())
      .build();
  }
}
```
`src/main/java/…​/HelloCdkStack.java`에 위치합니다.  

```
// ...

namespace HelloCdk
{
  public class HelloCdkStack : Stack
  {
    internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
    {
      // Define the Lambda function resource
      // ...

      // Define the Lambda function URL resource
      var myFunctionUrl = myFunction.AddFunctionUrl(new FunctionUrlOptions
      {
        AuthType = FunctionUrlAuthType.NONE
      });

      // Define a CloudFormation output for your URL
      new CfnOutput(this, "myFunctionUrlOutput", new CfnOutputProps
      {
        Value = myFunctionUrl.Url
      });
    }
  }
}
```
`hello-cdk.go`에 위치합니다.  

```
// ...

func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack {
  var sprops awscdk.StackProps
  if props != nil {
    sprops = props.StackProps
  }
  stack := awscdk.NewStack(scope, &id, &sprops)

  // Define the Lambda function resource
  // ...

  // Define the Lambda function URL resource
  myFunctionUrl := myFunction.AddFunctionUrl(&awslambda.FunctionUrlOptions{
    AuthType: awslambda.FunctionUrlAuthType_NONE,
  })

  // Define a CloudFormation output for your URL
  awscdk.NewCfnOutput(stack, jsii.String("myFunctionUrlOutput"), &awscdk.CfnOutputProps{
    Value: myFunctionUrl.Url(),
  })

  return stack
}

// ...
```

**주의**  
이 자습서를 간단하게 유지하기 위해 Lambda 함수 URL은 인증 없이 정의됩니다. 배포되면 함수를 간접적으로 호출하는 데 사용할 수 있는 공개적으로 액세스할 수 있는 엔드포인트가 생성됩니다. 이 자습서를 마치면 [12단계: 애플리케이션 삭제](#hello-world-delete)에 따라 이러한 리소스를 삭제합니다.

## 8단계: CloudFormation 템플릿 합성
<a name="hello-world-synth"></a>

이 단계에서는 CloudFormation 템플릿을 CDK CLI `cdk synth` 명령과 합성하여 배포를 준비합니다. 이 명령은 CDK 코드의 기본 검증을 수행하고, CDK 앱을 실행하고, CDK 스택에서 CloudFormation 템플릿을 생성합니다.

앱에 스택이 2개 이상 포함된 경우 합성할 스택을 지정해야 합니다. 앱에 단일 스택이 포함되어 있으므로 CDK CLI는 자동으로 스택을 탐지하여 합성합니다.

템플릿을 합성하지 않으면 배포 시 CDK CLI가 이 단계를 자동으로 수행합니다. 그러나 각 배포 전에 이 단계를 실행하여 합성 오류가 있는지 확인하는 것이 좋습니다.

템플릿을 합성하기 전에 필요에 따라 애플리케이션을 빌드하여 구문 및 유형 오류를 포착할 수 있습니다. 지침은 [4단계: CDK 앱 빌드](#hello-world-build)를 참조하세요.

CloudFormation 템플릿을 합성하려면 프로젝트 루트에서 다음을 실행합니다.

```
$ cdk synth
```

**참고**  
다음과 같은 오류가 발생하면 `hello-cdk` 디렉터리에 있는지 확인하고 다시 시도하세요.  

```
--app is required either in command-line, in cdk.json or in ~/.cdk.json
```

성공하면 CDK CLI는 `YAML` 형식의 CloudFormation 템플릿을 `stdout`에 출력하고 프로젝트의 `cdk.out` 디렉터리에 `JSON` 형식의 템플릿을 저장합니다.

다음은 CloudFormation 템플릿의 예제 출력입니다.

### AWS CloudFormation 템플릿
<a name="hello-world-synth-template"></a>

```
Resources:
  HelloWorldFunctionServiceRole<unique-identifier>:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
        Version: "2012-10-17"		 	 	 
      ManagedPolicyArns:
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    Metadata:
      aws:cdk:path: HelloCdkStack/HelloWorldFunction/ServiceRole/Resource
  HelloWorldFunction<unique-identifier>:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile: "

          \        exports.handler = async function(event) {

          \          return {

          \            statusCode: 200,

          \            body: JSON.stringify('Hello World!'),

          \          };

          \        };

          \      "
      Handler: index.handler
      Role:
        Fn::GetAtt:
          - HelloWorldFunctionServiceRole<unique-identifier>
          - Arn
      Runtime: nodejs20.x
    DependsOn:
      - HelloWorldFunctionServiceRole<unique-identifier>
    Metadata:
      aws:cdk:path: HelloCdkStack/HelloWorldFunction/Resource
  HelloWorldFunctionFunctionUrl<unique-identifier>:
    Type: AWS::Lambda::Url
    Properties:
      AuthType: NONE
      TargetFunctionArn:
        Fn::GetAtt:
          - HelloWorldFunction<unique-identifier>
          - Arn
    Metadata:
      aws:cdk:path: HelloCdkStack/HelloWorldFunction/FunctionUrl/Resource
  HelloWorldFunctioninvokefunctionurl<unique-identifier>:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunctionUrl
      FunctionName:
        Fn::GetAtt:
          - HelloWorldFunction<unique-identifier>
          - Arn
      FunctionUrlAuthType: NONE
      Principal: "*"
    Metadata:
      aws:cdk:path: HelloCdkStack/HelloWorldFunction/invoke-function-url
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:<unique-identifier>
    Metadata:
      aws:cdk:path: HelloCdkStack/CDKMetadata/Default
    Condition: CDKMetadataAvailable
Outputs:
  myFunctionUrlOutput:
    Value:
      Fn::GetAtt:
        - HelloWorldFunctionFunctionUrl<unique-identifier>
        - FunctionUrl
Parameters:
  BootstrapVersion:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /cdk-bootstrap/<unique-identifier>/version
    Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
Rules:
  CheckBootstrapVersion:
    Assertions:
      - Assert:
          Fn::Not:
            - Fn::Contains:
                - - "1"
                  - "2"
                  - "3"
                  - "4"
                  - "5"
                - Ref: BootstrapVersion
        AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.
```

**참고**  
생성된 모든 템플릿에는 기본적으로 ` AWS::CDK::Metadata` 리소스가 포함되어 있습니다. AWS CDK 팀은이 메타데이터를 사용하여 AWS CDK 사용량에 대한 인사이트를 얻고 이를 개선할 방법을 찾습니다. 버전 보고를 옵트아웃하는 방법을 비롯한 자세한 내용은 [버전 보고](cli.md#version-reporting)를 참조하세요.

단일 L2 구문을 정의하여 AWS CDK는 리소스가 애플리케이션 내에서 상호 작용하는 데 필요한 권한 및 글루 로직과 함께 Lambda 리소스가 포함된 광범위한 CloudFormation 템플릿을 생성합니다.

## 9단계: CDK 스택 배포
<a name="hello-world-deploy"></a>

이 단계에서는 CDK CLI `cdk deploy` 명령을 사용하여 CDK 스택을 배포합니다. 이 명령은 생성된 CloudFormation 템플릿을 검색하고 AWS CloudFormation 스택의 일부로 리소스를 프로비저닝하는 CloudFormation을 통해 배포합니다.

프로젝트 루트에서 다음을 실행합니다. 메시지가 표시되면 변경 사항을 확인합니다.

```
$ cdk deploy

✨  Synthesis time: 2.69s

HelloCdkStack:  start: Building <unique-identifier>:current_account-current_region
HelloCdkStack:  success: Built <unique-identifier>:current_account-current_region
HelloCdkStack:  start: Publishing <unique-identifier>:current_account-current_region
HelloCdkStack:  success: Published <unique-identifier>:current_account-current_region
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

IAM Statement Changes
┌───┬───────────────────────────────────────┬────────┬──────────────────────────┬──────────────────────────────┬───────────┐
│   │ Resource                              │ Effect │ Action                   │ Principal                    │ Condition │
├───┼───────────────────────────────────────┼────────┼──────────────────────────┼──────────────────────────────┼───────────┤
│ + │ ${HelloWorldFunction.Arn}             │ Allow  │ lambda:InvokeFunctionUrl │ *                            │           │
├───┼───────────────────────────────────────┼────────┼──────────────────────────┼──────────────────────────────┼───────────┤
│ + │ ${HelloWorldFunction/ServiceRole.Arn} │ Allow  │ sts:AssumeRole           │ Service:lambda.amazonaws.com │           │
└───┴───────────────────────────────────────┴────────┴──────────────────────────┴──────────────────────────────┴───────────┘
IAM Policy Changes
┌───┬───────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐
│   │ Resource                          │ Managed Policy ARN                                                             │
├───┼───────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${HelloWorldFunction/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │
└───┴───────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Do you wish to deploy these changes (y/n)? y
```

와 마찬가지로 앱에 단일 스택이 포함되어 있으므로 AWS CDK 스택을 지정할 필요가 `cdk synth`없습니다.

배포 중 CDK CLI는 스택이 배포될 때 진행 상황 정보를 표시합니다. 완료되면 [AWS CloudFormation 콘솔](https://console.aws.amazon.com/cloudformation/home)로 이동하여 `HelloCdkStack` 스택을 볼 수 있습니다. Lambda 콘솔로 이동하여 `HelloWorldFunction` 리소스를 볼 수도 있습니다.

배포가 완료되면 CDK CLI가 엔드포인트 URL을 출력합니다. 다음 단계를 위해 이 URL을 복사합니다. 다음은 예제입니다.

```
...
HelloCdkStack: deploying... [1/1]
HelloCdkStack: creating CloudFormation changeset...

 ✅  HelloCdkStack

✨  Deployment time: 41.65s

Outputs:
HelloCdkStack.myFunctionUrlOutput = https://<api-id>.lambda-url.<Region>.on.aws/
Stack ARN:
arn:aws:cloudformation:<Region:account-id>:stack/HelloCdkStack/<unique-identifier>

✨  Total time: 44.34s
```

## 10단계:에서 애플리케이션과 상호 작용 AWS
<a name="hello-world-interact"></a>

이 단계에서는 함수 URL을 통해 Lambda 함수를 호출 AWS 하여의 애플리케이션과 상호 작용합니다. URL에 액세스하면 Lambda 함수가 `Hello World!` 메시지를 반환합니다.

함수를 간접적으로 호출하려면 브라우저 또는 명령줄을 통해 함수 URL에 액세스합니다. 다음은 예제입니다.

```
$ curl https://<api-id>.lambda-url.<Region>.on.aws/
"Hello World!"%
```

## 11단계: 애플리케이션 수정
<a name="hello-world-modify"></a>

이 단계에서는 간접적으로 호출 시 Lambda 함수가 반환하는 메시지를 수정합니다. CDK CLI `cdk diff` 명령을 통해 변경 사항을 미리 보고 배포하여 애플리케이션을 업데이트합니다. 그런 다음의 애플리케이션과 상호 작용 AWS 하여 새 메시지를 확인합니다.

다음과 같이 CDK 스택 파일의 `myFunction` 인스턴스를 수정합니다.

**Example**  
`lib/hello-cdk-stack.ts`에 위치합니다.  

```
// ...

export class HelloCdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Modify the Lambda function resource
    const myFunction = new lambda.Function(this, "HelloWorldFunction", {
      runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime
      handler: "index.handler",
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello CDK!'),
          };
        };
      `),
    });

    // ...
  }
}
```
`lib/hello-cdk-stack.js`에 위치합니다.  

```
// ...

class HelloCdkStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Modify the Lambda function resource
    const myFunction = new lambda.Function(this, "HelloWorldFunction", {
      runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime
      handler: "index.handler",
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello CDK!'),
          };
        };
      `),
    });

    // ...

  }
}

module.exports = { HelloCdkStack }
```
`hello_cdk/hello_cdk_stack.py`에 위치합니다.  

```
# ...

class HelloCdkStack(Stack):

  def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
    super().__init__(scope, construct_id, **kwargs)

    # Modify the Lambda function resource
    my_function = _lambda.Function(
      self, "HelloWorldFunction",
      runtime = _lambda.Runtime.NODEJS_20_X, # Provide any supported Node.js runtime
      handler = "index.handler",
      code = _lambda.Code.from_inline(
        """
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello CDK!'),
          };
        };
        """
      ),
    )

    # ...
```
`src/main/java/…​/HelloCdkStack.java`에 위치합니다.  

```
// ...

public class HelloCdkStack extends Stack {
  public HelloCdkStack(final Construct scope, final String id) {
    this(scope, id, null);
  }

  public HelloCdkStack(final Construct scope, final String id, final StackProps props) {
    super(scope, id, props);

    // Modify the Lambda function resource
    Function myFunction = Function.Builder.create(this, "HelloWorldFunction")
      .runtime(Runtime.NODEJS_20_X) // Provide any supported Node.js runtime
      .handler("index.handler")
      .code(Code.fromInline(
        "exports.handler = async function(event) {" +
        " return {" +
        " statusCode: 200," +
        " body: JSON.stringify('Hello CDK!')" +
        " };" +
        "};"))
      .build();

    // ...
  }
}
```

```
// ...

namespace HelloCdk
{
  public class HelloCdkStack : Stack
  {
    internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
    {
      // Modify the Lambda function resource
      var myFunction = new Function(this, "HelloWorldFunction", new FunctionProps
      {
        Runtime = Runtime.NODEJS_20_X, // Provide any supported Node.js runtime
        Handler = "index.handler",
        Code = Code.FromInline(@"
          exports.handler = async function(event) {
            return {
              statusCode: 200,
              body: JSON.stringify('Hello CDK!'),
            };
          };
        "),
      });

      // ...
    }
  }
}
```

```
// ...

type HelloCdkStackProps struct {
  awscdk.StackProps
}

func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack {
  var sprops awscdk.StackProps
  if props != nil {
    sprops = props.StackProps
  }
  stack := awscdk.NewStack(scope, &id, &sprops)

  // Modify the Lambda function resource
  myFunction := awslambda.NewFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.FunctionProps{
    Runtime: awslambda.Runtime_NODEJS_20_X(), // Provide any supported Node.js runtime
    Handler: jsii.String("index.handler"),
    Code: awslambda.Code_FromInline(jsii.String(`
      exports.handler = async function(event) {
        return {
          statusCode: 200,
          body: JSON.stringify('Hello CDK!'),
        };
      };
    `)),
  })

// ...

}
```

현재 코드 변경은 배포된 Lambda 리소스를 직접 업데이트하지 않았습니다. 코드는 리소스의 원하는 상태를 정의합니다. 배포된 리소스를 수정하려면 CDK CLI를 사용하여 원하는 상태를 새 AWS CloudFormation 템플릿으로 합성합니다. 그런 다음 새 CloudFormation 템플릿을 변경 세트로 배포합니다. 변경 세트는 원하는 새 상태에 도달하는 데 필요한 변경 사항만 수행합니다.

변경 사항을 미리 보려면 `cdk diff` 명령을 실행합니다. 다음은 예제입니다.

```
$ cdk diff
Stack HelloCdkStack
Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff)
Resources
[~] AWS::Lambda::Function HelloWorldFunction HelloWorldFunction<unique-identifier>
 └─ [~] Code
     └─ [~] .ZipFile:
         ├─ [-]
                exports.handler = async function(event) {
                    return {
                      statusCode: 200,
                      body: JSON.stringify('Hello World!'),
                    };
                };

         └─ [+]
                exports.handler = async function(event) {
                    return {
                      statusCode: 200,
                      body: JSON.stringify('Hello CDK!'),
                    };
                };


✨  Number of stacks with differences: 1
```

이 차이를 생성하기 위해 CDK CLI는 AWS 계정 계정에서 `HelloCdkStack` 스택에 대한 최신 AWS CloudFormation 템플릿을 쿼리합니다. 그런 다음 최신 템플릿을 앱에서 방금 합성한 템플릿과 비교합니다.

변경 사항을 구현하려면 `cdk deploy` 명령을 실행합니다. 다음은 예제입니다.

```
$ cdk deploy

✨  Synthesis time: 2.12s

HelloCdkStack:  start: Building <unique-identifier>:current_account-current_region
HelloCdkStack:  success: Built <unique-identifier>:current_account-current_region
HelloCdkStack:  start: Publishing <unique-identifier>:current_account-current_region
HelloCdkStack:  success: Published <unique-identifier>:current_account-current_region
HelloCdkStack: deploying... [1/1]
HelloCdkStack: creating CloudFormation changeset...

 ✅  HelloCdkStack

✨  Deployment time: 26.96s

Outputs:
HelloCdkStack.myFunctionUrlOutput = https://<unique-identifier>.lambda-url.<Region>.on.aws/
Stack ARN:
arn:aws:cloudformation:<Region:account-id>:stack/HelloCdkStack/<unique-identifier>

✨  Total time: 29.07s
```

애플리케이션과 상호 작용하려면 [10단계: AWS에서 애플리케이션과 상호 작용](#hello-world-interact)을 반복합니다. 다음은 예제입니다.

```
$ curl https://<api-id>.lambda-url.<Region>.on.aws/
"Hello CDK!"%
```

## 12단계: 애플리케이션 삭제
<a name="hello-world-delete"></a>

이 단계에서는 CDK CLI `cdk destroy` 명령을 사용하여 애플리케이션을 삭제합니다. 이 명령은 생성한 리소스가 포함된 CDK 스택과 연결된 CloudFormation 스택을 삭제합니다.

애플리케이션을 삭제하려면 `cdk destroy` 명령을 실행하고 애플리케이션 삭제 요청을 확인합니다. 다음은 예제입니다.

```
$ cdk destroy
Are you sure you want to delete: HelloCdkStack (y/n)? y
HelloCdkStack: destroying... [1/1]

 ✅  HelloCdkStack: destroyed
```

## 다음 단계
<a name="hello-world-next-steps"></a>

축하합니다\$1 이 자습서를 완료했으며 AWS CDK를 사용하여 AWS 클라우드에서 리소스를 성공적으로 생성, 수정 및 삭제했습니다. 이제 AWS CDK 사용을 시작할 준비가 되었습니다.

원하는 프로그래밍 언어로 AWS CDK를 사용하는 방법에 대한 자세한 내용은 [AWS CDK 라이브러리 작업을](work-with.md) 참조하세요.

추가 리소스는 다음을 참조하세요.
+ [CDK Workshop](https://cdkworkshop.com/)에서 더 복잡한 프로젝트와 관련된 더 심층적인 투어를 시도하세요.
+ [API 참조](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html)를 참조하여 선호하는 AWS 서비스에 사용할 수 있는 CDK 구문을 살펴보세요.
+ [Construct Hub](https://constructs.dev/search?q=&cdk=aws-cdk&cdkver=2&sort=downloadsDesc&offset=0)를 방문하여 AWS 및 기타 사용자가 생성한 구문을 검색합니다.
+  AWS CDK 사용 [예제](https://github.com/aws-samples/aws-cdk-examples)를 살펴봅니다.

 AWS CDK는 오픈 소스 프로젝트입니다. 기여하려면 [AWS 클라우드 개발 키트(AWS CDK)에 기여를 참조하세요](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md).