はじめに
AnsibleでAzureVMを操作できるか検証を行う機会があったので、その時の手順を自分メモとして残しておきたいと思います。
やったこと
- コントロールノードを CentOS7(Dockerコンテナ)
- ターゲットノードをAzureVM(CentOS7)2台
- ターゲットノードにNginxをインストールを行う
- Ansibleの「ダイナミックインベントリ」を使用する
以下のAzure 公式ドキュメントの内容をベースに進めていきました。
チュートリアル - Ansible を使用して Azure リソースの動的インベントリを構成する | Microsoft Docs
コントロール側のバージョン確認
- Docker Desktop for Windows (Version 3.3.1) / Docker Engine v20.10.5
- CentOS 7.9.2009
- Ansible 2.10.8
- Azure CLI 2.22.1
1. 事前準備
コントロールノード側に各種ツールをインストールしていきます。
・Ansibleインストール
Microsoft Azure 公式ドキュメントを見ながらインストールを行います。
参考URL:クイック スタート - Azure CLI を使用して Ansible を構成する | Microsoft Docs
・Azure CLI インストール
Azure CLIを使用して、リソースグループ作成・削除およびVM構築を行います。
こちらも、Microsoft Azure 公式ドキュメントを見ながらインストールを行います。
参考URL:Linux での Azure CLI の手動インストール | Microsoft Docs
2. SSH鍵を作成する
AzureVMにログインする際に使用する鍵を作成します。
パスフレーズ無しでansible_rsa
というファイル名で作成します。
ssh-keygen -m PEM -t rsa -b 2048 -f ~/.ssh/ansible_rsa -N ""
3. Azure リソースグループを作成する
AzureVMが属するリソースグループをmyAnsibleRG
という名前で作成します。
az group create --name myAnsibleRG --location japaneast
4. AzureVMを作成する
このVMが「ターゲットノード」ということになります。
SSH鍵は前工程で作成したansible_rsa
を指定します。
# 1台目
az vm create --resource-group myAnsibleRG --name myAnsibleVM01 --image OpenLogic:CentOS:7.7:latest --size Standard_B1s --admin-username azureuser --ssh-key-values ~/.ssh/ansible_rsa.pub
# 2台目
az vm create --resource-group myAnsibleRG --name myAnsibleVM02 --image OpenLogic:CentOS:7.7:latest --size Standard_B1s --admin-username azureuser --ssh-key-values ~/.ssh/ansible_rsa.pub
5. AzureVMにタグを付ける
タグ付けした方のVMにだけNginxをインストールさせようとしているため、1台目のVMにタグ付けを行います。
az resource tag --tags Ansible=nginx --id /subscriptions/<YourAzureSubscriptionID>/resourceGroups/myAnsibleRG/providers/Microsoft.Compute/virtualMachines/myAnsibleVM01
6. 80番ポートを開ける
Nginxがインストールされたかを確認するため、1台目のVMの80番ポートを事前に開けておきます。
az vm open-port --port 80 --resource-group myAnsibleRG --name myAnsibleVM01
7. Azure の資格情報(クレデンシャル)ファイルの作成
AnsibleにAzureの資格情報を提供するためのローカルのクレデンシャルファイルを作成します。
セキュリティの観点から環境変数を定義する方法が推奨されますが、今回は検証目的のためクレデンシャルファイルを作成しました。
まずcredentials
という名称のファイルを作成します。
mkdir ~/.azure
vi ~/.azure/credentials
ファイルの中身は以下の通りです。
※誤って公開することがないようにご注意ください。
[default]
subscription_id=<your-subscription_id>
client_id=<security-principal-appid>
secret=<security-principal-password>
tenant=<security-principal-tenant>
8. ダイナミックインベントリの生成
インベントリはテキストファイルにターゲットノードの情報を定義して管理することもできるのですが、接続先のIPアドレスやホスト名がほぼ固定であるオンプレミス環境ならば問題ありませんが、クラウドでは頻繁にインスタンス(EC2やAzureVM)の追加や削除が発生するため、そのたびにインベントリファイルを更新するのは現実的ではありません。
そこで、スクリプトを使用してAPI経由でダイナミック(動的)にターゲットノードの情報を取得するのがダイナミックインベントリと呼ばれる仕組みです。
ダイナミックインベントリはazure_rm
という名称で終わる必要のあるYAMLファイルになります。
今回はmyazure_rm.yml
として保存しています。
plugin: azure_rm
include_vm_resource_groups:
- myAnsibleRG
auth_source: auto
keyed_groups:
- prefix: tag
key: tags
9. VMへの接続テスト
ソースグループ内のVMをpingしてみます。
ansible all -i ./myazure_rm.yml -m ping --private-key=~/.ssh/ansible_rsa -u azureuser
以下のような結果が表示され、VM2台ともに接続できていることが分かります。
myAnsibleVM01_500a | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
myAnsibleVM02_0c1a | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10. 設定済みのインベントリを確認する
設定済みのインベントリを確認します。
ansible-inventory -i myazure_rm.yml --graph
@all:
|--@tag_Ansible_nginx:
| |--myAnsibleVM01_500a
|--@ungrouped:
| |--myAnsibleVM02_0c1a
@tag_Ansible_nginx
を指定することで、1台目のVMへの接続をテストすることもできます。
ansible -i ./myazure_rm.yml -m ping --private-key=~/.ssh/ansible_rsa -u azureuser tag_Ansible_nginx
11. プレイブックを作成する
Nginxをインストールするためのプレイブックをnginx.yml
として作成します。
---
- name: Install and start Nginx on an Azure virtual machine
hosts: all
become: yes
tasks:
- name: Add Nginx Yum Repository
yum_repository:
name: nginx
description: nginx repo
baseurl: http://nginx.org/packages/mainline/centos/7/$basearch/
owner: root
gpgcheck: no
enabled: yes
state: present
- name: Install nginx
yum: name=nginx state=present
notify:
- start nginx
handlers:
- name: start nginx
service: name=nginx state=started
12.Nginxのインストールと動作確認
プレイブックを実行して Nginx のインストールを行います。
1台目のVMにのみインストールできることを確認するため--limit
を指定しています。
ansible-playbook -i ./myazure_rm.yml --private-key=~/.ssh/ansible_rsa -u azureuser nginx.yml --limit=tag_Ansible_nginx
Nginxがインストールされたことを確認します。 
また、2台目のVMにログインして Nginx がインストールされていないことを確認します。
[azureuser@myAnsibleVM02 ~]$ nginx -V
-bash: nginx: command not found
13. リソースのクリーンアップ
検証に使用したAzureリソースたちの後片付けを行って検証終了です。
az group delete --name myAnsibleRG
【おまけ】検証中にハマったところ
接続テストの際にエラーが出てしまい軽くハマってしまいました。
# これだとエラー
ansible -i ./myazure_rm.yml -m ping tag_Ansible_nginx
myAnsibleVM01_500a | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).",
"unreachable": true
}
今回の検証ではSSH鍵をansible_rsa
という名称で作成していたので、その鍵を明示的に指定する必要があります。
# SSH鍵を明示的に指定する
ansible -i ./myazure_rm.yml -m ping --private-key=~/.ssh/ansible_rsa tag_Ansible_nginx
myAnsibleVM01_500a | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"module_stderr": "Shared connection to 20.xxx.xxx.xxx closed.\r\n",
"module_stdout": "Please login as the user \"azureuser\" rather than the user \"root\".\r\n\r\n",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
"rc": 0
}
それでもまだエラーが出るのですが、azureuser
でログインするようにメッセージが出ているため、azureuserを指定するようにしてみます。
# SSH鍵を明示的に指定しつつ、azureuserでログインする
ansible -i ./myazure_rm.yml -m ping --private-key=~/.ssh/ansible_rsa -u azureuser tag_Ansible_nginx
myAnsibleVM01_500a | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
ようやく、エラーが解消されました。
以上です。