반응형

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

반응형
반응형

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


이번엔 ci/cd를 위한 2-1, 2-2번째 단계로,

2-1. Bitbucket에서 PR merge가 발생했을 때 이를 AWS API Gateway로 던져주는 이벤트를 만들고

2-2. API Gateway에서 Lambda를 호출하는 절차까지 포스팅해본다 :)

 

 

2-1. 먼저, Bitbucket에서 PR merge가 발생했을 때,

Webhooks으로 AWS API Gateway에게 event를 보내는 절차를 진행한다.

이는 bitbucket에서 webhook을 보내줘야 하므로

bitbucket-> 내 Repository -> settings -> Webhooks 에 들어가서 Create webhook을 클릭한다.

어떤 값들이 필요한지 확인해보자.

 

PR merge시에만 api gateway를 호출하면 되므로, Pull request의 Merged를 체크하고, URL만 있으면 된다.

URL은 어디에 있을까?

 

AWS API Gateway앱으로 가보자.

먼저 Restful API를 생성한다.

이름만 넣고 생성.

 

그리고 어떤 path를 통해서 오든, POST를 처리해주기 위해 /POST 메서드를 만들어준다.

그리고 클라이언트로부터 해당 api가 호출될 경우, 별도로 생성해둔 Lambda로 그대로 프록시하도록 설정해준 후,

API 배포를 수행한다.

 

 

그럼 스테이지가 생성되고, URL이 생성된다.

이 URL을, 위의 Bitbucket에서 요구했던 URL에 넣으면 된다 :)

 

그리고, bitbucket에서 해당 URL로 "Test connection"을 하는 옵션도 있는데,

이를 확인하려면 람다 코드에서 x-event-key가 diagnostic:ping일 경우 200을 리턴하는 코드가 있어야 한다.

 

webhook이 올 때 event를 보면,

아래와 같이 header에 X-Event-Key가 실려오기 때문에 이를 기준으로 pr merge, ping등을 체크할 수 있다.

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":"ㅁㄴㅇㄹㅇㅁㄴㄹㄴecute-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ㅁㄴㄹㅇㅁㄹ026764d32b66cc4f0c5",
      ”X-Event-Key":"pr:comment:edited",   // 이건 PR에 댓글을 수정했을 때
      "X-Forwarded-For":"ㅁㅇㄴㄹㅁ01",
      "X-Forwarded-Port":"443",
      "X-Forwarded-Proto":"https",

 

그래서, diagnostic:ping에 대해 응답하는 코드를 넣으면,

이렇게 200ok가 뜨게 된다 :)

 

끝-!

다음은 3. Lambda -> S3로 패키지 업로드 예정 :)

반응형
반응형

 

CI/CD 구축을 위한 단계

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

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

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

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

3. API gateway -> Lambda 호출 

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

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

6. Codebuild -> Deploy(ECS fargate)

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

 


이번엔 CI/CD 구축을 위한 위 1-1, 1-2번 절차 포스팅이다.

일단 ci/cd 자체가, 코드를 올려서 그걸 연속적으로 배포해준다는 것인데, 그럼 코드를 올려야 한다.

나는 위 Diagram과 같이 bitbucket을 썼고, bitbucket에서 PR(Pull Request) Merge가 발생할 때마다 이를 slack으로 전송했다.

 

이번엔 대단한 작업이 딱히 없다 :) 

bitbucket에서 내가 사용할 repository를 생성하고, 그 repo의 설정으로 들어가준다. (Repository settings)

Merge시에만 알람이 가게끔 Merged를 체크해준다.

 

 

 

그리고 Additional configuration에서, 메세지를 노티 받을 Slack의 Channel name과 webhook Uri를 입력해준다.

Webhook Uri는, 내가 메세지를 노티받을 Slack의 channel에 들어가서,

오른쪽 상단의 설정을 누른 후, 통합 > 앱추가 > Incoming webhooks 를 설치하면 나온다.

 

앱 > 앱 추가

 

 

검색 창에 'incoming webhook' 검색, 하단에 '설치' 버튼을 눌러 webhooks을 설치한다.

 

 

채널에 포스트에서, 내가 웹훅을 받을 채널을 선택한다. (#clone-prison)

 

 

그럼 아래에 웹후크 url이 나오는데, 이 URL을 bitbucket의 Repository settings에 넣으면 된다.

 

이렇게 저장을 하면, PR Merge시마다 slack으로 노티를 받을 수 있다 :) 

 

반응형
반응형

 

CI/CD 구축을 위한 단계

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

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

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

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

3. API gateway -> Lambda 호출 

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

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

6. Codebuild -> Deploy(ECS fargate)

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

 

CI/CD 구축을 위한 첫 번째 절차는, 일단 코드를 배포하기 위한 타겟, 즉 컨테이너를 생성하는 것이다.

이 컨테이너를 관리해주는 게 ECS(Elastic Container Service)인데, ECS 앱을 통해 컨테이너를 생성한다.

컨테이너를 생성하기 위해서는, 

1) 클러스터 생성

2) 작업 정의(Task-definition) 생성

3) 서비스(Service) 생성이 필요하다.

 

 

1) 클러스터 생성

EC2가 아닌 Fargate를 생성할 예정이므로, 네트워킹 전용을 고른다.

 

나중에 태그 값으로 생성 리소스들을 확인해보기 위해 태그도 붙인다.

 

 

벌써 클러스터 생성이 완료되었다. 클러스터 생성은 큰 어려움이 없다.

 

 

2) 작업 정의(Task-definition) 생성

이제는 이 클러스터 내 컨테이너가 어떤 이미지를 쓰고, 자원들은 얼마나 쓸 것인지 정의하는

작업 정의(Task-Definition)을 생성해야 한다. 왼쪽 메뉴에서 '작업 정의'를 클릭한다. 

역시 Fargate를 생성할 예정이므로 Fargate를 선택한다.

 

이름, IAM, 컨테이너 정의를 수행한다.

(이미지를 불러오려면 미리 ECR에 이미지를 push 해놨어야 한다.)

앞으로 이 작업 정의를 사용하는 컨테이너는 위 이미지의 태그값을 사용한다. (그러니 신중하게 하자... 변경하려면 다시 생성해야 한다)

 

ECR에 미리 push해 둔 이미지 파일들. URI를 복사해서 위 컨테이너 이미지 링크로 넣는다.

 

그리고 작업정의를 이어서 진행한다.

가벼운 코드이므로 작업 크기는 작게 잡았다.

 

작업 정의도 완료되었다.

 

3) 서비스(Service) 생성

다음은 서비스 생성이다.

서비스란 클러스터의 앞단에서 이 클러스터 내 컨테이너를 몇 개 띄울 것인지, scaling은 어떻게 할 것인지(optional),

로드밸런싱 등의 설정을 하는 곳이다.

역시 FARGATE로 시작할 예정이므로 FARGATE로 설정하고, 작업 정의는 2)에서 정의했던 정의를 들고온다.

클러스터는 1)에서 정의한 클러스터를 들고온다.

 

그리고 패키지가 업데이트될 때마다 롤링업데이트를 진행할 예정으로, 롤링 업데이트를 설정하고

(롤링 업데이트: 패키지 배포시마다 컨테이너 전체에 업데이트를 한 번에 진행하는 게 아니라, 컨테이너를 하나씩 업데이트해서 서비스 중단이 없게끔 하는 업데이트 방식)

 

로드 밸런싱을 설정한다.

로드 밸런서는 당장은 설정하지 않아도 문제없으나, 결국엔 패키지가 제대로 배포되었는지 확인을 위해(curl을 통해 확인)

LB까지 설정을 진행한다.  

여기서 로드 밸런싱할 컨테이너는 2)에서 만든 작업정의의 컨테이너이므로 Jane-test:3002가 맵핑되어 있다.

이제 로드밸런서에 80포트를 통해 3002번 포트에게 req가 오면, 그걸 Jane-target-grp3이라는 대상으로 보낸다.

 

사실 :3002를 direct로 사용한다기 보다는, 보통 path를 통해 curl 확인을 하므로 코드에서 설정한 http 경로를 입력한다.

예를들어, 나는 코드에서 아래와 같이 /jane_으로 get을 했을 경우 이렇게 프린트 하라고 정의했기 때문에, 경로를 /jane_으로 입력해준다.

(평가순서는, :80을 사용하는 다른 서비스도 많기 때문에 /path로 분기를 하는데, 어떤 path를 먼저 볼 것인지 하는 우선순위이다.)

 

이렇게 다 설정을 하면, 서비스도 생성이 완료되었다.

 

 

그리고 서비스에 따라 작업(컨테이너)이 생성되었다.

끝!

반응형
반응형

하루를 삽질했다.... T-T

AWS ALB를 통해 통신을 하려면, 아래와 같이 여러 절차가 필요하다.

 

 

1. 코드 내에 health check를 위한 코드가 필요 하고,

app.listen(3001,function() {
console.log("** 1. web server open on port 3001");
})
app.get('/jane/health', async(req,res) => {
console.log("** health checking executed");
res.sendStatus(200);
});

 

2. 각 포트들이 맞아야 한다.

2-1. 코드 내 오픈된 port(위 3001)

2-2. 컨테이너를 생성할 때 설정한 서비스 내 컨테이너 포트(아래 3001),

2-3. LB의 대상그룹(target group) 포트(3001)

2-4. ECS의 서비스 > 보안그룹 내 포트 (3001)

타겟그룹 health check settings
2-3. 대상그룹(Target group)의 Port(3001)
2-4. 서비스의 보안그룹 내 포트 범위 설정

 

 

 

3. ECS task를 수행하는 Role에 LB를 위한 권한 설정 추가

(ElasticLoadBalancingFullAccess)

 

4. LB의 리스너도 경로가 타겟그룹에 맞게 설정되어 있는지 확인.

2-2. ECS의 서비스 세부 정보 내 대상그룹(3001)

 

이렇게 하면... healthy가 뜬다.... 흑흑

2-3. 대상그룹(Target group)의 Port(3001)

 

 

그럼 LB를 통해 통신이 되는지 확인해보자.

bastion에 들어가서 LB의 dns + path로 curl을 날려본다.

 

[ec2-user@bastion~]$ curl internal-alb-testestsetste.ap-northeast-2.elb.amazonaws.com/jane/health

OK

 

[ec2-user@bastion~]$ curl internal-alb-testestestset.ap-northeast-2.elb.amazonaws.com/jane

Database printed

[{"id":1,"data":"text1"},{"id":2,"data":"text2"}]

 

 

확인 완료!

반응형
반응형

Amazon ECS(Elastic Container Service)

클러스터에서 컨테이너를 쉽게 실행, 중지 및 관리할 수 있게 해주는 컨테이너 관리 서비스.

간단한 API 호출을 통해 컨테이너 기반 앱을 시작, 중지할 수 있음.

 

ECS 구성 요소

1. ECR(Elastic Container Repository)

아마존에서 제공하는 컨테이너 이미지 저장소.

ECR에서 이미지 URI를 이용해 빌드한 이미지를 푸쉬하고 가져올 수 있음.

 

2. 작업 정의(=Task Definition)

 애플리케이션을 구성하는 컨테이너를 설명하는 텍스트(JSON), 태스크를 실행하기 위한 정의.

(태스크는 클러스터에 종속적이지만 Task Definition은 클러스터에 종속적이지 않음)

  - 시작 유형 (Fargate, EC2, External)

  - 사용할 컨테이너 이미지

  - 개방할 포트, CPU/MEM 리소스, 데이터 볼륨 설정 등

 

3. 작업(Task)

작업 정의에서 정의된 설정으로 인스턴스화 하는 것. 컨테이너를 실행하는 최소 단위로 하나 이상의 컨테이너로 구성됨.

Task는 Cluster에 속한 컨테이너 인스턴스(EC2 Instance)나 Fargate에 배포하게 됨.

 

4. 서비스(Service)

클러스터에서 지정된 수의 작업을 동시에 실행하고 관리할 수 있게 해주는 구성.

서비스는 Task를 포함하며, Task와 관련된 Auto Scaling, LB(Load Balancing)을 관리.

 - 클러스터, 작업정의, 시작유형, 작업 개수, LB, Auto Scaling, 네트워크 구성, 배포 유형(롤링, 블루/그린 등) 설정

 

5. 클러스터(Cluster)

작업 또는 서비스의 논리적 그룹. 클러스터를 실행하여 작업을 실행할 수 있음.

 - 클러스터 템플릿 선택(Fargate, EC2, External)

 

 

* 시작 유형

Fargate : 컨테이너를 배포하고 관리할 수 있는 서버리스 컴퓨팅 엔진
EC2 : 컨테이너를 배포하고 관리할 수 있는 클라우드 컴퓨팅 플랫폼
External : 컨테이너를 배포하고 관리할 수 있는 온프레미스 서버 또는 가상 머신

 

 

* 클러스터에는 두 가지 방식으로 태스크를 실행할 수 있음.

1. 작업 정의(=Task Definition)로 직접 태스크를 실행하는 방식

곧바로 실행되며 실행이 된 후로 더 이상 관리되지 않음. 일회성 명령어라면 한 번 실행된 후 종료되며, 데몬이라면 태스크를 명시적으로 종료할 때까지 컨테이너가 남아 있음. 직접 태스크를 실행하는 방법은 특별한 이유가 있을 때 외에는 거의 사용되지 않음.

 

2. 서비스(=Service): 하나의 Task Definition(Revision)과 연결됨

- 데몬타입: 모든 컨테이너 인스턴스에 해당하는 태스크가 하나씩 실행됨. 이것은 인스턴스 관리를 위한 용도로 사용됨.

- 리플리카 타입: 실행하려는 태스크의 개수를 지정하여, 이 개수만큼 실행되도록 자동 관리해줌. 이 리플리카 타입이 웹서버를 비롯한 실제 서비스에서 주로 사용됨.

프로세스를 배치하는 경우, 운영자가 직접 어떤 인스턴스에 어떤 프로세스를 언제 배치할지 결정해야 하는데, ECS에서는 서비스가 이 스케쥴링 역할을 담당함. (= 서비스는 각 인스턴스들에 설치된 ecs-client에서 수집된 정보를 기반으로 어디에 어떤 태스크를 언제 실행할지 결정. 즉, 다수의 컨테이너 인스턴스가 있을 시 언제 어디서 태스크가 실행될지 알 수 없음. 서비스가 직접 태스크 배치 스케쥴링을 수행) 

 

출처

https://tech.cloud.nongshim.co.kr/2021/08/30/%EC%86%8C%EA%B0%9C-amazon-ecs%EB%9E%80/

https://www.44bits.io/ko/post/container-orchestration-101-with-docker-and-aws-elastic-container-service

 

AWS ECS로 시작하는 컨테이너 오케스트레이션

컨테이너는 격리된 환경에서 애플리케이션을 실행할 수 있도록 도와줍니다. 컨테이너를 프로덕션 환경에서 사용하기 위해서는 적절한 스케줄링과 관리를 위한 도구가 필요합니다. 이 글에서는

www.44bits.io

 

[소개] Amazon ECS란?

Amazon ECS(Elastic Container Service) 란? 클러스터에서 컨테이너를 쉽게 실행, 중지 및 관리할 수 있게 해주는 컨테이너 관리 서비스 입니다.간단한 API 호출을 사용하여 컨테이너 기반 애플리케이션을

tech.cloud.nongshim.co.kr

 

반응형
반응형

현상

Codebuild에서 빌드 후 ECR에 image를 push하는 절차 중, 아래와 같이 ECR 관련한 명령이 실패되었다.

 

해결 방법

이런 것은 권한 문제일 가능성이 크다.

Codebuild에 설정한 역할(Role)에 AmazonEC2ContainerRegistryFullAccess를 추가해준다.

 

그리고, buildspec.yml에 ecr로 로그인을 위한 아래 커멘드가 존재해야 한다.

$(aws ecr get-login --no-include-email --region ap-northeast-2)

이렇게 하면, 빌드 성공!

반응형
반응형

현상

AWS codebuild를 통해 빌드를 하고 있는데, buildspec.yml을 읽는 과정에서 아래와 같은 에러가 발생했다.

 

[Container] 2022/05/31 20:23:56 Running command docker build -t $IMAGE_NAME .
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

[Container] 2022/05/31 20:23:58 Command did not exit successfully docker build -t $IMAGE_NAME . exit status 1
[Container] 2022/05/31 20:23:58 Phase complete: INSTALL State: FAILED
[Container] 2022/05/31 20:23:58 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: docker build -t $IMAGE_NAME .. Reason: exit status 1

 

 

해결

다행히 말 그대로 도커 데몬에 연결할 수 없다는 것인데, aws의 troubleshooting 사이트에 올라와 있는 에러였다.

https://docs.aws.amazon.com/ko_kr/codebuild/latest/userguide/troubleshooting.html

 

똑같이 따라가본다.

Codebuild > 프로젝트 > 내 프로젝트 > 환경 편집 > 이미지 재정의

 

난 가장 하단에 '권한이 있음'을 체크하지 않았었다.

이부분을 체크해준다.

 

 

그리고 다시 빌드를 했더니, 돌아간다 :)

 

끝 

(또 다른 이슈 발생,,,)

반응형
반응형

현상

ci/cd구축을 위해 code pipeline을 생성한 후, source에서 아래와 같은 에러가 발생함.

(제 pipeline은 S3를 통해 pkg를 가져오는 구조입니다.)

 

권한 부족

The provided role does not have permissions to prform this action.

 

 

IAM에서 여러 권한을 줘봤으나 현상은 모두 동일했고, 구글링을 반나절 해본 결과...

S3 bucket > 버킷정책을 확인해보라는 말을 보았다.

 

그래서 S3 bucket으로 가서, 버킷 정책을 확인했다.

codepipeline에 대한 권한이 없어 codepipeline을 *로 주었고, 생성한 codepipeline의 arn 추가했더니 

아래와 같이 2가지 에러가 발생했다.

Ln 16, Col 4에 언급된 링크를 들어가보면,

https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/access-analyzer-reference-policy-checks.html#access-analyzer-reference-policy-checks-error-unsupported-resource-arn-in-policy

 

Access Analyzer 정책 검사 참조 - AWS Identity and Access Management

Access Analyzer 정책 검사 참조 AWS IAM Access Analyzer 정책 검사를 사용하여 정책을 검증할 수 있습니다. AWS CLI, AWS API 또는 IAM 콘솔의 JSON 정책 편집기를 사용하여 정책을 생성 또는 편집할 수 있습니다.

docs.aws.amazon.com

 

 

Resolving the error (이슈 해결)

Some resource ARNs aren't supported in the Resource element of the resource-based policy when the policy is attached to a different resource type. For example, AWS KMS ARNs aren't supported in the Resource element for Amazon S3 bucket policies. Specify a resource ARN that is supported by a resource type attached to your resource-based policy.

일부 리소스 ARN들은 정책이 다른 리소스 타입에 연결된 경우, 리소스 요소를 지원하지 않는다,

예를 들어 AWS KMS ARN은 S3 버킷 정책에서 지원되지 않는다. --> codepipeline 만들 때 KMS를 썼었다. 이걸 제거하자.

 

 

결론

그래서 결국엔, codepipeline을 생성할 때, KMS를 사용하지 않고 기본 AWS 관리형 키를 선택한 결과 소스 가져오기가 성공하였다.

 

 

 

휴 일단 소스 가져오기까진 성공!

반응형
반응형

Axios란?

Axios는 브라우저, Node.js를 위해서 만들어진 Promise API를 활용하는 HTTP 비동기 통신 라이브러리 

 

Axios의 특징

  • Axios는 운영환경에 따라서 브라우저간 XMLHttpRequest 객체 또는 Node.js의 HTTP API를 사용한다.
  • Promise(ES6) API를 사용
  • 요청(Request) 응답 (reply)을 JSON 형태로 자동 변경

 

HTTP 메서드 별칭

편의를 위해 지원되는 모든 요청 메소드에 별칭이 제공됩니다.

axios.get(url[, config])            // GET
axios.post(url[, data[, config]])   // POST
axios.put(url[, data[, config]])    // PUT
axios.patch(url[, data[, config]])  // PATCH
axios.delete(url[, config])         // DELETE

axios.request(config)
axios.head(url[, config])
axios.options(url[, config])

 

Axios 사용 예시

1) GET

axios.get(url,[,config])
// 예로 만든 axios 구조
import axios from "axios"

axios.get('https://localhost:3000/login/user')
  .then((Response)=>{console.log(Response.data)})
  .catch((Error)=>{console.log(Error)})
[
  { id: 1, pw: '12345', name: 'jungho' },
  { id: 2, pw: '12345', name: 'sungJun' },
  { id: 3, pw: '12345', name: 'hyunJi' },
]

응답은 json 형태로 넘어온다.

 

 

 

구성 옵션

사용 가능한 구성(conifg) 설정 옵션입니다.

NOTE

url 속성만 필수이고, 나머지 속성은 옵션입니다. method가 지정되지 않으면 요청은 GET으로 기본 설정 됩니다.

baseURL은 서버의 기본 URL을 의미하며, headers에는 자신이 매번 전달해야하는 객체 (예: 사용자 토큰)를 넣어주시면 자동으로 삽입이 됩니다. URL 경로에는 baseURL의 뒷부분만 삽입을 해도 됨.

{
  // `url`은 요청에 사용될 서버 URL입니다.
  url: '/user',

  // `method`는 요청을 할 때 사용될 메소드 이름입니다.
  method: 'get', // 기본

  // `url` 속성 값이 절대 URL이 아니라면, `url` 앞에 `baseURL`이 붙습니다.
  // axios 인스턴스가 상대 URL을 해당 인스턴스의 메소드에 전달하도록
  // `baseURL`을 설정하는 것이 편리 할 수 ​​있습니다.
  baseURL: 'https://some-domain.com/api/',

  // `transformRequest`는 서버에 보내기 전에 요청 데이터를 변경할 수 있습니다.
  // 요청 메소드 'PUT', 'POST' 및 'PATCH' 에만 적용 가능합니다.
  // 배열의 마지막 함수는 버퍼(buffer)의 문자열이나 인스턴스를 반환해야 합니다.
  // ArrayBuffer, FormData 또는 Stream 헤더 객체를 수정할 수 있습니다.
  transformRequest: [function (data, headers) {
    // 데이터 변환 수행 후, 반환
    // ...
    return data;
  }],

  // `transformResponse`는 응답할 데이터에 대한 변경을 전달해
  // then/catch에 전달하도록 허용합니다.
  transformResponse: [function (data) {
    // 데이터 변환 수행 후, 반환
    // ...
    return data;
  }],

  // `headers`는 서버에 전송 될 사용자 정의 헤더 입니다.
  headers: { 'X-Requested-With': 'XMLHttpRequest' },

  // `params`는 요청과 함께 전송 될 URL 매개 변수입니다.
  // 일반 객체 이거나 URLSearchParams 객체여야 합니다.
  params: {
    ID: 12345
  },

  // `paramsSerializer`는`params`를 직렬화(serializing) 하는 옵션 함수입니다.
  // (예: https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
  paramsSerializer: function (params) {
    return Qs.stringify(params, {arrayFormat: 'brackets'})
  },

  // `data`는 요청 본문(request body)으로 전송할 데이터입니다.
  // 'PUT', 'POST' 및 'PATCH' 요청 메소드에만 적용 가능합니다.
  // 'transformRequest`가 설정되지 않은 경우 다음 유형 중 하나여야 합니다.
  // - [ string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams ]
  // - 브라우저 전용: FormData, File, Blob
  // - Node.js 전용: Stream, Buffer
  data: {
    firstName: 'Fred'
  },

  // `timeout`은 요청이 타임 아웃되는 밀리 초(ms)를 설정합니다.
  // 요청이`timeout` 설정 시간보다 지연될 경우, 요청은 중단됩니다.
  timeout: 1000, // 기본 값: `0` (타임아웃 없음)

  // `withCredentials`는 자격 증명(credentials)을 사용하여
  // 크로스 사이트 접근 제어(cross-site Access-Control) 요청이 필요한 경우 설정합니다.
  withCredentials: false, // 기본 값

  // `adapter`는 테스트를 보다 쉽게 해주는 커스텀 핸들링 요청을 허용합니다.
  // 유효한 응답(Promise)을 반환해야 합니다. (lib/adapters/README.md 참고).
  adapter: function (config) {
    // ...
  },

  // `auth`는 HTTP 기본 인증(auth)이 사용되며, 자격 증명(credentials)을 제공함을 나타냅니다.
  // 기존의 `Authorization` 커스텀 헤더를 덮어쓰는 `Authorization` 헤더(header)를 설정합니다.
  auth: {
    username: 'janedoe',
    password: 's00pers3cret'
  },

  // `responseType`은 서버에서 응답할 데이터 타입을 설정합니다.
  // [ 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream' ]
  responseType: 'json', // 기본 값

  // `responseEncoding`은 응답 디코딩에 사용할 인코딩을 나타냅니다.
  // [주의!] 클라이언트 사이드 요청 또는 `responseType`이 'stream'인 경우는 무시합니다.
  responseEncoding: 'utf8', // 기본 값

  // `xsrfCookieName`은 xsrf 토큰(token)에 대한 값으로 사용할 쿠키 이름입니다.
  xsrfCookieName: 'XSRF-TOKEN', // 기본 값

  // `xsrfHeaderName`은 xsrf 토큰 값을 운반하는 HTTP 헤더 이름입니다.
  xsrfHeaderName: 'X-XSRF-TOKEN', // 기본 값

  // `onUploadProgress`는 업로드 프로그래스 이벤트를 처리합니다.
  onUploadProgress: function (progressEvent) {
    // 네이티브 프로그래스 이벤트(Native Progress Event) 처리 코드
    // ...
  },

  // `onDownloadProgress`는 다운로드 프로그래스 이벤트를 처리합니다.
  onDownloadProgress: function (progressEvent) {
    // 네이티브 프로그래스 이벤트(Native Progress Event) 처리 코드
    // ...
  },

  // `maxContentLength`는 HTTP 응답 콘텐츠의 최대 크기를 바이트(Bytes) 단위로 설정합니다.
  maxContentLength: 2000,

 // `validateStatus`는 주어진 HTTP 응답 상태 코드에 대한 약속을 해결할지 거절 할지를 정의합니다.
 // `validateStatus`가`true`를 반환하면 (또는`null`,`undefined`) promise를 resolve 합니다.
 // 그렇지 않으면 promise가 reject 됩니다.
  validateStatus: function (status) {
    return status >= 200 && status < 300; // 기본 값
  },

  // `maxRedirects`는 Node.js에서 리디렉션 가능한 최대 갯수를 정의합니다.
  // 0으로 설정하면 리디렉션이 수행되지 않습니다.
  maxRedirects: 5, // 기본 값

  // `socketPath`는 Node.js에서 사용될 UNIX 소켓을 정의합니다.
  // 예: '/var/run/docker.sock'을 사용하여 docker 데몬에 요청을 보냅니다.
  // `socketPath` 또는`proxy`만이 지정 될 수 있습니다.
  // 둘 다 지정되면`socketPath`가 사용됩니다.
  socketPath: null, // 기본 값

  // `httpAgent`와`httpsAgent`는 각각 Node.js에서 http와 https 요청을 수행 할 때
  // 사용할 커스텀 에이전트를 정의합니다. 이것은 기본적으로 활성화되지 않은 `keepAlive`와 같은
  // 옵션을 추가 할 수 있게 합니다.
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),

  // 'proxy'는 프록시 서버의 호스트 이름과 포트를 정의합니다.
  // 기존의 `http_proxy` 및 `https_proxy` 환경 변수를 사용하여 프록시를 정의 할 수도 있습니다.
  // 프록시 설정에 환경 변수를 사용하고 있다면 `no_proxy` 환경 변수를 쉼표로 구분 된 도메인 목록으로
  // 정의하여 프록시 할 필요가 없습니다.
  // 환경 변수를 무시하고 프록시를 사용하지 않으려면 `false`를 설정합니다.
  // `auth`는 HTTP 기본 인증(Basic Auth)를 사용하여 프록시에 연결하고 자격 증명을 제공해야 함을 나타냅니다.
  // 기존의 `Proxy-Authorization` 커스텀 헤더를 덮어쓰는 `Proxy-Authorization` 헤더(header)를 설정합니다.
  proxy: {
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // `cancelToken`은 요청을 취소하는 데 사용할 수 있는 취소 토큰을 지정합니다.
  // (자세한 내용은 해제(Cancellation) 섹션 참조).
  cancelToken: new CancelToken(function (cancel) {
    // ...
  })

}

 

 

 

 

 

출처: https://koras02.tistory.com/48 [Koras02코딩웹:티스토리]

https://yamoo9.github.io/axios/guide/api.html

 

API | Axios 러닝 가이드

API 구성(configuration) 설정을axios()에 전달하여 요청할 수 있습니다. axios(config) axios({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone' } }); 1 2 3 4 5 6 7 8 9 axios({ method:'get', url:'http://bit

yamoo9.github.io

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType

 

XMLHttpRequest.responseType - Web APIs | MDN

The XMLHttpRequest property responseType is an enumerated string value specifying the type of data contained in the response.

developer.mozilla.org

"ms-stream" Non-Standard

The response is part of a streaming download; this response type is only allowed for download requests, and is only supported by Internet Explorer.

 

https://velog.io/@yiyb0603/React%EC%97%90%EC%84%9C-axios-%EC%BB%A4%EC%8A%A4%ED%85%80%ED%95%98%EA%B8%B0

반응형

+ Recent posts