内容简介:因為一些緣故,要再次嘗試透過 Ansible 建立 Azure 的一些資源,於是重新踏入這個坑進行了一番研究。Azure 和其他雲端供應商一樣,提供的服務越來越多樣,同時也支援越來越多服務都能以 Infrastructure as Code 的方式創建與管理,不過既然是重新入坑,還是先從簡單的動作開始著手,首先嘗試以 Ansible 來建立一個 Azure Virtual machines。(本文同步發表於不管是使用哪一種 Infrastructure as Code 或 Configuration Ma
因為一些緣故,要再次嘗試透過 Ansible 建立 Azure 的一些資源,於是重新踏入這個坑進行了一番研究。Azure 和其他雲端供應商一樣,提供的服務越來越多樣,同時也支援越來越多服務都能以 Infrastructure as Code 的方式創建與管理,不過既然是重新入坑,還是先從簡單的動作開始著手,首先嘗試以 Ansible 來建立一個 Azure Virtual machines。
為 Ansible 取得必要的權限
不管是使用哪一種 Infrastructure as Code 或 Configuration Management 工具,如要透過 工具 直接管理或操作雲端服務,首先都要為工具取得必要的授權及權限。而目前在 Azure 和 Ansible 的官網上,皆已經有文件在教學如何透過 Ansible 來管理 Azure,但在查閱了數篇之後發現,Azure 能夠提供授權給 Ansible 使用的方式主要有兩種:
- Active Directory Username/Password
- Service Principal Credentials
而本文將會採用第二種「Service Principal Credentials」。
如果你打算按著文件,逐一步驟建立「Service Principal Credentials」,我可以預告你很有可能會遇見一個坑,那就是明明是按著文件圖文一步步地操作,但最終就是無法輕易找到下面這四個所需參數。
subscription_id=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx client_id=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx secret=xxxxxxxxxxxxxxxxx tenant=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
在嘗試幾種操作之後,個人發現目前最簡單的做法應該是這份文件提到的指令。
只要按著文件中說明的 Azure CLI 指令 az ad sp create-for-rbac
,即可順利透過它取得上述四個參數中的後三項。而最簡單執行 Azure CLI 的方式,則是透過 Azure portal 的 Cloud Shell。
只要登入 Azure portal,在點擊上方工具列 Cloud Shell 的 Icon 即可操作它。

如下圖,可以直接在瀏覽器操作 Cloud Shell,而其中已經內建安裝好各種 Commands。(貼心小提醒,Cloud Shell 一段時間沒操作就會自己斷線,因此要做任何操作時最好是一氣呵成為佳。)

因此我們就直接在 Cloud Shell 中執行指令來建立 Service principal。
az ad sp create-for-rbac --name YourServicePrincipalName --password YourPassword
(Service principal 除了用密碼驗證之外,還可以用 Key 驗證,這部分就請自行查看文件。)
沒意外應該就會出現類似下圖的結果,順利取得所需參數。

你也可以在 Azure Active Directory 的 App registrations 中,查看剛才建立的 Service principal。

取得所需的參數之後,我們準備回到 Ansible 這邊。
首先,請先確保你欲執行 ansible
的 Client 有安裝所需的 Ansible Azure 相關 Modules,按 Ansible 官方文件 說明,可以透過 pip
指令安裝。
pip install 'ansible[azure]'
接著利用前面取得的重要參數,建立 credentials
。
因為 Ansible 的 Azure Module 預設會直接查看 ~/.azure/
之下有沒有 credentials
的相關檔案。這裡我們就直接建立 ~/.azure/credentials
,然後將上述四個參數存放在內。
#建立資料夾與檔案 mkdir ~/.azure/ vim ~/.azure/credentials #檔案內容如下 [default] subscription_id=這個可以在 Azure portal 的 Subscriptions 找到。 client_id=就是前面透過 az 得到的 appId secret=就是前面透過 az 得到的 password tenant=就是前面透過 az 得到的 tenant
測試執行
既然 Ansible 已經擁有了權限,接著就來測試看看,首先有一個非常適合用來測試的 task,即是 Create resource group,如下所示。
# CreateResourceGroup.yml - hosts: localhost connection: local tasks: - name: Create resource group azure_rm_resourcegroup: name: YourResourceGroupName location: japanwest
Azure 提供了 Rresource group 的概念,你可以將單一專案所需的資源全都放在同一個 Resource group 內方便管理,因此要正式開始創建 Azure 的服務前,第一步就是要建立一個 Resource group。
(小提醒,如果想知道 location
有哪些選擇,可以在 Cloud Shell 輸入指令 az account list-locations
查詢。位於台灣,可以考慮選 japanwest
。)
將上述的 task 建立成 Ansible Playbook 之後,就執行 ansible-playbook
試試看吧!
ansible-playbook CreateResourceGroup.yml
如順利執行,應該在 Azure portal 的 Resource groups,即可看見剛才透過 Ansible 建立的 Resource group。

建立 Virtual Machines
最後,終於進入了我們的主要目標「透過 Ansible 建立 Azure Virtual Machines」。
不過雖然是建立 Virtual machine,但除了 VM 本身之外,還要建立其他所需的資源,包含了 Virtual Network、Subnet、Public IP、Network Security Group、Network Interface Card。
所以真正要使用的 Ansible Playbook,會如下所示,還需要加上好幾個 tasks。
- name: Create virtual network azure_rm_virtualnetwork: resource_group: AnsibleResourceGroup name: AnsibleVnet address_prefixes: "11.0.0.0/16" - name: Add subnet azure_rm_subnet: resource_group: AnsibleResourceGroup name: AnsibleSubnet address_prefix: "11.0.1.0/24" virtual_network: AnsibleVnet - name: Create public IP address azure_rm_publicipaddress: resource_group: AnsibleResourceGroup allocation_method: Static name: AnsiblePublicIP register: output_ip_address - name: Create Network Security Group azure_rm_securitygroup: resource_group: AnsibleResourceGroup name: AnsibleNetworkSecurityGroup rules: - name: SSH protocol: Tcp destination_port_range: 22 source_address_prefix: 請改成堡壘機IP access: Allow priority: 500 direction: Inbound - name: MySQL protocol: Tcp destination_port_range: 3306 source_address_prefix: 請改成堡壘機IP access: Allow priority: 501 direction: Inbound - name: HTTP protocol: Tcp destination_port_range: 80 access: Allow priority: 502 direction: Inbound - name: Create virtual network inteface card azure_rm_networkinterface: resource_group: AnsibleResourceGroup name: AnsibleNIC virtual_network: AnsibleVnet subnet: AnsibleSubnet public_ip_name: AnsiblePublicIP security_group: AnsibleNetworkSecurityGroup - name: Create VM azure_rm_virtualmachine: resource_group: AnsibleResourceGroup name: AnsibleVM vm_size: Standard_A1_v2 admin_username: 請改成你欲設置的使用者帳號 admin_password: 請改成你欲設置的密碼 network_interfaces: AnsibleNIC image: offer: UbuntuServer publisher: Canonical sku: '16.04-LTS' version: latest - name: Dump public IP for VM which will be created debug: msg: "The public IP is {{ output_ip_address.state.ip_address }}."
快速提一下幾個需要注意的要點。
首先,在透過 azure_rm_securitygroup
建立 Network Security Group 時,可以一併設置多個 rules。如上述範例,即直接設置了 port 22、3306、80 的 rules,其中 port 22 與 3306 還設置了必須透過固定 IP 的堡壘機才能連上。
利用 azure_rm_virtualmachine
建立 VM 時,需要指定 admin_username
、是否使用 Key 或密碼登入、 vm_size
與 image
。
上面的範例是設置 SSH 以密碼登入為主,如果想要改用 Key 登入,可以參閱 Ansible Module - azure_rm_virtualmachine 文件 設置。
如果要查詢你目前選擇的 Region 有哪些 VM Size 可以使用,可以透過 az
查詢。(請將 japanwest
換成你實際選擇的 region)
az vm list-sizes -l japanwest
或者也可以搭配官網文件查詢,Linux VM 可查看此 文件 ,Windows VM 則查看此 文件 。
而如果要查詢可以使用哪些 Image 來建立 VM,同樣可以透過 az
查詢,但 Image 很多,因此需要加上一些篩選條件,詳細的用法請自行查看 az vm image list -h
。
az vm image list --location japanwest -f Ubuntu --publisher Canonical --sku 16.04
會得到類似下圖的結果。

最後執行的 Ansible Playbook
- hosts: localhost connection: local tasks: - name: Create resource group azure_rm_resourcegroup: name: AnsibleResourceGroup location: japanwest - name: Create virtual network azure_rm_virtualnetwork: resource_group: AnsibleResourceGroup name: AnsibleVnet address_prefixes: "11.0.0.0/16" - name: Add subnet azure_rm_subnet: resource_group: AnsibleResourceGroup name: AnsibleSubnet address_prefix: "11.0.1.0/24" virtual_network: AnsibleVnet - name: Create public IP address azure_rm_publicipaddress: resource_group: AnsibleResourceGroup allocation_method: Static name: AnsiblePublicIP register: output_ip_address - name: Create Network Security Group azure_rm_securitygroup: resource_group: AnsibleResourceGroup name: AnsibleNetworkSecurityGroup rules: - name: SSH protocol: Tcp destination_port_range: 22 source_address_prefix: 請改成堡壘機IP access: Allow priority: 500 direction: Inbound - name: MySQL protocol: Tcp destination_port_range: 3306 source_address_prefix: 請改成堡壘機IP access: Allow priority: 501 direction: Inbound - name: HTTP protocol: Tcp destination_port_range: 80 access: Allow priority: 502 direction: Inbound - name: Create virtual network inteface card azure_rm_networkinterface: resource_group: AnsibleResourceGroup name: AnsibleNIC virtual_network: AnsibleVnet subnet: AnsibleSubnet public_ip_name: AnsiblePublicIP security_group: AnsibleNetworkSecurityGroup - name: Create VM azure_rm_virtualmachine: resource_group: AnsibleResourceGroup name: AnsibleVM vm_size: Standard_A1_v2 admin_username: 請改成你欲設置的使用者帳號 admin_password: 請改成你欲設置的密碼 network_interfaces: AnsibleNIC image: offer: UbuntuServer publisher: Canonical sku: '16.04-LTS' version: latest - name: Dump public IP for VM which will be created debug: msg: "The public IP is {{ output_ip_address.state.ip_address }}."
如果實驗完畢,想要刪除 Resource group,也同樣能透過 Playbook 達成。
- hosts: localhost connection: local tasks: - name: Delete Resource Group azure_rm_resourcegroup: name: AnsibleResourceGroup state: absent force: yes
Ansible Module 官方文件
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。