読者です 読者をやめる 読者になる 読者になる

銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

Ansible で Azure を操作する

Ansibleのバージョン2.1がリリースされましたが、その中でもAzureとWindows対応が一つの目玉になっています。

www.redhat.com

www.ansible.com

というわけでAnsibleを使ってAzureに仮想マシンを立ててみたいと思います。

Ansibleはまだまだドキュメントが少なくて苦労したのですが、Azureに関してはこのページがまとまっています。

Getting Started with Azure — Ansible Documentation

準備

Ansibleのインストールですが、最新のARMに対応したモジュールを使うために2.1を使いたいので、GitHubからコードをcloneしてビルドしたrpmをインストールします。 Installation — Ansible Documentation

$ sudo yum install rpm-build make asciidoc git python-setuptools python2-devel
$ git clone git://github.com/ansible/ansible.git --recursive
$ cd ./ansible
$ make rpm
$ sudo yum install ./rpm-build/ansible-*.noarch.rpm


$ ansible --version
ansible 2.1.0.0 

つぎに、Azure Python SDK の2.0以降をいれます。libffi-develを入れておかないとエラーになった気がします。

$ sudo yum install libffi-devel 
$ pip install azure==2.0.0rc2

認証情報の設定

Azure を操作するということで、APIの認証情報の設定が必要です。Azure Portalにログインするときに使うAADのユーザーとパスワードでもいいのですが、それをファイルに書いておいておくのは危険だろうということで、Service Principalを使う方法が紹介されています。

azure.microsoft.com

このAzureのドキュメントに従って、旧ポータルで作成します。AADで認証するWebアプリを作ったことのある方にはわりとお馴染の手順です。サインオンURLとアプリケーションIDは存在しないURLを指定して問題ありません。作成したら、アプリケーションのクライアントIDとテナントIDをコピーしておきます。その後、認証キーを作成してキーもコピーしておきます。

その後、新ポータルに戻って、いま作成したService Principalに適当な権限を与えます。テスト目的であれば、サブスクリプションに対してService Principalを追加して、共同管理者権限を与えればよいでしょう。このときついでに、サブスクリプションIDもコピーしておきます。

最後に、Ansibleを実行するユーザーの$HOME/.azure/credentialsにコピーした情報を保存しておきます。

[default]
subscription_id=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
client_id=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
secret=xxxxxxxxxxxxxxxxx
tenant=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Playbookの作成と実行

Ansibleで操作する内容を記述するPlaybookを作成します。プロパティの詳細はこのページに書いてあります。

azure_rm_virtualmachine - Manage Azure virtual machines. — Ansible Documentation

良く似た名前で古いモジュールもありますが、こちらはAzure Management Certificateが必要になります。

azure - create or terminate a virtual machine in azure — Ansible Documentation

Playbookの一例です。

- hosts: all
  connection: local
  tasks:
  - name: Create storage account
    azure_rm_storageaccount:
      resource_group: ansible
      name: testaccount123
      account_type: Standard_LRS

  - name: Create virtual network
    azure_rm_virtualnetwork:
      resource_group: ansible
      name: testvn001
      address_prefixes: "10.10.0.0/16"

  - name: Add subnet
    azure_rm_subnet:
      resource_group: ansible
      name: subnet001
      address_prefix: "10.10.0.0/24"
      virtual_network: testvn001

  - name: Create public ip
    azure_rm_publicipaddress:
      resource_group: ansible
      allocation_method: Dynamic
      name: publicip001

  - name: Create NIC
    azure_rm_networkinterface:
      resource_group: ansible
      name: testnic001
      virtual_network: testvn001
      subnet: subnet001
      public_ip_name: publicip001

  - name: Create virtual machine
    azure_rm_virtualmachine:
      resource_group: ansible
      name: testwinvm001
      vm_size: Basic_A2
      storage_account: testaccount123
      storage_container: testvm001
      storage_blob: testvm001.vhd
      admin_username: admin12345
      admin_password: password12345!
      network_interfaces: testnic001
      image:
        offer: WindowsServer
        publisher: MicrosoftWindowsServer
        sku: Windows-Server-Technical-Preview
        version: 5.0.20160420
      os_type: Windows

作成する仮想マシンのイメージの詳細はAzure CLIを使うと取得できます。

$ azure vm image list-publishers -l <location>
$ azure vm image list-offers -l <location> -p <publisher>
$ azure vm image list -l <location> -p <publisher> -o <offer>

最後に、/etc/ansible/hostsにlocalhostを追加してPlaybook実行します。

$ ansible-playbook createvm.yml 

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [Create storage account] **************************************************
ok: [localhost]

TASK [Create virtual network] **************************************************
changed: [localhost]

TASK [Add subnet] **************************************************************
changed: [localhost]

TASK [Create public ip] ********************************************************
changed: [localhost]

TASK [Create NIC] **************************************************************
changed: [localhost]

TASK [Create virtual machine] **************************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=7    changed=5    unreachable=0    failed=0  

なお、この実行結果はすでにストレージアカウントを作成ずみの場合のものです。Ansibleは状態を確認しながらあるべき状態に設定するので、作成済みの場合は何もしません。また、デフォルトでは処理が完了するのを待機するのですが、ストレージアカウントや仮想マシンの作成はアクセスできるまで待機するので非常に時間がかかります。