반응형

CI/CD 구축을 위한 단계

  0. ECS fargate 생성 (Cluster, Service, task-definition, task)

1-1. Bitbucket에 코드 업로드 (git)

1-2. Bitbucket <-> slack 연동 (PR 알람 노티를 위함)

2-1. Bitbucket <-> AWS API Gateway 연동 with Webhook

2-2. API gateway -> Lambda 호출 

3. Lambda -> S3로 패키지 업로드

4. AWS Codepipeline: S3 -> Codebuild + ECR 연동

5. Codebuild -> Deploy(ECS fargate)

6. ECS <-> LB(ALB) 연동하여 동작 테스트 


이제 bitbucket으로부터 /POST가 올 때 lambda까지 호출하는 절차를 구현했으므로,

Lambda에서 S3로 코드를 올리는 함수를 구현해보자.

 

로컬에서 사용할 함수들을 간단히 정의한 후, npm init -y으로 package.json을 생성했고

index.js와 pkg.json, node_modules를 zip으로 묶어 lambda에 upload 했다.

const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const crypto = require('crypto');
const axios = require('axios');

exports.handler = async (event) => {
    try {
        console.log(`Incoming event: ${JSON.stringify(event)}`);
        const eventBody = JSON.parse(event.body);

일단 사용할 함수들을 정의하고, event를 JSON.stringiy로 찍어본다.

로그를 보면 아래와 같은 event가 들어온다.

 

2022-05-26T22:51:32.181Z 399fc240-aa51-411b-8537-26dbe8d6d578 INFO
{
   "resource":"/",
   "path":"/",
   "httpMethod":"POST",
   "headers":{
      "Accept":"*/*",
      "Content-Type":"application/json; charset=UTF-8",
      "Host":"ㅁㄴㅇㄹㅁㄴxecute-api.ap-northeast-2.amazonaws.com",
      "User-Agent":"Atlassian HttpClient 1.1.0 / Bitbucket-5.10.0 (5010000) / Default",
      "Via":"1.1 localhost (Apache-HttpClient/4.5.5 (cache))",
      "X-Amzn-Trace-Id":"Root=1-62900473-046a3026764d32b66cc4f0c5",
      ”X-Event-Key":"pr:comment:edited",   
      "X-Forwarded-For":"ㅁㄴㅇㄹ.201",
      "X-Forwarded-Port":"443",
      "X-Forwarded-Proto":"https",
      "X-Request-Id":"ㅁㄴㅇㄹㅁ7ffac28c454d"
      "X-Hub-Signature": "sha256=ㅁㄴㅇㄹㅁㅁㄴㅇㄹbㅁㅇㄹa20b",
   },
   "multiValueHeaders":{
      "Accept":[
         "*/*"
      ],
      "Content-Type":[
         "application/json; charset=UTF-8"
      ],
      "Host":[
         "ㅁㄴㄹㅇs.com"
      ],
      "User-Agent":[
         "Atlassian HttpClient 1.1.0 / Bitbucket-5.10.0 (5010000) / Default"
      ],
      "Via":[
         "1.1 localhost (Apache-HttpClient/4.5.5 (cache))"
      ],
      "X-Amzn-Trace-Id":[
         "Root=ㅁㄴㅇㄹㄴㅇㄹㅁㄴㄹㅇ66cc4f0c5"
      ],
      "X-Event-Key":[
         "pr:comment:edited"
      ],
      "X-Forwarded-For":[
         "ㅁㄴㄹㅇㅇㅇ1"
      ],
      "X-Forwarded-Port":[
         "443"
      ],
      "X-Forwarded-Proto":[
         "https"
      ],
      "X-Request-Id":[
         "ㅁㄴㄹㅁ8c454d"
      ]
   },
   "queryStringParameters":null,
   "multiValueQueryStringParameters":null,
   "pathParameters":null,
   "stageVariables":null,
   "requestContext":{
      "resourceId":"ㅁㄹㅇㄹak",
      "resourcePath":"/",
      "httpMethod":"POST",
      "extendedRequestId":"SㅁㄴㄹㅇTA=",
      "requestTime":"26/May/2022:22:51:31 +0000",
      "path":"/prod/",
      "accountId":"ㅁㄴㅇㄹㅁㄴ",
      "protocol":"HTTP/1.1",
      "stage":"prod",
      "domainPrefix":"ㅁㄴㅇㅇㄹh",
      "requestTimeEpoch":ㅁㅇㄹ353,
      "requestId":"ㅁㄴㄹㅇㄹ15ㅁㅇㄹb672d3f5ee",
      "identity":{
         "cognitoIdentityPoolId":null,
         "accountId":null,
         "cognitoIdentityId":null,
         "caller":null,
         "sourceIp":"ㅁㄹㄴㅇㅁㅇㄴ",
         "principalOrgId":null,
         "accessKey":null,
         "cognitoAuthenticationType":null,
         "cognitoAuthenticationProvider":null,
         "userArn":null,
         "userAgent":"Atlassian HttpClient 1.1.0 / Bitbucket-ㅁㄴㄹㅇ(ㅁㄴㄹ) / Default",
         "user":null
      },
      "domainName":"ㅁㄹㄹㅇ2.amazonaws.com",
      "apiId":"ㅁㄹㄴㅇvㅁㄴㄹh"
   },
   "body":"{\"eventKey\":\"pr:comment:edited\",\"date\":\"2022-05-27T07:51:31+0900\",\"actor\":{\"name\":\"jane\",\"emailAddress\":\"

중략.

 

이를 가지고, 헤더를 정규화해주고 (key를 소문자화) 인증서도 체크하고, 코드도 다운받고, 이를 s3로도 올린다.

코드는 아래 링크에 잘 설명되어 있으므로, 자세한 건 이로 대체하고

https://devlog-wjdrbs96.tistory.com/331

        const repoConfig = {
            serverUrl: process.env.BITBUCKET_SERVER_URL, 
            projectName: eventBody.pullRequest.toRef.repository.project.key, 
            repoName: eventBody.pullRequest.toRef.repository.name, 
            branch: eventBody.pullRequest.toRef.displayId, 
            token: process.env.BITBUCKET_TOKEN, 
        };


        // Upload the repository package to S3 bucket
        const s3Upload = await s3.upload({
            Bucket: process.env.S3BUCKET,
            ServerSideEncryption: 'AES256',
            Key: `${repoConfig.projectName}/${repoConfig.repoName}/${repoConfig.branch}.zip`,
            Body: file
        }).promise();
        console.log(s3Upload);

        console.log('Exiting successfully');
        return responseToApiGw(200, 'success');

업로드 하는 부분만 다뤄보자면, key를 event에서 받아온 정보들로 담은 후(projectName, repoName 등)

s3에 zip형태로 올린다.

여기서 말하는 Body: file은, 코드를 다운로드할 때 axios.req로 코드를 bitbucket으로부터 다운받은 뒤,

그의 응답data(=file)를 가져온 부분이다. 

 

 

그러면, 코드에서 언급한 디렉토리가 생성되고 그 아래에 zip파일까지 업로드되는 것을 확인할 수 있다.

 

 

끝.

다음 포스팅은 본격적으로 codepipeline을 생성해보자.

4. AWS Codepipeline: S3 -> Codebuild + ECR 연동

5. Codebuild -> Deploy(ECS fargate)

6. ECS <-> LB(ALB) 연동하여 동작 테스트 

반응형

+ Recent posts