자습서: 첫 번째 AWS CDK 앱 생성 - AWS Cloud Development Kit (AWS CDK) v2

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

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

자습서: 첫 번째 AWS CDK 앱 생성

첫 번째 CDK 앱을 개발하고, AWS 환경을 부트스트래핑하고, AWS에 애플리케이션을 배포하기 위해 AWS CDK Command Line Interface(AWS CDK CLI)를 사용하여 AWS Cloud Development Kit (AWS CDK) 사용을 시작하세요.

사전 조건

이 자습서를 시작하기 전에 AWS CDK 시작하기의 단계를 완료하세요.

이 자습서 소개

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

이 자습서를 통해 다음을 수행합니다.

  • 프로젝트 생성 - CDK CLI cdk init 명령을 사용하여 CDK 프로젝트를 생성합니다.

  • AWS 환경 구성 - 애플리케이션을 배포할 AWS 환경을 구성합니다.

  • AWS 환경 부트스트래핑 - CDK CLI cdk bootstrap 명령으로 부트스트래핑하여 AWS 환경을 배포할 준비를 합니다.

  • 앱 개발 - AWS Construct 라이브러리의 구문을 사용하여 Lambda 함수 및 Lambda 함수 URL 리소스를 정의합니다.

  • 배포를 위한 앱 준비 - CDK CLI를 사용하여 앱을 빌드하고 AWS CloudFormation 템플릿을 합성합니다.

  • 앱 배포 - CDK CLI cdk deploy 명령을 사용하여 애플리케이션을 배포하고 AWS 리소스를 프로비저닝합니다.

  • 애플리케이션과 상호 작용 - 배포된 Lambda 함수를 간접적으로 호출하고 응답을 수신하여 AWS에서 해당 함수와 상호 작용합니다.

  • 앱 수정 - Lambda 함수를 수정하고 배포하여 변경 사항을 구현합니다.

  • 앱 삭제 - CDK CLI cdk destroy 명령을 사용하여 생성한 모든 리소스를 삭제합니다.

1단계: CDK 프로젝트 생성

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

CDK 프로젝트를 생성하려면 다음을 수행하세요.
  1. 원하는 시작 디렉터리에서 생성하고 hello-cdk라는 디렉터리로 이동합니다.

    $ mkdir hello-cdk && cd hello-cdk
    중요

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

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

    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#
    $ cdk init app --language csharp

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

    Go
    $ cdk init app --language go

    앱이 생성된 후에는 다음 명령도 입력하여 앱에 필요한 AWS Construct 라이브러리 모듈을 설치합니다.

    $ go get

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

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

프로젝트 초기화 중 CDK CLI는 단일 CDK 스택이 포함된 CDK 앱을 생성합니다. CDK 앱 인스턴스는 App 구문을 사용하여 생성됩니다. 다음은 CDK 애플리케이션 파일에서 이 코드의 일부입니다.

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', { });
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', { });
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",) 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() .build()); app.synth(); } }
C#

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(); } } }
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) } // ...

CDK 스택은 Stack 구문을 사용하여 생성됩니다. 다음은 CDK 스택 파일에서 이 코드의 일부입니다.

TypeScript

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 } }
JavaScript

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 }
Python

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
Java

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 } }
C#

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 } } }
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" ) 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 환경 구성

이 단계에서는 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
  2. 명명된 프로파일을 사용하려면 --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
  2. 명명된 프로파일을 사용하려면 --profile 옵션을 사용하여 프로파일 이름을 입력합니다.

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

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

CDK 스택의 환경을 구성하려면 다음을 수행하세요.
  • 애플리케이션 파일 에서 Stack 구문의 env 속성을 사용하여 환경을 구성합니다. 다음은 그 예제입니다.

    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#

    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 환경 부트스트래핑

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

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

$ cdk bootstrap

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

4단계: CDK 앱 빌드

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

TypeScript
$ npm run build > hello-cdk@0.1.0 build > tsc
JavaScript

빌드 단계는 필요하지 않습니다.

Python

빌드 단계는 필요하지 않습니다.

Java
$ mvn compile -q

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

C#
$ dotnet build src

또는 Visual Studio에서 F6을 누릅니다.

Go
$ go build

5단계: 앱의 CDK 스택 나열

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

$ cdk list HelloCdkStack

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

6단계: Lambda 함수 정의

이 단계에서는 AWS Construct 라이브러리에서 aws_lambda 모듈을 가져오고 Function L2 구문을 사용합니다.

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

TypeScript

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!'), }; }; `), }); } }
JavaScript

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 }
Python

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!'), }; }; """ ), )
Java

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(); } }
C#

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!'), }; }; "), }); } } }
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" // 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 리소스를 정의하는 모든 구문은 스택 범위 내에서 생성됩니다. 구문 내부에 구문을 정의하여 계층 구조(트리)를 생성할 수 있습니다. 여기에서 대부분의 경우 범위는 this(Python: self)입니다.

  • Id – AWS CDK 앱 내 Function의 구문 ID입니다. 이 ID와 스택 내 함수의 위치를 기반으로 하는 해시는 배포 중 함수를 고유하게 식별합니다. AWS CDK는 앱에서 구문을 업데이트하고 배포된 리소스를 업데이트하기 위해 다시 배포할 때도 이 ID를 참조합니다. 여기서 구문 ID는 HelloWorldFunction입니다. 함수에는 functionName 속성으로 지정된 이름이 있을 수도 있습니다. 이는 ID 구문과 다릅니다.

  • props - 함수의 속성을 정의하는 값 번들입니다. 여기서 runtime, handlercode 속성을 정의합니다.

    속성은 AWS CDK에서 지원하는 언어에서 다르게 표시됩니다.

    • TypeScript 및 JavaScript에서 props는 단일 인수이며 원하는 속성이 포함된 객체를 전달합니다.

    • Python에서 props는 키워드 인수로 전달됩니다.

    • Java에서는 props를 전달하기 위해 Builder가 제공됩니다. 두 가지가 있습니다. 하나는 FunctionProps용이고, 다른 하나는 Function용으로, 이를 사용하면 한 단계로 구문과 해당 props 객체를 빌드할 수 있습니다. 이 코드는 후자를 사용합니다.

    • C#에서는 FunctionProps 객체 이니셜라이저를 사용하여 객체를 인스턴스화하고 이를 세 번째 파라미터로 전달합니다.

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

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

7단계: Lambda 함수 URL 정의

이 단계에서는 Function 구문의 addFunctionUrl 도우미 메서드를 사용하여 Lambda 함수 URL을 정의합니다. 배포 시 이 URL의 값을 출력하려면 CfnOutput 구문을 사용하여 AWS CloudFormation 출력을 생성합니다.

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

TypeScript

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, }) } }
JavaScript

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 }
Python

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)
Java

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(); } }
C#

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 }); } } }
Go

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단계: 애플리케이션 삭제에 따라 이러한 리소스를 삭제합니다.

8단계: CloudFormation 템플릿 합성

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

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

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

템플릿을 합성하기 전에 필요에 따라 애플리케이션을 빌드하여 구문 및 유형 오류를 포착할 수 있습니다. 지침은 4단계: CDK 앱 빌드 단원을 참조하십시오.

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 템플릿의 예제 출력입니다.

Resources: HelloWorldFunctionServiceRoleunique-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 HelloWorldFunctionunique-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: - HelloWorldFunctionServiceRoleunique-identifier - Arn Runtime: nodejs20.x DependsOn: - HelloWorldFunctionServiceRoleunique-identifier Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/Resource HelloWorldFunctionFunctionUrlunique-identifier: Type: AWS::Lambda::Url Properties: AuthType: NONE TargetFunctionArn: Fn::GetAtt: - HelloWorldFunctionunique-identifier - Arn Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/FunctionUrl/Resource HelloWorldFunctioninvokefunctionurlunique-identifier: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunctionUrl FunctionName: Fn::GetAtt: - HelloWorldFunctionunique-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: - HelloWorldFunctionFunctionUrlunique-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 사용량에 대한 통찰력을 얻고 이를 개선할 방법을 찾습니다. 버전 보고를 옵트아웃하는 방법을 비롯한 자세한 내용은 버전 보고 섹션을 참조하세요.

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

9단계: CDK 스택 배포

이 단계에서는 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

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

배포 중 CDK CLI는 스택이 배포될 때 진행 상황 정보를 표시합니다. 완료되면 AWS CloudFormation 콘솔로 이동하여 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에서 애플리케이션과 상호 작용

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

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

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

11단계: 애플리케이션 수정

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

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

TypeScript

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!'), }; }; `), }); // ...
JavaScript

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 }
Python

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!'), }; }; """ ), ) # ...
Java

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(); // ... } }
C#

// ... 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!'), }; }; "), }); // ... } } }
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) // 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 HelloWorldFunctionunique-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에서 애플리케이션과 상호 작용을 반복합니다. 다음은 그 예제입니다.

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

12단계: 애플리케이션 삭제

이 단계에서는 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

다음 단계

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

선호하는 프로그래밍 언어로 AWS CDK를 사용하는 방법에 대해 자세히 알아보려면 AWS CDK 라이브러리 작업 섹션을 참조하세요.

추가 리소스는 다음을 참조하세요.

  • CDK Workshop에서 더 복잡한 프로젝트와 관련된 더 심층적인 투어를 시도하세요.

  • 즐겨 사용하는 AWS 서비스에 사용할 수 있는 CDK 구문을 살펴보려면 API 참조를 확인하세요.

  • AWS와 기타 업체에서 생성한 구문을 살펴보려면 Construct Hub를 방문하세요.

  • AWS CDK 사용 를 살펴보세요.

AWS CDK는 오픈 소스 프로젝트입니다. 기여하려면 Contributing to the AWS Cloud Development Kit (AWS CDK)를 참조하세요.