

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

# AWS CDK 를 사용하여 Step Functions에서 표준 워크플로 생성
<a name="tutorial-lambda-state-machine-cdk"></a>

AWS Cloud Development Kit (AWS CDK) 코드형 인프라(IaC)프레임워크를 사용하여 AWS Lambda 함수가 포함된 AWS Step Functions 상태 머신을 생성할 수 있습니다.

의 CDK지원되는 언어 중 하나를 사용하여 AWS 인프라를 정의합니다. 인프라를 정의한 후 앱을 CloudFormation 템플릿에 합성하고 AWS 계정에 배포합니다.

 이 방법을 사용하여 Lambda 함수가 포함된 Step Functions 상태 머신을 정의한 다음 Step Functions AWS Management Console을 사용하여 상태 머신을 실행합니다.

이 자습서를 시작하기 전에 *AWS Cloud Development Kit (AWS CDK) 개발자 안내서*의 [AWS CDK 시작하기 - 사전 조건](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_prerequisites)의 설명대로 AWS CDK 개발 환경을 설정해야 합니다. 그런 다음 다음 명령으로 AWS CLI에 AWS CDK를 설치합니다.

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

이 자습서에서는 [CloudFormation 를 사용하여 Step Functions에서 워크플로 생성](tutorial-lambda-state-machine-cloudformation.md)와 동일한 결과를 생성합니다. 하지만 이 자습서에서 AWS CDK를 사용하기 위해 IAM 역할을 만들 필요가 없습니다. AWS CDK에서 자동으로 만듭니다. AWS CDK 버전에도 상태 머신에 단계를 추가하는 방법을 설명하는 [Succeed 워크플로 상태](state-succeed.md) 단계가 포함되어 있습니다.

**작은 정보**  
TypeScript와 AWS CDK 함께를 사용하여 Step Functions 워크플로를 시작하는 샘플 서버리스 애플리케이션을 배포하려면 워크숍의 [를 사용하여 배포AWS CDK](https://catalog.workshops.aws/stepfunctions/iac/deploy-with-cdk)를 참조하세요. * AWS Step Functions * 

## 1단계: AWS CDK 프로젝트 설정
<a name="lambda-state-machine-cdk-step-1"></a>

1. 홈 디렉터리 또는 원하는 경우 다른 디렉터리에서 다음 명령을 실행하여 새 AWS CDK 앱을 위한 디렉터리를 만듭니다.
**중요**  
디렉터리 이름을 `step`으로 지정해야 합니다. AWS CDK 애플리케이션 템플릿은 디렉터리 이름을 사용하여 소스 파일과 클래스의 이름을 생성합니다. 다른 이름을 사용하는 경우 앱이 이 자습서와 일치하지 않습니다.

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

   ```
   mkdir step && cd step
   ```

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

   ```
   mkdir step && cd step
   ```

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

   ```
   mkdir step && cd step
   ```

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

   ```
   mkdir step && cd step
   ```

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

   .NET 버전 6.0 이상을 설치했는지 확인합니다. 자세한 내용은 [지원되는 버전](https://dotnet.microsoft.com/en-us/download/dotnet)을 참조하세요.

   ```
   mkdir step && cd step
   ```

------

1. **cdk init** 명령을 사용하여 앱을 초기화합니다. 다음 예제와 같이 원하는 템플릿(“app”)과 프로그래밍 언어를 지정합니다.

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

   ```
   cdk init --language typescript
   ```

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

   ```
   cdk init --language javascript
   ```

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

   ```
   cdk init --language python
   ```

   프로젝트가 초기화되면 프로젝트의 가상 환경을 활성화하고 AWS CDK 기준선 종속성을 설치합니다.

   ```
   source .venv/bin/activate
   python -m pip install -r requirements.txt
   ```

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

   ```
   cdk init --language java
   ```

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

   ```
   cdk init --language csharp
   ```

------

## 2단계: AWS CDK를 사용하여 상태 머신 만들기
<a name="lambda-state-machine-cdk-step-2"></a>

먼저 Lambda 함수와 Step Functions 상태 머신을 정의하는 개별 코드 조각을 살펴보겠습니다. 그런 다음 AWS CDK 앱에 이들을 배치하는 방법을 설명하겠습니다. 마지막으로 이러한 리소스를 합성하고 배포하는 방법을 살펴보겠습니다.

### Lambda 함수를 만들려면
<a name="lambda-state-machine-cdk-create-function"></a>

다음 AWS CDK 코드는 Lambda 함수를 정의하고 소스 코드를 인라인으로 제공합니다.

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

```
const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
    code: lambda.Code.fromInline(`
          exports.handler = (event, context, callback) => {
              callback(null, "Hello World!");
          };
      `),
    runtime: lambda.Runtime.NODEJS_18_X,
    handler: "index.handler",
    timeout: cdk.Duration.seconds(3)
});
```

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

```
const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
    code: lambda.Code.fromInline(`
          exports.handler = (event, context, callback) => {
              callback(null, "Hello World!");
          };
      `),
    runtime: lambda.Runtime.NODEJS_18_X,
    handler: "index.handler",
    timeout: cdk.Duration.seconds(3)
});
```

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

```
hello_function = lambda_.Function(
            self, "MyLambdaFunction",
            code=lambda_.Code.from_inline("""
            exports.handler = (event, context, callback) => {
                callback(null, "Hello World!");
                }"""),
                runtime=lambda_.Runtime.NODEJS_18_X,
                handler="index.handler",
                timeout=Duration.seconds(25))
```

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

```
final Function helloFunction = Function.Builder.create(this, "MyLambdaFunction")
        .code(Code.fromInline(
                "exports.handler = (event, context, callback) => { callback(null, 'Hello World!' );}"))
        .runtime(Runtime.NODEJS_18_X)
        .handler("index.handler")
        .timeout(Duration.seconds(25))
        .build();
```

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

```
var helloFunction = new Function(this, "MyLambdaFunction", new FunctionProps
{
    Code = Code.FromInline(@"`
      exports.handler = (event, context, callback) => {
        callback(null, 'Hello World!');
      }"),
    Runtime = Runtime.NODEJS_12_X,
    Handler = "index.handler",
    Timeout = Duration.Seconds(25)
});
```

------

이 짧은 예제 코드에서 다음을 확인할 수 있습니다.
+ 함수의 논리명(`MyLambdaFunction`)
+ AWS CDK 앱의 소스 코드에 문자열로 임베딩된 함수의 소스 코드
+ 기타 함수 속성(예: 사용할 런타임(Node 18.x)), 함수 진입점 및 제한 시간

### 상태 머신을 생성하려면
<a name="lambda-state-machine-cdk-create"></a>

상태 머신에는 Lambda 함수 작업과 [Succeed 워크플로 상태](state-succeed.md) 상태 등 두 가지 상태가 있습니다. 함수를 사용하려면 함수를 간접적으로 호출하는 Step Functions [Task 워크플로 상태](state-task.md)를 만들어야 합니다. 이 Task 상태는 상태 머신의 첫 번째 단계로 사용됩니다. Task 상태의 `next()` 메서드를 통해 Success 상태가 상태 머신에 추가됩니다. 다음 코드는 먼저 `MyLambdaTask` 함수를 간접적으로 호출한 다음 `next()` 메서드를 사용하여 `GreetedWorld` 성공 상태를 정의합니다.

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

```
const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
  definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
    lambdaFunction: helloFunction
  }).next(new sfn.Succeed(this, "GreetedWorld"))
});
```

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

```
const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
  definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
    lambdaFunction: helloFunction
  }).next(new sfn.Succeed(this, "GreetedWorld"))
});
```

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

```
state_machine = sfn.StateMachine(
                                 self, "MyStateMachine",
                                 definition=tasks.LambdaInvoke(
                                 self, "MyLambdaTask",
                                 lambda_function=hello_function)
                                 .next(sfn.Succeed(self, "GreetedWorld")))
```

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

```
final StateMachine stateMachine = StateMachine.Builder.create(this, "MyStateMachine")
        .definition(LambdaInvoke.Builder.create(this, "MyLambdaTask")
            .lambdaFunction(helloFunction)
            .build()
            .next(new Succeed(this, "GreetedWorld")))
        .build();
```

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

```
var stateMachine = new StateMachine(this, "MyStateMachine", new StateMachineProps {
    DefinitionBody = DefinitionBody.FromChainable(new LambdaInvoke(this, "MyLambdaTask", new LambdaInvokeProps
    {
        LambdaFunction = helloFunction
    })
    .Next(new Succeed(this, "GreetedWorld")))
});
```

------

### AWS CDK 앱을 빌드하고 배포하기
<a name="lambda-state-machine-cdk-app"></a>

새롭게 만든 AWS CDK 프로젝트에서 스택 정의가 포함된 파일을 다음 예제와 비슷하게 편집합니다. 이전 섹션에서 살펴본 Lambda 함수와 Step Functions 상태 머신의 정의를 이해합니다.

1. 다음 예제와 같이 스택을 업데이트합니다.

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

   다음 코드로 `lib/step-stack.ts`를 업데이트합니다.

   ```
   import * as cdk from 'aws-cdk-lib';
   import * as lambda from 'aws-cdk-lib/aws-lambda';
   import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
   import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
   
   export class StepStack extends cdk.Stack {
     constructor(app: cdk.App, id: string) {
       super(app, id);
   
       const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
         code: lambda.Code.fromInline(`
             exports.handler = (event, context, callback) => {
                 callback(null, "Hello World!");
             };
         `),
         runtime: lambda.Runtime.NODEJS_18_X,
         handler: "index.handler",
         timeout: cdk.Duration.seconds(3)
       });
   
       const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
         definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
           lambdaFunction: helloFunction
         }).next(new sfn.Succeed(this, "GreetedWorld"))
       });
     }
   }
   ```

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

   다음 코드로 `lib/step-stack.js`를 업데이트합니다.

   ```
   import * as cdk from 'aws-cdk-lib';
   import * as lambda from 'aws-cdk-lib/aws-lambda';
   import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
   import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
   
   export class StepStack extends cdk.Stack {
     constructor(app, id) {
       super(app, id);
   
       const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
         code: lambda.Code.fromInline(`
             exports.handler = (event, context, callback) => {
                 callback(null, "Hello World!");
             };
         `),
         runtime: lambda.Runtime.NODEJS_18_X,
         handler: "index.handler",
         timeout: cdk.Duration.seconds(3)
       });
   
       const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
         definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
           lambdaFunction: helloFunction
         }).next(new sfn.Succeed(this, "GreetedWorld"))
       });
     }
   }
   ```

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

   다음 코드로 `step/step_stack.py`를 업데이트합니다.

   ```
   from aws_cdk import (
       Duration,
       Stack,
       aws_stepfunctions as sfn,
       aws_stepfunctions_tasks as tasks,
       aws_lambda as lambda_
   )
   class StepStack(Stack):
   
       def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
           super().__init__(scope, construct_id, **kwargs)
   
           hello_function = lambda_.Function(
               self, "MyLambdaFunction",
               code=lambda_.Code.from_inline("""
               exports.handler = (event, context, callback) => {
                   callback(null, "Hello World!");
                   }"""),
                   runtime=lambda_.Runtime.NODEJS_18_X,
                   handler="index.handler",
                   timeout=Duration.seconds(25))
   
           state_machine = sfn.StateMachine(
               self, "MyStateMachine",
               definition=tasks.LambdaInvoke(
               self, "MyLambdaTask",
               lambda_function=hello_function)
               .next(sfn.Succeed(self, "GreetedWorld")))
   ```

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

   다음 코드로 `src/main/java/com.myorg/StepStack.java`를 업데이트합니다.

   ```
   package com.myorg;
   
   import software.constructs.Construct;
   import software.amazon.awscdk.Stack;
   import software.amazon.awscdk.StackProps;
   import software.amazon.awscdk.Duration;
   import software.amazon.awscdk.services.lambda.Code;
   import software.amazon.awscdk.services.lambda.Function;
   import software.amazon.awscdk.services.lambda.Runtime;
   import software.amazon.awscdk.services.stepfunctions.StateMachine;
   import software.amazon.awscdk.services.stepfunctions.Succeed;
   import software.amazon.awscdk.services.stepfunctions.tasks.LambdaInvoke;
   
   public class StepStack extends Stack {
       public StepStack(final Construct scope, final String id) {
           this(scope, id, null);
       }
   
       public StepStack(final Construct scope, final String id, final StackProps props) {
           super(scope, id, props);
   
           final Function helloFunction = Function.Builder.create(this, "MyLambdaFunction")
                   .code(Code.fromInline(
                           "exports.handler = (event, context, callback) => { callback(null, 'Hello World!' );}"))
                   .runtime(Runtime.NODEJS_18_X)
                   .handler("index.handler")
                   .timeout(Duration.seconds(25))
                   .build();
   
           final StateMachine stateMachine = StateMachine.Builder.create(this, "MyStateMachine")
                   .definition(LambdaInvoke.Builder.create(this, "MyLambdaTask")
                           .lambdaFunction(helloFunction)
                           .build()
                           .next(new Succeed(this, "GreetedWorld")))
                   .build();
       }
   }
   ```

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

   다음 코드로 `src/Step/StepStack.cs`를 업데이트합니다.

   ```
   using Amazon.CDK;
   using Constructs;
   using Amazon.CDK.AWS.Lambda;
   using Amazon.CDK.AWS.StepFunctions;
   using Amazon.CDK.AWS.StepFunctions.Tasks;
   
   namespace Step
   {
       public class StepStack : Stack
       {
           internal StepStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
           {
               var helloFunction = new Function(this, "MyLambdaFunction", new FunctionProps
               {
                   Code = Code.FromInline(@"exports.handler = (event, context, callback) => {
                       callback(null, 'Hello World!');
                   }"),
                   Runtime = Runtime.NODEJS_18_X,
                   Handler = "index.handler",
                   Timeout = Duration.Seconds(25)
               });
   
               var stateMachine = new StateMachine(this, "MyStateMachine", new StateMachineProps
               {
                   DefinitionBody = DefinitionBody.FromChainable(new LambdaInvoke(this, "MyLambdaTask", new LambdaInvokeProps
                   {
                       LambdaFunction = helloFunction
                   })
                   .Next(new Succeed(this, "GreetedWorld")))
               });
           }
       }
   }
   ```

------

1. 소스 파일을 저장한 다음 앱의 기본 디렉터리에서 `cdk synth` 명령을 실행합니다.

   AWS CDK에서 앱을 실행하고 앱에서 CloudFormation 템플릿을 합성합니다. 그러면 AWS CDK에서 템플릿을 표시합니다.
**참고**  
TypeScript를 사용하여 AWS CDK 프로젝트를 만든 경우 `cdk synth` 명령을 실행하면 다음 오류가 반환될 수 있습니다.  

   ```
   TSError: ⨯ Unable to compile TypeScript:
   bin/step.ts:7:33 - error TS2554: Expected 2 arguments, but got 3.
   ```
다음 예제와 같이 `bin/step.ts` 파일을 수정하여 이 오류를 해결합니다.  

   ```
   #!/usr/bin/env node
   import 'source-map-support/register';
   import * as cdk from 'aws-cdk-lib';
   import { StepStack } from '../lib/step-stack';
   
   const app = new cdk.App();
   new StepStack(app, 'StepStack');
   app.synth();
   ```

1. Lambda 함수와 Step Functions 상태 머신을 AWS 계정에 배포하려면 `cdk deploy`를 실행합니다. 가 AWS CDK 생성한 IAM 정책을 승인하라는 메시지가 표시됩니다.

## 3단계: 상태 머신 실행 시작
<a name="lambda-state-machine-cdk-step-3"></a>

상태 머신을 만든 후에 실행을 시작할 수 있습니다.

### 상태 머신 실행을 시작하려면
<a name="to-start-the-state-machine-execution"></a>

1. [Step Functions 콘솔](https://console.aws.amazon.com/states/home)을 열고 AWS CDK을 사용하여 만든 상태 머신의 이름을 선택합니다.

1. 상태 머신 페이지에서 **실행 시작**을 선택합니다.

   **실행 시작** 대화 상자가 표시됩니다.

1. (선택 사항) 생성된 기본값을 재정의하려면 사용자 지정 실행 이름을 입력합니다.
**비 ASCII 이름 및 로깅**  
Step Functions는 비 ASCII 문자가 포함된 상태 머신, 실행, 활동 및 레이블 이름을 허용합니다. 이러한 문자는 Amazon CloudWatch에서 데이터 로깅을 방지하므로 Step Functions 지표를 추적할 수 있도록 ASCII 문자만 사용하는 것이 좋습니다.

1. **실행 시작**을 선택합니다.

   상태 머신 실행이 시작되고 실행 중인 실행을 보여주는 새로운 페이지가 표시됩니다.

1. Step Functions 콘솔은 실행 ID가 제목인 페이지로 이동합니다. 이 페이지를 *실행 세부 정보* 페이지라고 합니다. 실행이 진행되는 동안 또는 완료된 후에 이 페이지에서 실행 결과를 검토할 수 있습니다.

   실행 결과를 검토하려면 **그래프 보기**에서 개별 상태를 선택한 다음 [단계 세부 정보](concepts-view-execution-details.md#exec-details-intf-step-details) 창에서 개별 탭을 선택하여 입력, 출력 및 정의가 포함된 각 상태의 세부 정보를 각각 봅니다. *실행 세부 정보* 페이지에서 볼 수 있는 실행 정보에 대한 자세한 내용은 [실행 세부 정보 개요](concepts-view-execution-details.md#exec-details-interface-overview) 섹션을 참조하세요.

## 4단계: 정리
<a name="lambda-state-machine-cdk-step-4"></a>

상태 머신을 테스트한 후에는 상태 머신과 관련 Lambda 함수를 모두 제거하여 AWS 계정에서 리소스를 확보하는 것이 좋습니다. 앱의 기본 디렉터리에서 `cdk destroy` 명령을 실행하여 상태 머신을 제거합니다.

## 다음 단계
<a name="lambda-state-machine-cdk-next-steps"></a>

를 사용하여 AWS 인프라를 개발하는 방법에 대한 자세한 내용은 [AWS CDK 개발자 안내서](https://docs.aws.amazon.com/cdk/v2/guide/home.html)를 AWS CDK참조하세요.

선택한 언어로 AWS CDK 앱을 작성하는 방법에 대한 내용은 다음을 참조하세요.

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

 [TypeScript에서 AWS CDK 사용](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-typescript.html)용 

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

 [JavaScript에서 AWS CDK 사용](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-javascript.html) 

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

 [Python에서 AWS CDK 사용](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-python.html) 

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

 [Java에서 AWS CDK 사용](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-java.html) 

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

 [C\$1에서 AWS CDK 사용](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-csharp.html) 

------

이 자습서에서 사용되는 AWS Construct Library 모듈에 대한 자세한 내용은 다음 AWS CDK API 참조 개요를 참조하세요.
+  [aws-lambda](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html) 
+  [aws-stepfunctions](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_stepfunctions-readme.html) 
+  [aws-stepfunctions-tasks](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_stepfunctions_tasks-readme.html) 