DevOps課程-Configuration Management with Ansible 20

Project: Terraform & Ansible(外加Terraform執行Terraform與Ansible設置)

ZONGRU Li
11 min readOct 17, 2023

前面兩節課程中,我們是使用Terraform腳本建立被控機台並Output出IP位置

講師主控機使用Mac的ssh驅動Ansible操控被控機台

我是windows沒辦法,還特地開了一台EC2當作主控機

這邊就要嘗試Terraform建立被控機之後順便驅動Ansible進行相關建置

也就是從機台創建到機台被設定可運行服務一次自動化搞定!

首先到被控機Terraform腳本先移除當前的被控機

#到被控機的Terraform創建目錄下執行:
terraform destroy
(敲yes)

這時候看到該被控機腳本,其中關鍵有EC2機台建立:

其中我們有學過三種Provisioner:

  1. local-exec
  2. remote-exec
  3. file

這邊會使用到local-exec的Provisioner來達成自動驅動Ansible腳本

這是因為執行建立Ansible目標機的Terraform這台機台

同樣被當成Ansible主控機使用!!

所以我個人首先遇到的挑戰是我沒有Mac

我要讓我當成主控機的EC2可以拿到跑Terraform

大致上會有兩部分設定:

  1. 安裝並設置aws cli執行者身分
  2. 安裝Terraform
  3. 安裝Ansible(已安裝)
  4. 撰寫搬移Terraform建置Ansible被控機腳本

1.安裝並設置aws cli執行者身分

#主控機Ubuntu上面執行:
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 --version
只放最後畫面
#執行設置aws身分:
aws configure

#依序填入(找當初建一般帳號拿到的檔案)
Access key ID
Secret access key
ap-northeast-1
json

#檢核:
aws configure list
只放最後畫面

2.安裝Terraform

照著下載區提示跑:

LINK

確認:

3.安裝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

4.撰寫搬移Terraform建置Ansible被控機腳本

這邊就要開始最困難的部分

我先嘗試在Ansible主控機上執行Terraform建立另一台EC2出來看看:

先建立terraform目錄:

放置公鑰:

調整變數名稱還有公鑰位置:

然後初始化:

嘗試建置看看:

putty也確實可以連:

先刪除:

另外建立被控機的TF程式專案,目光先集中在EC2建立:

前面提到有學過的三種Provisioner:

  1. local-exec
  2. remote-exec
  3. file

這邊將會使用"local-exec" Provisioner

用意是在Terraform機台上驅動執行腳本任務

就相當於我們在這台Ansible控制機執行Ansible去驅動Ansible被控機一樣!

但是現在有個問題是,TF建出來的機器IP是動態的

要有辦法傳到Ansible的host檔內去被控制

有一個解法就是ansible執行指令上面給

#類似這樣:
ansible-playbook --inventory {檔案或直接給IP位置}, playbook.yaml

#如上如果直接傳入IP,後面一定要逗號隔開,即便看起來很怪

在Terraform內傳入IP就變成如下:

另外尚有ansible_ssh_private_key_file的私鑰設定也一併在指令內提供

完全不吃hosts檔案的形式執行Ansible腳本

改成Terraform用變數給:

另外還要給Ansible驅動使用的被控機User:

也可以變數,但這邊就簡單示範

另一邊Ansible腳本也要調整,就是這裡:

這時候就是依據指令給的會跑下去,完全忽視hosts檔案

所有Play都要改!!

另外這邊有打錯,中間不是下底線,而是減號:

將必要修改好的Terraform腳本跟Ansible調整的腳本上傳到機台上:

我把前面嘗試建置的部分砍掉

#這邊需要補一次init:
terraform init
#執行建置:
terraform apply
#然後yes

過程會稍微久一點:

後來發現ansible的腳本有打錯的地方:

應該改成:

執行destroy後重來:

變成發生連線拒絕:

我後來自行調整成:

然後再撞到Ansible bug:

我對應在Ansible腳本增加了:

重新移除再次執行建置Terraform腳本看到:

如上淡灰色的是Ansible腳本的log

最後看到:

簡單來說就是忘了上傳這份:

至此我真的有點想為了Terraform還Mac...Holy Pig!

這邊docker-compose-full.yaml暫時註解需要帳號的image:

另外deploy-docker-new-user.yaml註解docker登入:

重來:

最終我把以下檔案完成改造

docker-compose-full.yaml檔案中需要講師docker hub帳密的Container註解

所以驅動的Ansible腳本-deploy-docker-new-user.yaml也調整增加註解

把需要帳密登入docker hub部分排除:

源頭驅動的Terraform則是增加了等待EC2機台建立的sleep 150秒

Wait for EC2 to be fully initialized

這邊又再次強調Terraform相關內容強調過的:

不建議使用provisioner!!

在前面嘗試中,我真的有試過只睡30秒

就可以接著執行provisioner驅動Ansible(可以連到被建被控機)

主要是等待EC2機台建立到可以被連線

但是後來穩定一點至少要等150秒

而這邊講師提供另一種Ansible解決這個問題的方案,調整Ansible腳本

加入使用wait_for module等待被建(被控)機台22 PORT打開

LINK

deploy-docker-new-user.yaml開頭改為(開頭順便加入gather_facts False):

所以Terraform建立EC2那段就可以不需要睡150秒

執行後看到:

接著再遇上:

後來忘了是建置機的IP變了,防火牆問題

最後調整完成功:

當前的Terraform腳本main.tf是:

terraform.tfvars:

驅動的Ansible腳本:

其他暫時不紀錄

Using null_resource

使用null_resource:

LINK

這東西是用在我們可能尚未建立任何物件時候,但是又想驅動某些指令

可能是本機發動或是遠端發動

另外可以注意到有個trigger可以指定等待EC2機台建置後

最終改成這樣:

執行後看到:

然後看到一樣結果:

最後移除上述資源後,再次紀錄當前Code

Terraform部分

main.tf:

terraform.tfvars:

Ansible部分:

deploy-docker-new-user.yaml:

ansible.cfg:

project-vars:

沒有用到的hosts:

備存到Git去

#然後執行以下動作創建新的local branch儲存到Github ansible這個Repo去:
git checkout -b TerraformAnsible
git add .
git commit -m "TerraformAnsible"
git push -u origin TerraformAnsible

參考課程reference

--

--

ZONGRU Li
ZONGRU Li

Written by ZONGRU Li

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

No responses yet