# Chapter4 AWS CodeDeploy

AWS CodeDeploy는 Amazon EC2, AWS Fargate, AWS Lambda 및 온프레미스 서비스와 같은 다양한 컴퓨팅 서비스에 대한 소프트웨어 배포를 자동화하는 완전 관리형 배포 서비스입니다. AWS CodeDeploy를 사용하여 소프트웨어 배포를 자동화할 수 있으므로 오류가 발생하기 쉬운 수동 작업이 필요하지 않습니다.

이 실습에서는 CodeDeploy를 사용하여 [Apache Tomcat을 실행하는 Amazon EC2 인스턴스에 Java WAR 패키지를 설치합니다.](http://tomcat.apache.org/)

시나리오 단순성을 위해 이 실습에서는 단일 가용 영역(AZ)에 단일 EC2 인스턴스를 사용합니다. 실제 프로덕션 환경에서는 Elastic Load Balancer(ELB) 뒤의 여러 AZ에 분산된 인스턴스를 사용해야 합니다.

<figure><img src="https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2FZhvOhfwB7mgyikOpblgS%2Fimage.png?alt=media&#x26;token=0daa749e-24f0-4efd-a9e1-2911204f987c" alt=""><figcaption></figcaption></figure>

## EC2 인스턴스 생성

AWS CloudFormation을 사용하여 애플리케이션을 배포할 VPC와 EC2 인스턴스를 프로비저닝할 것입니다.

1. AWS 콘솔에 로그인하고 **CloudFormation** 을 검색합니다.
2. [CloudFormation YAML 템플릿 다운로드](https://static.us-east-1.prod.workshops.aws/public/bc11432d-6ad0-4a3b-8d67-faf8b047ae57/static/ec2-cfn.yaml).
3. CloudFormation 콘솔에서 **스택 생성 > 새 리소스 사용(표준)**&#xC744; 클릭 합니다.
4. **템플릿 파일 업로드**를 선택 하고 **파일 선택**을 클릭 합니다 . 2단계에서 다운로드한 yaml 파일을 선택하고 **다음**을 클릭 합니다.

<figure><img src="https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2Fsafk5TVnH3aIUMhGG3yc%2Fimage.png?alt=media&#x26;token=a3adb5ad-d2cb-4fdb-957a-56e5b63921f4" alt=""><figcaption></figcaption></figure>

5\. 스택 이름을 **UnicornStack**으로 지정하고 <http://checkip.amazonaws.com/>에서 나의IP 주소를 확인합니다. 그리고 MyIP에 IP주소와 CIDR를 입력하고 , 다음을 클릭합니다.   ex)1.2.3.&#x34;**/32**&#x20;

6\. 나머지는 모두 기본값으로 설정하고 다음 버튼을 클릭합니다.

7\. 마지막에 AWS CloudFormation에서 IAM 리소스를 생성할 수 있는 옵션을 선택하고 전송 버튼을 클릭합니다.

<figure><img src="https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2FiY3U0qPgpuY4JkFWFX2H%2Fimage.png?alt=media&#x26;token=10cbcb3f-6704-4b77-9c05-7577de9e30c8" alt=""><figcaption></figcaption></figure>

8\. 스택이 완료될 때까지 기다립니다. 이 작업은 5분 정도 소요됩니다.

9\. 성공하면 AWS 콘솔에서 "EC2"를 검색하고 **UnicornStack::WebServer**라는 인스턴스가 있는지 확인합니다.

## **애플리케이션을 실행하기 위한 스크립트 생성**

다음으로 Git 리포지토리에 몇 가지 bash 스크립트를 만들어야 합니다. CodeDeploy는 이러한 스크립트를 사용하여 대상 EC2 인스턴스에서 애플리케이션을 설정하고 배포합니다.

1. Cloud9 IDE에 로그인합니다.
2. **\~/environment/unicorn-web-project/** 아래에 **scripts**라는 새 폴더를 만듭니다.

![](https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2FMjYfcu23cXANNQlbzCYp%2Fimage.png?alt=media\&token=baef83fc-6006-43f5-b03f-0d4d4851024f)

3\. **scripts 폴더**에 **install\_dependencies.sh** 파일을 만들고 아래의 내용을 복사 붙여넣기 하고 저장합니다.

```bash
#!/bin/bash
sudo yum install tomcat -y
sudo yum -y install httpd
sudo cat << EOF > /etc/httpd/conf.d/tomcat_manager.conf
<VirtualHost *:80>
    ServerAdmin root@localhost
    ServerName app.wildrydes.com
    DefaultType text/html
    ProxyRequests off
    ProxyPreserveHost On
    ProxyPass / http://localhost:8080/unicorn-web-project/
    ProxyPassReverse / http://localhost:8080/unicorn-web-project/
</VirtualHost>
EOF
```

4\. **scripts** 폴더에 **start\_server.sh** 파일을 만들고 아래의 내용을 복사 붙여넣기 하고 저장합니다.

```bash
#!/bin/bash
sudo systemctl start tomcat.service
sudo systemctl enable tomcat.service
sudo systemctl start httpd.service
sudo systemctl enable httpd.service
```

5\. **scripts** 폴더에 **stop\_server.sh** 파일을 만들고 아래의 내용을 복사 붙여넣기 하고 저장합니다.

```bash
#!/bin/bash
isExistApp=pgrep httpd
if [[ -n $isExistApp ]]; then
sudo systemctl stop httpd.service
fi
isExistApp=pgrep tomcat
if [[ -n $isExistApp ]]; then
sudo systemctl stop tomcat.service
fi
```

6\. scripts 폴더 하위에는 아래와 같이 3개의 sh파일이 있어야 합니다.&#x20;

![](https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2FaiHs6KQ3llAgmVXPZq5J%2Fimage.png?alt=media\&token=447eebcb-7ed4-48a7-9a60-ecfcfb1cda25)

7\. CodeDeploy는 애플리케이션 사양(AppSpec.yml) 파일을 사용하여 배포 중에 수행할 작업을 지정하고 소스의 어떤 파일이 대상에 배치되는지 정의합니다. AppSpec 파일의 이름은 **appspec.yml**로 지정 하고 소스 코드의 루트 디렉터리에 배치해야 합니다.

8\. **\~/environment/unicorn-web-project/** 폴더에서 New File을 생성하고 파일의 이름을 **appspec.yml**으로 설정하고 아래의 내용을 추가하고 저장합니다.

```yaml
version: 0.0
os: linux
files:
  - source: /target/unicorn-web-project.war
    destination: /usr/share/tomcat/webapps/
hooks:
  BeforeInstall:
    - location: scripts/install_dependencies.sh
      timeout: 300
      runas: root
  ApplicationStart:
    - location: scripts/start_server.sh
      timeout: 300
      runas: root
  ApplicationStop:
    - location: scripts/stop_server.sh
      timeout: 300
      runas: root
```

9\. 새로 추가된 스크립트 폴더와 appspec.yml 파일을 CodeDeploy에서 사용할 수 있도록 하려면 CodeBuild가 생성하는 zip 파일에 추가해야 합니다. **buildspec.yml** 파일에 들어가 **아티팩트** 섹션을 아래와 같이 수정합니다.

<pre class="language-yaml"><code class="lang-yaml">phases:
  [..]
  
artifacts:
  files:
<strong>    - target/unicorn-web-project.war
</strong>    - appspec.yml
    - scripts/**/*
  discard-paths: no
</code></pre>

10\. 이제 CodeCommit에 대한 모든 변경 사항을 커밋합니다.

```bash
cd ~/environment/unicorn-web-project
git add *
git commit -m "Adding CodeDeploy files"
git push -u origin main
```

11\. CodeBuild 콘솔에서 unicorn-web-build 프로젝트를 선택하고 **빌드 시작**을 클릭합니다. zip 패키지에 새로 추가된 아티팩트를 포함하는 프로젝트를 다시 실행합니다.

## **CodeBuild 서비스 IAM 역할 생성**

CodeDeploy에는 원하는 컴퓨팅 플랫폼에 대한 권한을 부여하는 서비스 역할이 필요합니다. **EC2/온프레미스 배포의 경우 AWS Managed AWSCodeDeployRole** 정책을 사용할 수 있습니다 .

1. **AWS 콘솔**에  **IAM** 콘솔을 엽니다 .
2. **역할**을 선택한 다음 **역할 만들기**를 클릭 합니다.
3. 다른 AWS 서비스의 사용사례에서 CodeDeploy를 선택하고 **다음**을 클릭합니다.&#x20;

<figure><img src="https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2FSpNNt2CiK8i3Byk3Bwqh%2Fimage.png?alt=media&#x26;token=00b27996-31c6-42ae-b680-b39ab17abcc0" alt=""><figcaption></figcaption></figure>

4\. **AWSCodeDeployRole** 이 있는 것을 확인하고 다음 버튼을 클릭합니다.

5\. 역할 이름을 **UnicornCodeDeployRole**로 지정 합니다. 나머지는 기본값으로 두고 **역할 생성**을 클릭 하여 완료합니다.

## **CodeDeploy 애플리케이션 생성**

이제 필요한 파일이 준비되었으므로 CodeDeploy 애플리케이션을 생성해 보겠습니다.&#x20;

1. AWS 콘솔에 **CodeDeploy**를 검색합니다 .
2. 왼쪽 메뉴 에서 **애플리케이션**을 클릭하고 **애플리케이션 생성**을 선택합니다 .
3. 애플리케이션 이름을 **unicorn-web-deploy**로 지정 하고 **EC2/온프레미스**를 컴퓨팅 플랫폼으로 선택합니다. **애플리케이션 생성**을 클릭 합니다 .

<figure><img src="https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2FWA4GCZKleLmnXzFkRPfR%2Fimage.png?alt=media&#x26;token=a2383837-9fa6-4ed4-ac33-adc10253d8e9" alt=""><figcaption></figcaption></figure>

## **배포 그룹 만들기**

다음으로 배포 중에 사용된 설정 및 구성이 포함된 배포 그룹을 생성해 보겠습니다. 예를 들어 배포가 특정 태그가 있는 모든 EC2 인스턴스를 대상으로 한다고 정의합니다.

1. **unicorn-web-deploy** **배포 그룹** **생성**을 클릭합니다 .
2. 다음 옵션을 구성합니다.

* 이름 = **unicorn-web-deploy-group**
* 서비스 역할 = **arn:aws:iam::\<aws-account-id>:role/UnicornCodeDeployRole**
* 배포 유형 = **현재 위치**
* 환경 구성 = **Amazon EC2 인스턴스**
* 태그 그룹 1 키 = **role**
* 태그 그룹 1 값 = **webserver**
* AWS CodeDeploy 에이전트 설치 = **지금 및 업데이트 예약(14일)**
* 배포 설정 = **CodeDeployDefault.AllAtOnce**
* 로드 밸런서 = **로드 밸런싱 활성화 선택을 취소합니다(서버가 하나만 있음).**&#x20;

<figure><img src="https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2FHRtliCp5u6h1wvLyvNuK%2Fimage.png?alt=media&#x26;token=57f55a7e-ef74-46cb-9f15-3dd322ca87ff" alt=""><figcaption></figcaption></figure>

3\. **배포 그룹 생성**을  클릭 합니다 .

## **배포 만들기**

배포 그룹을 만든 후(즉, 배포할 리소스를 정의한 후) 이제 배포를 만들 수 있습니다!

1. **unicorn-web-deploy-group**에서 **배포 생성**을 클릭 합니다 .
2. 개정 위치의 경우 이전에 생성한 S3 버킷을 사용합니다. (my-artifact-bucket-name은 본인의 버킷이름으로 변경합니다.)

   ```bash
   s3://<my-artifact-bucket-name>/unicorn-web-build.zip
   ```
3. 개정 파일 유형을 **.zip**으로 선택하십시오 .

<figure><img src="https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2FYKrEt6uxnsp2idEEwuVJ%2Fimage.png?alt=media&#x26;token=95905dc1-f0e9-471e-85d1-9e00ed5f6386" alt=""><figcaption></figcaption></figure>

4\. 다른 설정은 기본값으로 두고 **배포만들기**를 클릭합니다 .

5\. 이제 배포가 시작됩니다. 배포 수명 주기 이벤트를 주시하고 성공적으로 완료되었는지 확인합니다.&#x20;

<figure><img src="https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2Fi3UMO8rzzkUm4cbx8tlc%2Fimage.png?alt=media&#x26;token=0785e00f-8da1-497e-8af0-b0346030ce28" alt=""><figcaption></figcaption></figure>

6\. **이제 EC2 인스턴스 콘솔로 이동해서** WebServer 인스턴스의 **IP를 복사해서 URL**에 붙여넣기 합니다.&#x20;

<figure><img src="https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2F4TzLDbQyOePt9oURttm4%2Fimage.png?alt=media&#x26;token=6303d65d-ca1a-4e08-8831-e21ef2bfdd81" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3028315059-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRxKEBgoW1BlesyWArOgq%2Fuploads%2F2DVntPYdsXPQGx3ac4Me%2Fimage.png?alt=media&#x26;token=5216850d-91b5-439f-919c-57fed3493d5c" alt=""><figcaption></figcaption></figure>

이제 애플리케이션을 빌드하고 배포할 수 있습니다. 하지만  현재 두 작업 모두 수동으로 트리거됩니다. CodeCommit의 변경으로 인해 트리거되는 전체 프로세스를 자동화하면 훨씬 더 좋을 것입니다. AWS CodePipeline을 소개합니다.
