DevOps課程-Configuration Management with Ansible 20
Project: Terraform & Ansible(外加Terraform執行Terraform與Ansible設置)
前面兩節課程中,我們是使用Terraform腳本建立被控機台並Output出IP位置
講師主控機使用Mac的ssh驅動Ansible操控被控機台
我是windows沒辦法,還特地開了一台EC2當作主控機
這邊就要嘗試Terraform建立被控機之後順便驅動Ansible進行相關建置
也就是從機台創建到機台被設定可運行服務一次自動化搞定!
首先到被控機Terraform腳本先移除當前的被控機
#到被控機的Terraform創建目錄下執行:
terraform destroy
(敲yes)
這時候看到該被控機腳本,其中關鍵有EC2機台建立:
其中我們有學過三種Provisioner:
- local-exec
- remote-exec
- file
這邊會使用到local-exec的Provisioner來達成自動驅動Ansible腳本
這是因為執行建立Ansible目標機的Terraform這台機台
同樣被當成Ansible主控機使用!!
所以我個人首先遇到的挑戰是我沒有Mac
我要讓我當成主控機的EC2可以拿到跑Terraform
大致上會有兩部分設定:
- 安裝並設置aws cli執行者身分
- 安裝Terraform
- 安裝Ansible(已安裝)
- 撰寫搬移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
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:
- local-exec
- remote-exec
- 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打開
deploy-docker-new-user.yaml開頭改為(開頭順便加入gather_facts False):
所以Terraform建立EC2那段就可以不需要睡150秒
執行後看到:
接著再遇上:
後來忘了是建置機的IP變了,防火牆問題
最後調整完成功:
當前的Terraform腳本main.tf是:
terraform.tfvars:
驅動的Ansible腳本:
其他暫時不紀錄
Using null_resource
使用null_resource:
這東西是用在我們可能尚未建立任何物件時候,但是又想驅動某些指令
可能是本機發動或是遠端發動
另外可以注意到有個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