iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0
DevOps

不想吃土嗎?就利用開源軟體打造CICD Pipeline吧!系列 第 28

Day 28: Ansible番外篇!Ansible Vault!

  • 分享至 

  • xImage
  •  

來到了鐵人賽的最後三天,讓我們為我們的CICD Pipeline加入更多的功能吧!

這二十多天以來,我們一直都利用Jenkins的Credentials功能去儲存所有服務的連接認證。如果我們所儲存的認證是用於CICD部署方面,這個做法是非常合理的。

但是有一些情況,我們需要有一個安全的地方去儲存程式內部使用的重要資料。例如跟其他服務的API金鑰,又或是其他一些重要的檔案。這個時候,單靠Jenkins的Credentials功能可能就不太合適了。

因此,我們今日會嘗試利用Ansible其中一個功能,Ansible Vault,去把一些程式內部的機密資料加密,然後再應用到我們開發的程序上面。

更新我們的專案

首先,我們假設我們的專案有一個頁面,需要在GET的時候傳入password這個Query參數。如果傳入的參數等於我們設定的密碼,那麼我們才返回Hello World!,否則則傳回404的頁面。

app.js中更改為以下內容。

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
    const secret = process.env.SECRET_PASSWORD;
    if (req.query.password === secret) {
        res.send('Hello World!')
    } else {
        res.sendStatus(404);
    }
})

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`)
})

其中一行const secret = process.env.SECRET_PASSWORD代表我們從環境變數中取得SECRET_PASSWORD這個值,然後再在下面的判斷式中進行比對。如果密碼正確就返回Hello World!的內容。

然後在Terminal中運行以下指令。

SECRET_PASSWORD=secret node app.js

SECRET_PASSWORD=secret代表我們要把secret作為我們的密碼傳入環境變數中,讓我們的程式取得其值。

運行成功後用瀏覽器登入http://localhost:3000,應該會返回404。然後登入http://localhost:3000?password=secret,應該可以返回Hello World!

更新Playbook

由於我們在專案中加入了環境變數去傳遞我們的密碼。因此我們利用Ansible去進行步署時,亦必須傳入這個環境變數。

因此,在Deploy docker這個部份,加入以下內容去傳入環境變數。

        env:
          SECRET_PASSWORD: "{{ secret_password }}"
  • {{ secret_password}}: 一會我們會把密碼從加密了的變數文件中取得並傳入此變數中

然後,我們在vars_file的部份中加入一個新的變數檔案secret.yml,變成以下內容。

  vars_files:
    - vars.yml
    - secret.yml

(完整的main.yml可參考附錄)

然後我們在專案中新增一個secret.yml,並以YAML的格式加入我們的密碼。

secret_password: secret

然後,我們要利用Ansible Vault去對secret.yml進行加密。在Terminal中輸入以下指令。

ansible-vault encrypt secret.yml

輸入指令後,Ansible Vault會要求你輸入你的加密密碼。輸入以後即可為secret.yml進行加密。

加密完成後,打開secret.yml,應該會變成類似以下的內容。

$ANSIBLE_VAULT;1.1;AES256
61636633646161316633643562373232363532313134663065323361343831393339343038333164
6463383433643965643435393634313838373834373161310a663763346232396431333638366565
65666530646635343130346331303439383132646566613236616331383833343961323663393033
6634386434363337340a353932366633666237613465316332663261663630383934383339643733
65313465643465366432316661653966333666373439616365303532393161393963

這個就是利用了Ansible Vault進行過加密後的檔案,這個加密後的檔案可以上傳到版本管理系統讓CICD Pipeline讀取。當我們需要把類似的機密資料部署到伺服器上,但又不想資料被人存取或修改時。Ansible Vault就可以在此起到作用了。

下一步,我們嘗試在本機運行Ansible,同時利用Ansible Vault解密我們的秘密密碼。在Terminal中運行以下指令。

ansible-playbook -i "{VM_EXTERNAL_IP}", main.yml -u {USERNAME} --private-key {SSH_PRIVATE_KEY} --ask-vault-pass
  • {SSH_PRIVATE_KEY}: Private Key的檔案位罝
  • {USERNAME}: 用戶名稱
  • {VM_EXTERNAL_IP}: VM的公共IP位址
  • --ask-vault-pass: 輸入加密密碼並解密所需檔案

然後應該會要求你輸入Vault的密碼。輸入成功後應該可以看到成功部署。

小結

今天,我們成功利用Ansible Vault把機密資料部署到伺服器上。明天,我們又是例行工作,把整個過程自動化起來了!

附錄 – 完整的Ansible Playbook檔案

---
- hosts: all
  become: true
  vars:
    ansible_python_interpreter: /usr/bin/python3
  vars_files:
    - vars.yml
    - secret.yml
  tasks:
    - name: Test Sever Connection
      ping:

    - name: Install dependencies
      apt:
        name: "{{ item }}"
        state: latest
        update_cache: true
      loop: "{{ docker_dependencies }}"

    - name: Add docker's official GPG key
      apt_key:
        url: https://download.docker.com/linux/debian/gpg
        state: present

    - name: Add docker repository
      apt_repository:
        repo: deb [signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bullseye stable
        state: present

    - name: Install docker engine
      apt:
        name: "{{ item }}"
        state: latest
        update_cache: true
      loop: "{{ docker_engines }}"

    - name: Verify docker installation
      become: true
      command: docker run --rm hello-world

    - name: Log into harbor registry
      docker_login:
        registry_url: {IMAGE_REGISTRY}
        username: {HARBOR_USERNAME}
        password: {HARBOR PASSWORD}
        reauthorize: yes

    - name: Deploy docker
      docker_container:
        name: "ironman-helloworld"
        image: {IMAGE_REGISTRY}/ironman-helloworld:1.0.0
        state: started
        restart: yes
        pull: yes
        ports:
          - "80:3000"
        env:
          SECRET_PASSWORD: "{{ secret_password }}"

題外話

看到終點了,應該可以毫無疑問成功完賽了!


上一篇
Day 27: Ansible最終回!與Jenkins共舞!
下一篇
Day 29: Ansible鐵人賽特別篇!Ansible Vault與Jenkins聯乘自動化!
系列文
不想吃土嗎?就利用開源軟體打造CICD Pipeline吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言