DevOps課程-Configuration Management with Ansible 21
Dynamic Inventory
考量到我們透過Ansible管理InfraStructure,是非常動態的
上面說法是指,機台常態地被新增或被刪除
例如有依據業務需求設置auto-sacling機制
如果像下面這樣hard code就不合理(以下都是一些學習建立的動態機台IP):
也就是要動態地提供上面的IP位置,甚至是多組IP
然後考慮到以前製作的另一份EC2的Terraform Code
是有使用到user_data:
上面那個user_data不重要
這邊會嘗試將調整建立3台EC2(兩台是micro,一台small)
然後執行Ansible腳本而不要hard code IP位置
最終調整成:
terraform.tfvars:
先在主控機上面嘗試執行,最後看到:
看起來沒問題後,先移除,順便調整一下機台Tag
轉去調整Ansible腳本部分,但是想辦法動態提供機台IP給Ansible
Inventory Plugin V.S. Inventory Scrip
要做到前面描述的事情,需要Ansible自行連線到AWS上面拿到IP資訊
並透過AWS帳號去拿到特定region上面的機台IP等資訊,主要手段有兩個
- Inventory Plugin
- Inventory Scrip
找到關鍵文件:
建議選擇"Plugin"主要原因有幾個因素:
- 這會使用到Ansible的功能例如STATE MANGMENT
- Inventory Plugin是用YAML
- Inventory Script則是Python
所以以下就會依據Inventory Plugin來建置
然後不論選擇Inventory Plugin還是Inventory Script
都會對應到不同的InfraStructure Provider而有所不同
#可以透過以下指令來查看有哪些plugin清單:
ansible-doc -t inventory -l
所以這邊就是要找到連結AWS的Inventory Plugin
最終找到:
中間很多參數解釋,往下滾也會看到使用範例:
重點在於還要Python的module支援:
其中boto3是Python與AWS溝通使用的library
Boto3=AWS SDK for python
所以在驅動Ansible的主控機台上一定要具備上面要求的Python module
沒有的話就要pip工具來安裝
另外Ansible中的ansible.cfg要加入以下設定來使用aws_ec2這個Plugin:
Write plugin configuration
除了上述ansible.cfg設定檔內要有啟用aws_ec2 plugin設置外
還要建立一個設定檔,並且有一個嚴格的限制是
檔名結尾必須是"aws_ec2"的yaml檔案
例如:
inventory_aws_ec2.yaml
填寫以下內容:
#執行指令可以確認ansible是否可以連結到AWS該region上的機台資訊:
ansible-inventory -i inventory_aws_ec2.yaml --list
我看到缺乏boto3與botocore的python套件的警告
所以這邊額外加裝上述python套件:
#執行以下pip工具指令:
pip install boto3
pip install botocore
所以還要先安裝pip工具
#執行安裝pip工具(過程要輸入y):
sudo apt install python3-pip
繼續安裝前面的python套件:
再次執行確認inventory_aws_ec2.yaml檔案設定的指令
#執行指令可以確認ansible是否可以連結到AWS該region上的機台資訊:
ansible-inventory -i inventory_aws_ec2.yaml --list
我這時候先將三台機台建置起來,再次重跑上述指令會看到:
也就是還沒連線到真的三個被控機台
而只是透過boto3 module來取得到AWS EC2機台資訊
#如果只是要簡短看到機台,可以改下:
ansible-inventory -i inventory_aws_ec2.yaml --graph
如上這些DNS資訊就將會是Ansible之後連線取用的機台資訊
Assign public DNS to EC2 instance
上面拿到的目前是Private DNS,直接在EC2網頁
如果想透過這一個Private DNS或著IP去連線,必須在相同VPC內:
所以這時候我注意到,我的主控機用的VPC跟被控機用的VPC是不同
所以看到連不通:
但是我建立的目標機三台是使用相同的VPC
嘗試進到其中一台目標機去ping隔壁台目標機會看到:
後來研究了解到,即便是使用相同的VPC或SG的兩個機台之間
預設AWS不會允許兩台用private IP或private DNS互相溝通
需要額外在SG的inbound內設置以下允許所有ICMP的設置:
ICMP(Internet Control Message Protocol)
然後就可以透過內部IP或內部DNS與相同VPC的其他機台溝通:
Private DNS部分則是看VPC有無啟用以下兩個屬性設置:
另外也參考到這篇stackoverflow解說(LINK)
然後也看到這篇(LINK):
所以調整被控機的VPC設定加入:
最後重建所有被控機資源(機台還有VPC)後
新的被控機之間就可以透過private DNS溝通:
所以這時候被控機的main.tf變成:
以上只是個人研究,課程這邊則是要想辦法讓被控機有Public DNS
如上面範例,被控機建立出來後的Public DNS都是空的:
但是其實解法也就是一樣的啟用VPC上的
enable_dns_support = true
調整重建後重建被控機看到:
再次用指令檢視
#如果只是要簡短看到機台DNS,可以改下:
ansible-inventory -i inventory_aws_ec2.yaml --graph
Configure Ansible to use dynamic inventory
接著就是要讓ansible腳本可以吃到前面定義的inventory_aws_ec2.yaml檔案
然後得到剛剛弄好的三台的Public DNS
在ansible.cfg設定中,原本會固定執行機台指定到hosts檔案:
腳本中原本指定的機台是:
現在則要調整成:
每一個Play都要改到
然後對我來說現在就出現問題了,我必須要過濾掉主控機那台
所以研究aws_ec2 inventory的文件寫法(LINK)
所以我重新調整被控機的TF程式碼,新增tag:
總之三台都加上述tag
然後調整inventory_aws_ec2.yaml
#再次指令檢視:
ansible-inventory -i inventory_aws_ec2.yaml --graph
如上圖,主控機的部分消失了
接著回到課程
在執行腳本操作被控機台的時候
我們必須指定使用者帳號與連線ssh key的部分
除了直接打到ansible-playbook指令後面參數之外
也可以全域地打在ansible設定檔內:
並且為了避免Ansible使用到上面設定檔設置的預設的hosts檔案
執行指令要指定機台檔案-i參數指定到"inventory_aws_ec2.yaml"
#從主控機上執行playbook腳本:
ansible-playbook -i inventory_aws_ec2.yaml deploy-docker-new-user.yaml
最後看到成功完成:
以上就是動態地給予被控機的方式去執行Ansible腳本作業
如果我這時候調整Terraform,立刻地新增了第四台被控機:
執行:
等建置好之後,執行ansible腳本
#再次從主控機上執行playbook腳本:
ansible-playbook -i inventory_aws_ec2.yaml deploy-docker-new-user.yaml
可以看到只異動了第四台:
另外為了不要每次都指定到inventory_aws_ec2.yaml檔案
也可以設置到ansible設定檔內:
#這時候再次執行可改為不帶指定被控機相關檔案:
ansible-playbook deploy-docker-new-user.yaml
Create dynamic groups
在使用aws_ec2的Plugin對應建立inventory_aws_ec2.yaml
還有個問題是只有aws_ec2這個機台群組,如果要多個?
例如講師的設置有兩台DEV,還有兩台PROD
但是希望Ansible可以同時指定到這兩種機台
#用以下指令檢視,卻只有aws_ec2這個機台群組:
ansible-inventory -i inventory_aws_ec2.yaml --graph
希望可以是:
這邊就可以在inventory_aws_ec2.yaml檔案改用keyed_groups
但是他的過濾條件會跟filters使用的attribute不一樣
要從以下清單指令的條件去過濾:
#清單指令中的資訊去過濾:
ansible-inventory -i inventory_aws_ec2.yaml --list
這邊先參考講師的設置重建成DEV與PROD的機台群組
首先簡單過濾tag:
#拿取分群用過濾資訊用:
ansible-inventory -i inventory_aws_ec2.yaml --list
#看機台群分類結果用:
ansible-inventory -i inventory_aws_ec2.yaml --graph
如上,群組變多了,只是名稱上多了一個下底線"_Name_dev_server":
如果要避免下底線,可以給前綴字
這時候調整Ansible腳本指定機台為tag_Name_dev_server:
#直接執行:
ansible-playbook deploy-docker-new-user.yaml
最終正常跑完:
只作用在AWS網頁上定義的有Tag是"dev-server"
對應到Ansible機台群組變成"tag_Name_dev_server"
在分群上,我們只用到tag來分群,範例也還有好多種:
例如
#拿取分群用過濾資訊用:
ansible-inventory -i inventory_aws_ec2.yaml --list
#看機台群分類結果用:
ansible-inventory -i inventory_aws_ec2.yaml --graph
以上即是Ansible動態指定雲端機台的基本方式