---
# System prepended metadata

title: '[架設個人文檔網站吧！]Github Action + S3 微型 CI/CD 實務'
tags: [S3, CD, git]

---

# Github Action + S3 微型 CI/CD 實務
:::info
前情提要我們建立了一個文檔網站並透過 Github 管理服務文件，進一步希望能結合版本控制和快速部署環境
:::

[TOC]
## 學習目的
上線的網站如有新的資訊希望修改，除了透過 github進行版本控制，也希望能節省未來更新作業的部署流程
構想使用Github + Action 組合建構一個微型的 CI/CD 流程，達成自動化部署更新環境

![github action cicd](https://hackmd.io/_uploads/HJrL9JRjT.png)


## 事前準備

需要準備以下內容：

1. AWS 帳號
2. Github 帳號
4. IDE tools


## Github Action 是什麼

GitHub Actions 是 GitHub 提供的一項功能，它允許自動化和客製化你的軟體開發工作流程。使用 GitHub Actions，可以在程式碼倉庫中設定各種操作（Actions），例如建置、測試、部署等，以回應各種事件，如程式碼推送、合併請求等。這使得整個軟體開發生命週期的自動化變得更加容易。 

核心是透過 YAML 檔案定義的工作流程（workflow）。每個工作流程由一個或多個作業（jobs）組成，每個作業又包含一系列的步驟（steps）。每個步驟代表一個單獨的任務，可以是執行命令、呼叫操作、或其他自訂操作。

## 建立 AWS 訪問金鑰
:::info
在前面我們為了讓 AWS S3 安全得只提供 Cloudfront 能夠訪問快取內容，設置了 cloudfront OAC 及限制了 S3 訪問權限。
我們需要讓 Github Action 能夠同步 push 上 Github 的文件
:::

建立 AWS IAM User，我們只需要連線的 access key，在最小訪問控制權限內，這裡不需要勾選 「Provide user access to the AWS Management Console」

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

選擇直接附加策略，搜尋 S3 可以到預設的 policy 有一筆 「AmazonS3FullAccess」，這邊預計使用到 s3 sync、delete 的動作選擇該權限，「Create User」完成建立

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

選擇創建好的 IAM User 接著要建立訪問金鑰，選擇「Security credentials」

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

建立 Access Key 選擇「Create access key」

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

這裡會看到一排使用 key 的建議，我們需要讓 Github Action 上的運行環境使用 AWS CLI，這裡需要選擇第一個透過 CLI 訪問

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

完成後會得到一組 Access key & Secret access key 將這組 key 記下後續會用到

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


## 建立 Github Action 訪問 key

首先我們將 AWS 的金鑰及 S3 Bucket 地址等 key&value 建立在 Github Repository secrets 裡
![image](https://hackmd.io/_uploads/HkbtqxCi6.png)

:::success
AWS accesskey Name 的值為：
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_S3_BUCKET_NAME
:::

## 建立 Github Action

先建一個 workflows 在專案裡建立一個 folder 命名為「.github/workflows」該目錄提供存放 workflows 運行環境 YAML 文件，工作結構參考如下圖：

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

:::success
參考閱讀 [Github Action](https://docs.github.com/en/actions/quickstart)
:::

了解工作結構後，接著我們要開始編寫需要讓 Action 做哪些事情，在專案目錄下的「.github/workflows」裡面建立 <example>.yaml 文件
    
![image](https://hackmd.io/_uploads/SJC8aVx26.png)

```yaml
//workflow 的名稱//
name: s3Sync
//定義工作流的觸發條件，工作流會在每次推送到 "main" 或 "master" 分支時觸發//
on: 
  push:
    branches:
      - main
      - master
//定義一個名為 "build" 的工作，將在最新版本的 Ubuntu 操作系統上運行，這裡使用提供的免費 GitHub-hosted runners //
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
//使用自定義行動 hannut91/aws-cli 的版本 1.18.43 來顯示 AWS 命令行界面（CLI）的版本//
      - name: version of aws-cli
        uses: hannut91/aws-cli@1.18.43
        with:
         args: --version

// 當前目錄的內容部署到 S3 存儲桶。並使用 AWS-Cli s3 sync 同步命令，刪除在 S3 存儲桶中存在但本地不存在的任何文件。使用環境變數 secrets 提供 AWS 憑證和區域作為環境變數。//
      - name: Deploy to S3
        uses: hannut91/aws-cli@1.18.43
        with:
         args: s3 sync . s3://${{ secrets.AWS_S3_BUCKET_NAME }}/ --delete
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_DEFAULT_REGION: ap-northeast-1
```
:::info
actions/checkout 是 GitHub Actions 中的一個預建動作，目的是將代碼存儲庫的內容檢出（checkout）到 GitHub Actions runner 的工作目錄中。這個動作通常是 GitHub Actions 工作流的一個開始階段，以確保工作目錄中包含代碼庫的最新版本。

具體動作執行以下操作：
clone 或 update 指定的存儲庫
檢出指定的提交或分支
:::
:::info
在同步到 AWS S3 時會需要使用到 AWS CLI 指令集，參考在 Github Action Marketplase 上人家製作好的 [hannut91/aws-cli@1.18.43](https://github.com/hannut91/aws-cli)
:::

## 自動部署驗證

重新修改內容後提交 git push，在Github 控制板上 Actions 裡面將會看到 workflows 有一筆剛剛建立的 name 正在運行，點選後可以看到正在運行的流程狀態

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

成功運行完部署後，可以看到整體流程都沒有報錯，並可以分析每個流程所消耗的時間

![image](https://hackmd.io/_uploads/By_4-sx36.png)

AWS S3 上查看檔案異動時間驗證已完成部署    

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

    
## 延伸閱讀

[Doscify 架設私有文檔網站](https://hackmd.io/Ep_qspD6QmOVGUyrE5eAbg)

[AWS S3+Cloudfront 建立靜態網站](https://hackmd.io/krdTdumATTWXnoCTxPaYJA)

[Git & Github 版本控制](https://hackmd.io/7eIaOpMpSt6OMaC_TVBKlA)

---