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) 연동하여 동작 테스트