๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๊ฐœ๋ฐœ/AWS

[AWS] AWS CDK ์‹œ์ž‘ํ•˜๊ธฐ (1) | Javascript, AWS Configure, CDK Init, CDK deploy, lambda, api gateway

๋ฐ˜์‘ํ˜•

 

๐Ÿ“„ ๋ชฉ์ฐจ

     

    1. AWS & CDK ์„ค์ •

    AWS Configure

    ๊ธฐ์กด์— aws configure๋ฅผ ํ†ตํ•ด AWS์™€ ๋กœ์ปฌ์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋‹ค๋ฉด ๊ฑด๋„ˆ๋›ฐ์–ด๋„ ๋ฉ๋‹ˆ๋‹ค.
    aws configure list

     

    $ aws configure
    AWS Access Key ID: [aws ์—์„œ IAM์ƒ์„ฑํ•˜์—ฌ ์ž…๋ ฅ]
    AWS Secret Access Key : [aws ์—์„œ IAM์ƒ์„ฑํ•˜์—ฌ ์ž…๋ ฅ]
    Default region name [None]: ap-northeast-2
    Default output format [None]: json

     

    aws-cdk ์„ค์น˜

    • npm์„ ํ†ตํ•ด aws-cdk ์„ค์น˜
    $ sudo npm i -g aws-cdk
    $ cdk version # 2.15.0 (build 151055e)

     

    2. CDK ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

    cdk init

    • cdk init ์ปค๋งจ๋“œ๋กœ cdkํ”„๋กœ์ ํŠธ๊ฐ€ ์ƒ์„ฑ
    $ cdk init sample-app --language typescript

     

    vsCode๋กœ sample-app ํ”„๋กœ์ ํŠธ๋ฅผ ์—ด์–ด๋ณด๋ฉด ํŒŒ์ผ ๊ตฌ์กฐ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

     

    3.  ์Šคํƒ์— lambda, API GW ์ถ”๊ฐ€

    ์Šคํƒ์ดˆ๊ธฐํ™” 

    lib ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋ณด๋ฉด ์ž‘์„ฑ๋˜์–ด ์žˆ๋Š” stack์ด ์žˆ์Šต๋‹ˆ๋‹ค.

    sample-app์„ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜์˜€๊ธฐ์— queue ๋“ฑ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋“ค์–ด๊ฐ€์žˆ๋Š” ์ฝ”๋“œ๋“ค์ด ์žˆ์„ํ…๋ฐ,

    ์›๋ž˜ ์žˆ๋˜ ์ฝ”๋“œ๋ฅผ ๋ชจ๋‘ ๋‚ ๋ฆฌ๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. 

    // lib/sample_cdk-stack.ts
    
    import { Duration, Stack, StackProps } from 'aws-cdk-lib';
    import { Construct } from 'constructs';
    
    export class SampleCdkStack extends Stack {
      constructor(scope: Construct, id: string, props?: StackProps) {
        super(scope, id, props);
      }
    }

     

    ๋žŒ๋‹ค ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ

    • root๋””๋ ‰ํ† ๋ฆฌ์— (bin, lib์™€ ๊ฐ™์€ ๊ณ„์ธต์—) lambda ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ
    • lambda ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด hello.js ํŒŒ์ผ ์ƒ์„ฑ 

    • hello.js์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑ 
    exports.handler = async function(event) {
        console.log('requests: ', JSON.stringify(event, undefined, 2))
        return {
            statusCode: 200,
            headers: { 'Content-Type' : 'text/plain' },
            body: `hello! ${event.path}\n`
        }
    }

     

    lambda contruct library ์„ค์น˜

    • ์•„๋ž˜ ์ปค๋งจ๋“œ๋กœ lambda construct libaray ์„ค์น˜
    • ์ด๊ฒŒ ์„ค์น˜๋˜์–ด ์žˆ์–ด์•ผ ์ž‘์„ฑํ•œ lambda ์ฝ”๋“œ๋ฅผ cdk์—์„œ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์Œ 
    $ npm install @aws-cdk/aws-lambda

     

     

    stack์— ๋žŒ๋‹ค ์ •์˜

    stack์ด ์ •์˜๋˜์–ด ์žˆ๋Š” ํŒŒ์ผ(lib/~~.stack.ts)์— lambda๋ฅผ ์ •์˜ํ•ด์ค๋‹ˆ๋‹ค.

    // lib/sample_cdk-stack.ts
    import { Duration, Stack, StackProps } from 'aws-cdk-lib';
    import * as lambda from 'aws-cdk-lib/aws-lambda';
    import { Construct } from 'constructs';
    
    export class SampleCdkStack extends Stack {
      constructor(scope: Construct, id: string, props?: StackProps) {
        super(scope, id, props);
    
        // defines an AWS Lambda resource
        const hello = new lambda.Function(this, 'HelloHandler', {
          runtime: lambda.Runtime.NODEJS_14_X,    // execution environment
          code: lambda.Code.fromAsset('lambda'),  // code loaded from "lambda" directory
          handler: 'hello.handler'                // file is "hello", function is "handler"
        });
      }
    }

     

     

    stack์— api gateway ์ถ”๊ฐ€ ์ •์˜

    api gateway ๋„ stack ์— ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค. 

    // lib/sample_cdk-stack.ts
    import { Duration, Stack, StackProps } from 'aws-cdk-lib';
    import * as lambda from 'aws-cdk-lib/aws-lambda';
    import * as apigw from 'aws-cdk-lib/aws-apigateway';
    import { Construct } from 'constructs';
    
    export class SampleCdkStack extends Stack {
      constructor(scope: Construct, id: string, props?: StackProps) {
        super(scope, id, props);
    
        // defines an AWS Lambda resource
        const hello = new lambda.Function(this, 'HelloHandler', {
          runtime: lambda.Runtime.NODEJS_14_X,    // execution environment
          code: lambda.Code.fromAsset('lambda'),  // code loaded from "lambda" directory
          handler: 'hello.handler'                // file is "hello", function is "handler"
        });
    
        // defines an API Gateway REST API resource backed by our "hello" function.
        new apigw.LambdaRestApi(this, 'Endpoint', {
          handler: hello
        });
      }
    }

     

     

    4. AWS์— ๋ฐฐํฌ

    bootstrap stack ์„ค์น˜ (cdk bootstrap)

    AWS CDK ์•ฑ์„ ์ฒ˜์Œ์œผ๋กœ ๋””ํด๋กœ์ด ํ•  ๋•Œ๋Š”, "bootstrap stack์„ ์„ค์น˜ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    • bootstrap stack ์„ค์น˜ 
    $ cdk bootstrap

     

    cdk synth

    cdk synth ์ปค๋งจ๋“œ๋Š” cdkํ”„๋กœ์ ํŠธ ์ฝ”๋“œ๋ฅผ cloudFormation ํ…œํ”Œ๋ฆฟ์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ค๋‹ˆ๋‹ค. 

    • cdk synth ์ปค๋งจ๋“œ๋ฅผ ํ†ตํ•ด cloudFormation์ด ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑ๋  ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ
    • deploy๋ฅผ ์œ„ํ•ด ๊ผญ ํ•„์š”ํ•œ ๋‹จ๊ณ„๋Š” ์•„๋‹˜ 
    $ cdk synth
    Resources:
      CdkworkshopQueue18864164:
        Type: AWS::SQS::Queue
        Properties:
          VisibilityTimeout: 300
        Metadata:
          aws:cdk:path: cdkworkshop/CdkworkshopQueue/Resource
      CdkworkshopQueuePolicy78D5BF45:
        Type: AWS::SQS::QueuePolicy
        Properties:
          PolicyDocument:
            Statement:
              - Action: sqs:SendMessage
                Condition:
                  ArnEquals:
                    aws:SourceArn:
                      Ref: CdkworkshopTopic58CFDD3D
                Effect: Allow
                Principal:
                  Service: sns.amazonaws.com
                Resource:
                  Fn::GetAtt:
                    - CdkworkshopQueue18864164
                    - Arn
            Version: "2012-10-17"
          Queues:
            - Ref: CdkworkshopQueue18864164
        Metadata:
          aws:cdk:path: cdkworkshop/CdkworkshopQueue/Policy/Resource
      CdkworkshopQueuecdkworkshopCdkworkshopTopic7642CC2FCF70B637:
        Type: AWS::SNS::Subscription
        Properties:
          Protocol: sqs
          TopicArn:
            Ref: CdkworkshopTopic58CFDD3D
          Endpoint:
            Fn::GetAtt:
              - CdkworkshopQueue18864164
              - Arn
        Metadata:
          aws:cdk:path: cdkworkshop/CdkworkshopQueue/cdkworkshopCdkworkshopTopic7642CC2F/Resource
      CdkworkshopTopic58CFDD3D:
        Type: AWS::SNS::Topic
        Metadata:
          aws:cdk:path: cdkworkshop/CdkworkshopTopic/Resource
      CDKMetadata:
        Type: AWS::CDK::Metadata
        Properties:
          Modules: aws-cdk=1.18.0,jsii-runtime=Python/3.7.3

     

    cdk deploy

    cdk deploy ์ปค๋งจ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ํ˜„์žฌ๊นŒ์ง€ ์ž‘์„ฑํ•œ ์Šคํƒ์ด aws์— ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค. 

    $ cdk deploy

     

    ๋””ํ”Œ๋กœ์ด๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์œ„์ฒ˜๋Ÿผ api gateway url์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด url๋กœ ๋“ค์–ด๊ฐ€๋ณด๋ฉด api gateway -> lambda๋ฅผ ํ†ตํ•ด response๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

     

     

    AWS ๊ณ„์ •์—์„œ๋„ ๋ฆฌ์†Œ์Šค๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

    AWS > cloudFormation์— ๊ฐ€๋ณด๋‹ˆ ์ž˜ ๋“ค์–ด๊ฐ€ ์žˆ๋„ค์š”

     

    AWS > Lambda์—๋„ hello handler๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

     

    ํ˜น์‹œ ๋””ํ”Œ๋กœ์ด๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋˜์—ˆ๋Š”๋ฐ, ๊ณ„์ •์—์„œ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋ฉด,

    • ๋‹ค๋ฅธ ๊ณ„์ •๊ณผ ์—ฐ๊ฒฐ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด๋ณด์„ธ์š”
    • ๋‹ค๋ฅธ ๋ฆฌ์ „์— ๋ฐฐํฌํ•˜์˜€๋Š”์ง€ ํ™•์ธํ•ด๋ณด์„ธ์š”

    aws configure list๋ฅผ ํ†ตํ•ด ๋””ํดํŠธ๋กœ ์„ค์ •๋œ aws ๊ณ„์ • ๋ฐ ๋ฆฌ์ „์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

     

     

     

    ์ฐธ๊ณ )

    https://towardsthecloud.com/how-to-set-up-aws-cdk

    https://cdkworkshop.com/20-typescript/20-create-project/500-deploy.html

    ๋ฐ˜์‘ํ˜•