---
# System prepended metadata

title: AWS CI/CD Pipeline
tags: [AWS, DevOps]

---

CI/CD Pipeline 為自定義
可彈性加入所需之Stage
並依需求選擇使用哪一項工具



# AWS CodePipeline
### 簡介

CI/CD Stages:
1. Source: Code Repository (Github、AWS CodeCommit、S3)
2. Build: 程式建置 (AWS CodeBuild、Jenkins)
3. Deploy: 程式部署 (AWS CodeDeploy) ，可部署到環境或DockerHub上

![image](https://hackmd.io/_uploads/B18PTzFPp.png)



### 實作
AWS CodeCommit 做為Repository
AWS CodeDeploy根據Code Source中包含的Script 部署靜態網頁到EC2
(此例部署靜態網頁，故略過Build Stage)

1. 建立IAM role
    給EC2使用
    -AmazonEC2RoleforAWSCodeDeploy
    -AmazonSSMManagedInstanceCore
    
2. 建立EC2
    作為部署環境
    Tag用來Attach which EC2 to be used to deploy
    後面Deploy設置會用到此Tag
    
3. 建立CodeCommit
    作為Repository
    上傳程式
    Sample Code:
    https://github.com/leefangyu/aws-codepipeline-s3-codedeploy-linux
    程式結構:
    ![image](https://hackmd.io/_uploads/BymAKMuva.png)


4. 設定CodeDeploy
此處設定Deploy Group來定義部署相關設定
在這裡選擇建立好的EC2 Tag
![image](https://hackmd.io/_uploads/rJqrHiIPT.png)

    在執行個體上安裝代理程式
Linux 執行個體已使用 SSM 代理程式設定，現在將以代理CodeDeploy程式進行更新。
![image](https://hackmd.io/_uploads/HyVQLoUP6.png)

5. 建立Pipeline
將前面建立的Stage串起來
![image](https://hackmd.io/_uploads/Skd8Pi8Dp.png)


6. 運行結果
![image](https://hackmd.io/_uploads/S1vOeT8Pa.png)

    ![image](https://hackmd.io/_uploads/HyTMka8PT.png)
    
    進行變更
    ![image](https://hackmd.io/_uploads/r1Oib6LDT.png)

    Trigger Pipeline 運行
    ![未命名](https://hackmd.io/_uploads/SJ-Xb68Dp.png)
    
    自動部署成功
    ![image](https://hackmd.io/_uploads/Sy9NW6IP6.png)


### Problem
* The overall deployment failed because too many individual instances failed deployment, too few healthy instances are available for deployment, or some instances in your deployment group are experiencing problems.
![image](https://hackmd.io/_uploads/ryXZ7aUvT.png)


    Solution:
-> 查看codedeploy-agent.service status
    ```
    sudo service codedeploy-agent status
    ```
    -> Unit codedeploy-agent.service not found.
    -> Install codedeploy-agent
    -> 確認codedeploy-agent運行中
    ![image](https://hackmd.io/_uploads/BJYXC3Uwa.png)


# Jenkins Pipeline in EC2
### 簡介
建立Jenkins Server 於EC2中
並在其建立Pipeline施行CI/CD

Code Source可使用多種Repository 
ex: Github、Gitlab、Azure DevOps(Microsoft TFS)、AWS CodeCommit
Build、Test、Deploy階段則以JenkinsFile作為腳本定義CI/CD行為
可部署到多種環境 ex: EC2、ECS、DockerHub

![image](https://hackmd.io/_uploads/H13Zh37_a.png)

### 實作
建立一Jenkins Freestyle Project 
透過SSH plugin連接將部署的AWS EC2
設定Pipeline自動部署Flask App到AWS EC2 by Docker

#### Set the Jenkins Server ready for pipeline

1. Launch EC2 Instance

2. Set the Security Group to let ur computer connect to Jenkins server via EC2 public IP:8080
SG inbound rules:
-http port 80
-ssh port 22
-custom tcp 8080 (Jenkins server port)

3. Install Jenkins on EC2

4. Log in to Jenkins by connecting public IP:8080
note:
無法從公司IP用port 8080進入Jenkins server

5. Install docker and Git on the same EC2 to let Jenkins use docker and Git

6. Set Jenkins to use sudo without password in Jenkins shell:
    ```
    sudo nano /etc/sudoers
    #add "jenkins ALL=(ALL) NOPASSWD: ALL" to sudoers
    ```

7. Install docker plugins in Jenkins:
-docker commons
-docker 
-docker pipeline
-docker-build-step

8. Install SSH plugin in Jenkins:
-Publish Over SSH

9. Set the SSH server for deployment:
->Manage Jenkins
->System Configuration
->System
->Publish over SSH
![image](https://hackmd.io/_uploads/ByFSgd9Oa.png)
->Add SSH Server
![image](https://hackmd.io/_uploads/S1GUxu9OT.png)

#### Start to set the pipeline
Build Step : Create image and push to DockerHub
Deploy Step : Pull the image from DockerHub and run container

1. New item
2. Create freestyle project
![image](https://hackmd.io/_uploads/Bkx9Ed9_T.png)

3. Configure
4. Source Code Management
->設定Code Repository
![image](https://hackmd.io/_uploads/Sk8A7dc_p.png)

5. Build Triggers
->設定觸發建置
Poll SCM 設輪詢時間定時檢查Source Code有無新Commit
![image](https://hackmd.io/_uploads/rkNJNu9_a.png)

6. Build Steps
->Execute shell
執行Build Commands
![image](https://hackmd.io/_uploads/SJKBNO9da.png)

7. Post-build Actions
->Send build artifacts over SSH
執行Deploy Commands
![image](https://hackmd.io/_uploads/BJGwVuq_T.png)

8. 運行結果
    ->可觀察每次Build的Console Output
![image](https://hackmd.io/_uploads/r1srBu5_T.png)

    ->部署完成
![image](https://hackmd.io/_uploads/B1ZtDv9_a.png)




# Reference

* Install CodeDeploy Agent:
https://docs.aws.amazon.com/codedeploy/latest/userguide/codedeploy-agent-operations-install-ubuntu.html

    https://mabdullahabid.medium.com/install-codedeploy-agent-for-ubuntu-server-6e87db526dba

* CodePipeline:
https://docs.aws.amazon.com/zh_tw/codepipeline/latest/userguide/tutorials-simple-codecommit.html

* Sample Code:
https://github.com/leefangyu/aws-codepipeline-s3-codedeploy-linux

* Jenkins in CodePipeline:
https://docs.aws.amazon.com/zh_tw/codepipeline/latest/userguide/tutorials-four-stage-pipeline.html

* Install Jenkins on AWS EC2:
https://www.jenkins.io/doc/tutorials/tutorial-for-installing-jenkins-on-AWS/

* SSH plugin in Jenkins:
https://www.thesunflowerlab.com/jenkins-aws-ec2-instance-ssh/