DevOps課程-Configuration Management with Ansible 25

Ansible Roles — Make your Ansible content more reusable and modular

ZONGRU Li
13 min readOct 24, 2023

這個課程會需要針對專案結構做改造,並且仍需要有Ansible主控機與被控機

所以順便整理主控機建置,都會用Terraform建立

到時候放到專案內TF-AnsibleController目錄

以下整理Ansible主控機+該機台充當Terraform建置機的Ubuntu機台指令

#Ansible主控機安裝以下Ansible工具(參考第二篇筆記):
sudo add-apt-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt-get install ansible

#Ansible主控機安裝AWS Cli工具(參考第20篇筆記整理):
sudo apt-get install unzip
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
#確認AWS Cli安裝:
aws --version
#設置aws執行身分:
aws configure
#依序填入(找當初建一般帳號拿到的檔案)
Access key ID
Secret access key
ap-northeast-1
json
#檢核:
aws configure list

#安裝Terraform(同樣參考第20篇筆記整理):
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
#確認:
which terraform
terraform -v

#直接在該機台產出key-pair(該機台使用者是ubuntu),第一個指令後enter三次,TF建被控機使用:
ssh-keygen -t rsa -b 2048
chmod 400 ~/.ssh/id_rsa

#安裝Python module管理工具pip(以下整理第21篇筆記):
sudo apt install python3-pip

#透過pip工具安裝跟AWS溝通用的module:
pip install boto3
pip install botocore

#之後編寫好ansible.cfg與inventory_aws_ec2.yaml可以執行:
ansible-inventory -i inventory_aws_ec2.yaml --list
ansible-inventory -i inventory_aws_ec2.yaml --graph

另外被控機則是放在專案內的TF-AnsibleHosts目錄,大概弄個兩台就夠了

Ansible Roles

這邊才開始課程內容,主要分以下幾個部分

What are Roles in Ansible?

What are the Use case?

Demo: create own Role

例如公司團隊選擇使用Ansible來自動化許多作業,例如:

  • Automate our Infrastructure
  • Automate our Networks
  • Automate our Applications

然後Ansible程式專案內會有越來越多Ansible腳本

變得越來越複雜混亂,難以維護

這邊就會需要引入"Role"

也就是分類不同Ansible腳本到roles裡面去管理

將數量過多的Ansible腳本分開管理

並且方便重複利用或分享給團隊

  • Role like a package for your tasks
  • Extracting tasks from Playbooks

而封裝而成的就是role

也就是多個Plays重複地包含了相同的tasks時

我們可以把這些tasks封裝成role,讓這些不同的Play直接調用role即可

  • Re-use role in different Plays
  • Much cleaner Plays

Role裡面主要包含:

  • Task that the role execute
  • Static Files that the role deploys
  • (Default) Variables for the tasks
  • Custom modules, which are used within this role
  • Like small applications
  • Easy to maintain and reuse
  • Standard file structure(easy to navigate)
  • Parameterize role, but execute without having to define variables
  • Possibility to overwrite default variables
  • Develop and test separately

在一般使用情況下,可以直接使用社群提供寫好的role

例如有人寫法建立MySQL的role,或是別人寫好建置Nginx的role

可以從community裡面找到這類role,來源大概有兩個:

  • Ansible GALAXY
  • Git Repository

Create Ansible Roles

接著課程就講怎麼把之前做好的以下專案目錄改成role的架構:

範例從deploy-docker-new-user.yaml開始改造

在這份Ansible腳本中有三大段:

1.安裝Python3,docker,docker-compose,docker python module

2.Create new linux user

3.Start docker containers

上面撰寫的內容是針對EC2開發的腳本

但是如果今天被控機台改開在Digital Ocean上面,可能只有1的部分要調整

但是2與3基本上會變成可重複在不同雲端機台執行的腳本動作

Like Functions

  • extract common logic
  • use function in different places with different parameters

首先複製一份deploy-docker-new-user.yaml

新的改叫做deploy-docker-with-roles.yaml

接著要創建一個必須固定名稱的目錄叫roles

在roles目錄的下一層接著再加開新的目錄(這層目錄名稱可以自行定義)

先定義兩個create_user與start_containers兩個子目錄在roles下面

而在這些自訂名稱的子目錄下接著建立固定名稱的目錄名稱叫:tasks

並在這些tasks目錄內建立main.yaml檔案

回到deploy-docker-with-roles.yaml

把上述剪下的內容貼到create_user裡面tasks裡面的main.yaml內

變成:

先把變數直接打上去,調整成:

同理,start_containers一樣調整:

Using Roles in Plays

在deploy-docker-with-roles.yaml中原本的play目前變成:

上面的tasks就要改呼叫roles(可以多筆role)變成:

另外注意到變數的部分,看到start_containers裡面

也就是roles裡面的tasks裡面的main.yaml內容有使用到變數

可以在Play那邊給予

另外檔案的部分

接著嘗試看看當前的腳本,先準備好被控機台

#確認一下機台群組名稱:
ansible-inventory -i inventory_aws_ec2.yaml --graph

如上,指定到tag_Name_dev_server

我在本機編輯完成後,先推到github,然後在主控機重新clone

#主控機上執行:
ansible-playbook deploy-docker-with-roles.yaml -i inventory_aws_ec2.yaml

(看到這邊一次成功我也嚇到,看來前面整理的準備指令很到位)

看到依然正常的執行結果

從主控機隨便ssh到其中一台被控機確認:

Complete our Roles

當前我們把必要執行多個module,寫到roles子目錄裡面tasks裡的main.yaml

其中剛剛提到的靜態檔案,也可以透過roles結構管理:

內容建立為:

這時候roles裡面tasks裡的main.yaml要引用到該檔案內容寫法改成:

可以注意到,新的src後面也不用寫什麼file/有的沒的

Ansible將會自動地對應到隔壁的files目錄去找到檔案

再次嘗試執行:

#主控機上執行:
ansible-playbook deploy-docker-with-roles.yaml -i inventory_aws_ec2.yaml

一樣正常!

Customize Roles with Variables

在Roles的架構模式下,上面的變數可以另外定義在Role目錄裡面

而不用直接如上圖hardcode在Role裡面的tasks裡面的main.yaml

以下為了更好呈現,會把註解打開:

改造完成後,有兩個變數來自roles裡面的vars目錄去定義

唯獨密碼還是來自專案上的變數檔案project-vars:

但是現在會有一個問題是

如果Roles目錄內的vars裡面也定義了docker_password這個變數

那結果到底Ansible用以哪一個變數優先呢?

這時候就要參考Ansible的Variable的Precedence

LINK

另外也可以設置變數的預設值,但是要定義到另一個子目錄叫defaults:

例如範例如下定義預設的變數為:

如果腳本一多,變數可能也會變得成千上百個

有一份defaults值的話,會相對方便作業

同理在create_user裡面也可以定義defaults的變數:

然而也可以直接在Play裡面給予變數值來取代default值:

以上Demo就完成了開頭的以下三個問題:

What are Roles in Ansible?

What are the Use case?

Demo: create own Role

相關專案內容會儲存到AnsibleRoles這個branchs內存放

參考課程reference

--

--

ZONGRU Li
ZONGRU Li

Written by ZONGRU Li

2022/11/17 開源部分個人筆記給LINE "Java程式語言討論區"社群,希望能對社群的技術學習做一點點貢獻.(掩面....記得退訂閱!

No responses yet