# CodeCommit, CodeBuild, CodeDeploy

## 1. CodeCommit

용량 제약 없이 private repository를 제공하는 완전 관리형 Git이다. 내 계정의 VPC에만 코드를 저장하여 보안과 compliance를 높이고 다른 툴들과 통합이 용이하다.

- HTTPS, SSH로 접근한다.

- IAM 유저를 만들고 해당 유저의 Git credential로 인증한다.

- IAM으로 유저별 권한 제어할 수 있다.

- notification, trigger 지원한다.

- Trigger를 통해 Lambda와 연결해 자동화 구현 가능하다.

## 2. CodeBuild

Jenkins 등을 대체하며, 도커 위에서 동작하는 완전 관리형 빌트 툴이다.

### 개요

- 보안 서비스(KMS, IAM, VPC, CloudTrail)과 통합 가능하다.

- GitHub, CodeCommit 등에서 소스 코드를 가져온다.

- 명령을 buildspec.yml에 미리 정의할 수 있다.

- S3와 CloudWatch Logs에 결과 로그를 저장한다.

### buildspec.yml

```
version: 0.2
env:
	...
phases:
  install:
		runtime-versions:
			nodejs: 10
    commands:
      - command
    finally: # 성공 여부와 상관없이 실행
      - command
  pre_build:
	...
artifects:
  files:
	  - location
	name: artifect-name
```

### 환경 변수

[Environment variables in build environments - AWS CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html)

- `printenv` 커맨드로 모든 환경 변수를 출력할 수 있다.

- `$AWS_REIGON` 형식으로 CodeBuild에서 제공하는 환경 변수를 가져다 쓸 수 있다.

- `buildspec.yml`이나 콘솔에서 커스텀 환경 변수를 선언할 수 있다.

- 각 환경 변수값은 PlainText 혹은 SSM Parameter Store에서 읽을 수 있다.

- SSM Parameter Store을 환경 변수로 쓸 때, 적합한 IAM 권한이 있어야지만 값을 읽을 수 있다.

### 아티펙트

빌드하고 난 결과물을 말한다. 빌드별로 S3에 담아둔다.

- `콘솔 설정` : 어떤 버킷에 저장할 것인가?

- `files` : 어떤 파일들을 압축할 것인가?

- `name` : 어떤 이름으로 저장할 것인가?

```
# buildspec.yml
...
artifacts:
	files:
#   - '**/*' # 전체 경로를 나타냄
		- target/myapp.jar
	name: myapp-$(date +%Y-%m-%d)
```

아래는 CodeBuild Artifacts 설정 중 일부이다.

- S3에서 버저닝을 할 것인가?

- 암호화할 것인가?

- 압축할 것인가?

- Build ID 폴더에 저장할 것인가?

### CloudWatch (CW) 통합

- **CW Logs**나 S3에 로그를 기록할 수 있다.

- **CW Metrics**으로 CodeBuild 성공/실패 등 지표 추적하고 Alarm을 설정할 수 있다.

- **CW Events**를 통해 매 시간마다 빌드를 트리거할 수 있다.

- **CW Events**로 CodeBuild의 이벤트를 다른 서비스로 보낼 수 있다.

### CodeCommit과 통합

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134206_Uhsb5azjhEP9yLLCNt?q=80&s=1280x180&t=outside&f=webp)

## 3. CodeDeploy

Ansible, Chef 등을 대체하여 EC2에 자동으로 어플리케이션을 배포하는 완전 관리형 서비스이다.

- EC2/On-premise 머신에는 CodeDeploy agent가 설치되어 있어야 한다.

- agent는 주기적으로 CodeDeploy를 검사해 배포 여부를 확인하고, 배포 결과를 보고한다.

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134207_Le7Wimjj2gAHr5BgTF?q=80&s=1280x180&t=outside&f=webp)

- CodePipeline, Auto Scaling 등과 연동된다.

- **CloudWatch**와 연동이 가능하다.

```
# 로컬의 프로젝트를 aws에 배포할 때 사용하는 명령어
aws deploy push --application-name <name> \
								--s3-location <s3 location to save artifact> \
								--ignore-hidden-files \
								--region eu-east-1 \
								--profile aws-devops
```

### 배포 그룹

하나의 어플리케이션을 dev, prod 등 다른 환경에 배포해야 할 필요가 있다. 각 배포 그룹마다 각자의 배포 전략을 가지고 있으며, 태그를 통해 배포를 진행할 EC2를 추가한다.

### 배포 구성

- **AllAtOnce** : 한 번에 모든 인스턴스에 배포

- **HalfAtATime** : 50% 인스턴스를 배포 한 후 다음 50%를 배포

- **OneAtATime** : 한 번에 한 인스턴스에만 배포

- **Custom** : 직접 배포 구성을 만들 수 있다.

### 배포 타입

- **In-place **: 배포 그룹에 있는 인스턴스에 어플리케이션 배포

- **Blue/Green** : 새로운 인스턴스 그룹을 만들어 배포 후, 기존 그룹을 교체. 온프레미스에서는 불가능하다.

### appspec.yml

배포 생명 주기에 따라 실행 명령들을 `appspec.yml` 파일에 적는다. 각 명령들은 스크립트 파일로 만들어져 실행되어야 한다. 명령에는 CodeDeploy에서 제공하는 환경 변수를 사용할 수 있다.

![In-place deployment](https://upload.cafenono.com/image/slashpageHome/20240820/134208_PJvoA81EeiOIcI4zYv?q=80&s=1280x180&t=outside&f=webp)

![ECS deployment](https://upload.cafenono.com/image/slashpageHome/20240820/134208_l9puRsUrMiP8233xZ6?q=80&s=1280x180&t=outside&f=webp)

Lambda는 **트래픽 허용 전, 후**만 있다.

ECS는 도커이기 때문에, Test Traffic을 통해 서비스를 검증한다.

### 롤백

- 수동 롤백 : 수동으로 이전 버전을 재배포한다.

- 자동 롤백 : 배포가 실패하거나, **Alarm**이 트리거되었을 때 롤백한다.

### 온프레미스에 배포

온프레미스를 등록하기 위한 방법은 2가지이다.

- **IAM User** : 단일 인스턴스에 유저를 할당한다. 쉬운 방법.

- **IAM Role** : STS 임시 토큰을 사용해 인스턴스에 할당한다. 다수의 인스턴스에 유리하지만 복잡하다.

머신 등록이 되면 해당 온프레미스 머신에 태그를 붙여 EC2 인스턴스처럼 배포 그룹에 등록한다.

### Lambda에 배포

- **Canary** : 처음에 약간 트래픽만 새 버전으로 보내고, 정상이면 전부 새 버전으로 보낸다.

- **Linear** : 점진적으로 트래픽을 새 버전으로 보낸다.

- **All-at-once** : 한 번에 모든 트래픽을 새 버전으로 보낸다.

Lambda는 인스턴스를 실행하지 않기 때문에 트래픽을 관리하는 Hook만 존재한다.

![Image](https://upload.cafenono.com/image/slashpageHome/20240820/134209_2mDQwamtbCK5QsbFJ7?q=80&s=1280x180&t=outside&f=webp)

For the site tree, see the [root Markdown](https://slashpage.com/kaonmir.md).
