OpenStackとAnsible Towerでメリークリスマス

OpenStackとAnsible Towerでメリークリスマス

みなさんメリークリスマス。 この記事は、OpenStack Advent Calendar 2016の25日目の記事です。

OpenStack Advent Calendar 2016 最終日の今日は、OpenStack管理下にインスタンスを作成する際に、Ansible Towerを利用してPlaybookを適用する方法を紹介します。

OpenStackとAnsibleとAnsible Tower

OpenStack

OpenStackは、言わずと知れたクラウド基盤管理システムです。オープンな開発コミュニティ、そして全ての機能を外部から管理可能な、オープンなAPIを持っています。

このAPIを利用することで、従来のオンプレミスな仮想化基盤では難しかった、CI/CDに代表されるツールチェーンのような仕組みをインフラ分野にも適用することが可能となます。いわゆるInfrastructure as Codeを実現するのに、OpenStackが一役買ってくれるという訳ですね。

Ansible

Ansibleは、現代を代表するITオートメーションツールです。コア部分の実体は、単なるコマンドラインツールなのですが、この単純でシンプルな構造が非常に使い勝手が良く、運用の現場での利用が急速に進んでいます。

世の中では利点ばかりが強調されがちですが、シンプルであるがゆえに、Ansibleのコア部分が削ぎ落とした機能がいくつかあります。 実際に運用していると、サーバのオートスケール時の自動構築や、ツールチェーンに組み込みたい場合、そしてシステム監査のような場面で、以下の3点は、なにか対策があるといいのになぁと思ってりしています。

  1. 外部APIを持っていない
  2. コマンドの実行権限管理はOS任せ
  3. Playbookやログなどが分散してしまう

それぞれ、いろいろと考えて対処しているのですが、これを公式に解決してくれるのがAnsible Towerです。

Ansible Tower

Ansible Towerは、Playbookによるジョブ管理システムです。具体的には以下の機能を提供してくれます。現時点では有償ですが、10ノードまで管理できる無償のトライアル版が提供されいますので、今回は、このトライアル版を利用してAnsible TowerとOpenStackの連携方法についてご紹介します。

  1. コールバック機能も含めた外部API機能
  2. Gitなどのソフトウェア構成管理システム上に置いたPlaybookを利用したジョブ管理機能
  3. ジョブ実行ログの集中管理機能
  4. ユーザ・グループレベルでの実行権限管理

インストール手順は、特に難しということはありません。公式ドキュメントや、@ITコチラの記事を参照してみてください。

Tower起動させると、こんな感じのリッチなWebダッシュボードから操作できるようになります。

f:id:pyde:20161225211100p:plain

紹介する構成

testserverをデプロイする際に、Ansible Towerの管理下にあるPlaybookをジョブとして実行する方法を紹介します。

                             172.16.165.0/24
+------+--------------+---------------------+
       |.130          |.66
       |              |
       |              |
 +-----+----+   +-----+-----+
 |  router  |   | OpenStack |
 +-----+----+   +-----------+
       |
       |
       |.1                    192.168.0.0/24
+-----++---------------+--------------------+
      |.15             |
      |                |
      |                |
 +----+----+    +------+------+
 |  tower  |    | testserver  |
 +---------+    +-------------+

ジョブとして実行するPlaybook

playbookは、以下の構成でGitHubに置いて、これをAnsible Towerから利用します。

playbook
├── site.yml
└── web
    ├── files
    │   ├── index.html
    │   └── josug2016.png
    └── tasks
         └── main.yml

playbookで実行するタスク(playbook/web/tasks/main.yml)は、以下の通りです。パッケージ更新後にnginxをインストールし、コンテンツを配置した後で、最後にnginxをリスタートしています。

---
# tasks file for web

- block:
  - name: update all packages
    apt:
      upgrade: yes
      update_cache: yes
  - name: install nginx
    apt:
      name: nginx
      update_cache: no
  - name: copy contents
    copy:
      src: "{{ item }}"
      dest: "/usr/share/nginx/html/{{ item }}"
    with_items:
      - index.html
      - josug2016.png
  - name: restart nginx
    service:
      name: nginx
      state: restarted
  become: yes
  become_user: root

Ansible TowerでのOpenStack連携設定

それでは、Ansible Towerを操作して、実際にOpenStackとの連携をみてみましょう。

Ansible TowerからOpenStack環境を利用するための設定項目は4つあります。

  1. プロジェクトの作成
  2. Credentialの作成
  3. Dynamic Inventoryを利用するInventory Groupの作成
  4. Playbookを実行するJob Templateの作成

1. プロジェクトの作成

今回のAdvent Calendar用に1つプロジェクトを作成します。

SCM URLには、GitHub上に配置してあるPlaybookのパスを指定しています。

f:id:pyde:20161225211052p:plain

2. Credentialの作成

利用するCredentialは2つあります。

1つは、Dynamic InventoryからOpenStackのAPIを利用するためのopenstackと、

f:id:pyde:20161225211102p:plain

そしてもう1つは、起動したインスタンスにログインしてPlaybookを適用するためのubuntuです。

f:id:pyde:20161225211104p:plain

3. Inventory Groupの作成

OpenStack環境で管理されている仮想マシン群を、Ansibleから操作するためには Dynamic Inventory を利用するのが常套手段です。当然ながらAnsible Towerからも Dynamic Inventory が利用できます。

ここでは、すでに作成済みのCredential(openstack)を利用して、Dynamic Inventory(webservice)を作成しています。

4. Job Templateの作成

ubuntuとopenstackという2つのCredentialとInventoryを指定して、Job Templateを作成します。更に、管理対象ホストからジョブ起動させるトリガーを引けるように、Callbackを許可します。

f:id:pyde:20161225211057p:plain

このCallback URLに、操作対象ホストからcurlなどでアクセスすることにより、ジョブをキックすることができます。

curl --data "host_config_key=設定キー" https://192.168.0.241:443/api/v1/job_templates/15/callback/ --insecure

OpenStack管理下に仮想マシンインスタンスを起動

openstackコマンドで、インスタンスを起動させる際に、user-dataとして実行するスクリプト(userdata.sh)は、以下の通りです。

#!/bin/bash -v

curl --data "host_config_key=08e4d419bebc422a2bfacbd4bfd469fb" https://192.168.0.15:443/api/v1/job_templates/15/callback/ --insecure

#
# [EOF]
#

実際に、このuser-dataを利用してインスタンスを起動します。

openstack --os-cloud=josug server create \
--flavor m1.small \
--image trusty-server-cloudimg-amd64 \
--key-name ぼくの鍵 \
--nic net-id=ぼくのネットワークID \
--security-group ぼくのSecGroup \
--user-data ./userdata.sh \
testserver

起動時のTowerとの連携は以下の通りです。

  1. boot => OpenStack APIを利用して、Computeノード上にインスタンス(testserver)を起動する
  2. callback => 起動プロセスの最後に実行されるスクリプト(userdata.sh)からAnsible TowerのCallback URLにアクセスしてジョブをキックする
  3. playbook => Ansible Towerにジョブとして登録されているPlaybookを実行する
client               OpenStack               Tower             testserver(compute)
  +                      +                     +                      +
  |      1.boot          |                     |                      |
  +---------------------->                     |                      |
  |                      |                     |                      |
  |                      |                     |                      |
  |                      |                     |        1.boot        |
  |                      +-------------------------------------------->
  |                      |                     |                      |
  |                      |                     |                      |
  |                      |                     |       2.callback     |
  |                      |                     <----------------------+
  |                      |                     |                      |
  |                      |                     |                      |
  |                      |                     |       3.playbook     |
  |                      |                     +---------------------->
  |                      |                     |                      |
  |                      |                     |                      |
  +                      +                     +                      +

さらに進んだ利用方法

今回は、openstackコマンドのuser-dataオプションから、Callback URLキックするスクリプトを利用しましたが、こちらの記事のように、Heatのテンプレートからも同様にuser-dataに指定することで、操作対象ホストからCallbackでPlaybookをキックできます。オートスケール時の初期設定にも利用できて、さらに便利に使えますね。

クリスマスプレゼント間に合わず

Ansible Towerは、現在のところオープンソースではありません。しかし、Ansible WorksをRed Hatが買収されて以降、Red Hatのポリシーに従って、オープンソース化に向けた努力を続けているそうです。

きっと来年のクリスマスまでには、Ansible Towerがオープンソースソフトウェアとして広く利用できるに違いない!と期待を込めて、このカレンダー記事を書きました。

それでは皆さん、メリークリスマス:-)