はじめに
IaC(Infrastructure as Code)が叫ばれだして久しい昨今、みなさんどんなツールをお使いでしょうか。
Terraform?ARMテンプレート?はたまたBicepでしょうか。
本記事では、Ansibleを利用してのAKS操作を試してみた記録をまとめます。
環境
本記事の内容は、Azure Cloud Shell(Bash版)上で実行しました。
$ ansible --version
ansible 2.10.2
config file = None
configured module search path = ['/home/ussvgr/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /opt/ansible/lib/python3.7/site-packages/ansible
executable location = /opt/ansible/bin/ansible
python version = 3.7.3 (default, Jul 25 2020, 13:03:44) [GCC 8.3.0]
準備:Collectionのインストール(バージョンアップ)
Cloud Shell上の環境には、AnsibleでAzureリソースを操作するためのモジュールがデフォルトで導入済みです。
が、いささかバージョンが古いのでバージョンアップしておきます。(2021/10/31時点の情報です)
導入済みのCollectionのバージョンは、以下の通り1.2.0のようです。(CHANGELOG.mdファイルの最新の記述から確認)
$ head /opt/ansible/lib/python3.7/site-packages/ansible_collections/azure/azcollection/CHANGELOG.md
# Change Log
## v1.2.0 (2020-10-09)
### NEW MODULES
- azure_rm_backupazurevm ([#248](https://github.com/ansible-collections/azure/pull/248))
- azure_rm_backupazurevm_info ([#248](https://github.com/ansible-collections/azure/pull/248))
- azure_rm_recoveryservicesvault ([#254](https://github.com/ansible-collections/azure/pull/254))
- azure_rm_openshiftmanagedcluster ([#276](https://github.com/ansible-collections/azure/pull/276))
ansible-galaxyコマンドで最新のCollectionをインストールします。
$ ansible-galaxy collection install azure.azcollection
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'azure.azcollection:1.10.0' to '/home/ussvgr/.ansible/collections/ansible_collections/azure/azcollection'
Downloading https://galaxy.ansible.com/download/azure-azcollection-1.10.0.tar.gz to /home/ussvgr/.ansible/tmp/ansible-local-1517j3twu3a/tmpo_e77nln
azure.azcollection (1.10.0) was installed successfully
v.1.10.0がインストールされました。
最小のPlaybookでAKSクラスターを作成する
Azure公式にもAnsibleでAKSクラスターを作成するドキュメントがありますが、こちらに記載されているサンプルのPlaybookはazure.azcollectionのv1.2.0を前提として記述されています。
最新のバージョンではサービスプリンシパルやノードのSSH keyを省略可能なため、ただクラスタを作成するだけなら以下のように簡略化できます。
(サービスプリンシパル未指定時はマネージドIDで作成されます)
- name: Create Azure Kubernetes Service
hosts: localhost
connection: local
tasks:
- name: Create resource group
azure.azcollection.azure_rm_resourcegroup:
name: aks_rg
location: japaneast
- name: Create AKS Cluster
azure.azcollection.azure_rm_aks:
name: akstest
kubernetes_version: 1.20.7
location: japaneast
resource_group: aks_rg
dns_prefix: akstest
agent_pool_profiles:
- name: agentpool1
mode: System
count: 1
vm_size: Standard_D2_v2
ansible-playbookコマンドを実行します。
$ ansible-playbook aks.yaml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Create Azure Kubernetes Service] *********************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************************************
ok: [localhost]
TASK [Create resource group] *******************************************************************************************************************************************************
changed: [localhost]
TASK [Create AKS Cluster] **********************************************************************************************************************************************************
[WARNING]: Azure API profile latest does not define an entry for ContainerServiceClient
changed: [localhost]
PLAY RECAP *************************************************************************************************************************************************************************
localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ノードのスケールアウト
ノードの数を1として作成しましたが、これを2台にスケールアウトさせます。
agent_pool_profiles:
- name: agentpool1
mode: System
count: 2
vm_size: Standard_D2_v2
先程のPlaybookのagent_pool_profiles内のcountを1から2へ変更しました。
再度ansible-playbookコマンドを実行します。
$ ansible-playbook aks.yaml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Create Azure Kubernetes Service] *********************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************************************
ok: [localhost]
TASK [Create resource group] *******************************************************************************************************************************************************
ok: [localhost]
TASK [Create AKS Cluster] **********************************************************************************************************************************************************
[WARNING]: Azure API profile latest does not define an entry for ContainerServiceClient
changed: [localhost]
PLAY RECAP *************************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
適用途中の状態
ansible-playbookコマンドが完了すると全ノードが準備完了になりました。
countの値を再度1に戻して適用すればスケールインされます。
ノードのスケールアップ(SKUの変更)
ノードのサイズを変更してみます。
先程のPlaybookのagent_pool_profiles内のvm_sizeを「Standard_D2_v2」から「Standard_D3_v2」へ変更しました。
agent_pool_profiles:
- name: agentpool1
mode: System
count: 1
vm_size: Standard_D3_v2
$ ansible-playbook aks.yaml
〜略〜
TASK [Create AKS Cluster] **********************************************************************************************************************************************************
[WARNING]: Azure API profile latest does not define an entry for ContainerServiceClient
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Error creating the AKS instance: Operation failed with status: 'Bad Request'. Details: Changing property 'agentPoolProfile.vmSize' is not allowed."}
PLAY RECAP *************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
これはエラーになってしまいました。既存のノードプールのVMサイズを直接変更することはできないようです。
では、新規サイズのノードプールを一旦追加、追加が完了したら旧ノードプールを削除、という形で実行してみます。
元のagentpool1のサイズは「Standard_D2_v2」のまま、新たにagentpool2を追加しました。
agent_pool_profiles:
- name: agentpool1
mode: System
count: 1
vm_size: Standard_D2_v2
- name: agentpool2
mode: System
count: 1
vm_size: Standard_D3_v2
$ ansible-playbook aks.yaml
〜略〜
PLAY RECAP *************************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Playbookからagentpool1の記述を削除し再度実行。
agent_pool_profiles:
- name: agentpool2
mode: System
count: 1
vm_size: Standard_D3_v2
$ ansible-playbook aks.yaml
〜略〜
PLAY RECAP *************************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
「Standard_D3_v2」のagentpool2だけが残る形となり、スケールアップの目的は果たせました。
AKSクラスターのバージョンアップ
最初のPlaybookでKubernetesのバージョンを1.20.7で作成しましたが、これのバージョンアップを行います。
azure.azcollection.azure_rm_aks:
name: akstest
kubernetes_version: 1.20.9
location: japaneast
resource_group: aks_rg
dns_prefix: akstest
kubernetes_versionの値を書き換えてansible-playbookを実行します。
$ ansible-playbook aks.yaml
〜略〜
PLAY RECAP *************************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
以下のようにAPIサーバー・ノードプールともに1.20.9になりました。
また、Ansibleのモジュールにはazure_rm_aksupgrade_infoという、指定したAKSクラスターのバージョンアップ可能な対象バージョン一覧を取得するモジュールがあります。
以下のようなPlaybookを作成し実行します。
- name: Get available upgrade version for AKS instance
hosts: localhost
connection: local
tasks:
- name: Get available upgrade version
azure.azcollection.azure_rm_aksupgrade_info:
name: akstest
resource_group: aks_rg
register: upgradable_version
- name: Show Versions
debug:
msg: "{{ upgradable_version }}"
$ ansible-playbook aksupgrade_info.yaml
〜略〜
TASK [Get available upgrade version] ***********************************************************************************************************************************************
[WARNING]: Azure API profile latest does not define an entry for ContainerServiceClient
ok: [localhost]
TASK [Show Versions] ***************************************************************************************************************************************************************
ok: [localhost] => {
"msg": {
"azure_aks_upgrades": {
"agent_pool_profiles": null,
"control_plane_profile": {
"kubernetes_version": "1.20.9",
"name": null,
"os_type": "Linux",
"upgrades": [
{
"is_preview": null,
"kubernetes_version": "1.21.1"
},
{
"is_preview": null,
"kubernetes_version": "1.21.2"
}
]
}
},
"changed": false,
"failed": false,
"warnings": [
"Azure API profile latest does not define an entry for ContainerServiceClient"
]
}
}
PLAY RECAP *************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
1.20.9からのバージョンアップ可能バージョンは、1.21.1と1.21.2の2つであると確認できます。
これを組み合わせ、以下のように「指定できる最大のバージョンにアップグレード」というPlaybookを書くこともできます。
- name: Upgrade version for AKS instance
hosts: localhost
connection: local
tasks:
- name: Get available upgrade version
azure.azcollection.azure_rm_aksupgrade_info:
name: akstest
resource_group: aks_rg
register: upgradable_version
- name: Upgrade AKS Cluster
azure.azcollection.azure_rm_aks:
name: akstest
kubernetes_version: "{{ upgradable_version.azure_aks_upgrades.control_plane_profile.upgrades[-1].kubernetes_version }}"
location: japaneast
resource_group: aks_rg
dns_prefix: akstest
agent_pool_profiles:
- name: agentpool2
mode: System
count: 1
vm_size: Standard_D3_v2
AKSクラスターの削除
以下のPlaybookでAKSクラスターを削除できます。
- name: Delete AKS instance
hosts: localhost
connection: local
tasks:
- name: Delete AKS Cluster
azure.azcollection.azure_rm_aks:
name: akstest
resource_group: aks_rg
state: absent
$ ansible-playbook aks_delete.yaml
〜略〜
TASK [Delete AKS Cluster] **********************************************************************************************************************************************************
[WARNING]: Azure API profile latest does not define an entry for ContainerServiceClient
changed: [localhost]
PLAY RECAP *************************************************************************************************************************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
おわりに
AnsibleでもAKSに対するいろんな操作が可能でした。
ドキュメント見る限りもっと細かくAKSクラスターのオプションを指定可能なようなので、引き続き触ってみます。