AnsibleにはGoogle Compute Engineのリソース管理用モジュール(GCEモジュール)が組み込まれてます。
GCEモジュールを使うことで、
- Instanceの生成
- network access制御
- persistant diskの利用
- load balancerの管理
を自動化できます。
さらに、
inventoryプラグインもあり、
生成したGCEinstanceの情報をAnsible dynamic inventoryに自動的に吸い上げ、
tagやプロパティでグループ化できます。
しかし、
使う際には、必要な認証や設定がいくつかある上に、ドキュメントの記述が複雑でわかりづらい部分もあるため、結構ハマります。
その辺りを回避できるように解説していきます。
まず、
AnsibleのGCEモジュールは、pythonのapache-libcloudモジュールに依存しているので、 pip installします。
$ pip install apache-libcloud
GCEモジュールのドキュメントには、
Playbookファイルなどのディレクトリ構成の記載がありません。
ベスト・プラクティスを見習うべきですが、
簡単に始めるには、以下のような構成で良いんじゃないかと思います。
~/gce_ansible/ play.sh # playbook実行シェルスクリプト master.yml # master playbook credentials/ # 証明書管理Dir cacert.pem # libcloud用 CA bundleファイル pkey.pem # GCE用 証明書ファイル secrets.py # 証明書指定ファイル inventory/ # inventory管理用Dir gce.ini # GCE用設定ファイル gce.py # GCE用モジュール hosts # inventoryファイル vars/ gce_auth.yml # GCE認証情報変数 instance.yml # GCEinstance設定変数
以下、ディレクトリごとに解説します。
credentials | 証明書の取得
libcloud用 CA bundleファイル
Mac OS Xで利用している場合、libcloud用 CA bundleファイルが必要です。
cURL - Extract CA Certs
にアクセスし「HTTP from curl.haxx.se: cacert.pem」をダウンロードして、
前述ディレクトリの credentials に配置しましょう。
ちなみに、これが無いとplaybook実行時に以下のようなエラーが出ました。
RuntimeError: No CA Certificates were found in CA_CERTS_PATH.
GCE用 証明書ファイル
次に、GCEにアクセスするための証明書ファイルが必要です。
Google Developer Console
で、(Project名) > APIS&AUTH > 認証情報
を選択、OAuthの「新しいクライアントIDを作成」をクリックします。
「サービスアカウント」を選択してクライアントIDを作成しましょう。
完了画面にパスワード’notasecret’ が表示され、
自動的にp12形式証明書ファイルを取得できます。
完了画面を閉じた後「サービスアカウント」欄に追加されたメールアドレスは後で必要になります。
証明書をapache-libcloudで使うため、
以下のコマンドで、p12ファイルをpem形式(openSSL標準)に変換します。
$ openssl pkcs12 -in (p12ファイルパス).p12 -passin pass:notasecret -nodes -nocerts | openssl rsa -out ~/gce_ansible/credentials/pkey.pem
証明書指定ファイル(secrets.py)
GCE用証明書ファイルをansibleに認識させるため、
以下のようにpythonファイルを作成します。
GCE_PARAMS = ('i...@project.googleusercontent.com', '~/gce_ansible/credentials/pkey.pem') GCE_KEYWORD_PARAMS = {'project': 'project-name'}
記載するのは、前述の「サービスアカウント」欄のメールアドレスと、pemファイルパス、対象のGCEプロジェクト名です。
inventory | 実行対象ホスト
ローカルホスト指定(hosts)
GCEのinstance生成は、ローカルPCから実行するので、
まずはlocalhostを設定します。
[localhost] 127.0.0.1
GCE Dynamic Inventory
Dynamic Inventoryという仕組みを使うと、
GCEで生成したinstanceのIPアドレスを自動で取得して、
inventoryとして判断してくれるようになります。
Ansibleが提供している GCE inventory plugin を使います。
Ansibleのgithubリポジトリの、 - plugins/inventory/gce.ini - plugins/inventory/gce.py
を取得して、それぞれ
- inventory/gce.ini
- inventory/gce.py
に置きましょう。
gce.iniに、secrets.pyの絶対パスを指定します。例えば、
libcloud_secrets = /Users/shuhei/gce_ansible/credentials/secrets.py
動作確認
Dynamic Inventoryが正常に動作するかどうかを確認します。
$ cd ~/gce_ansible $ export SSL_CERT_FILE=$HOME/gce_ansible/credentials/cacert.pem $ ./inventory/gce.py --list
GCE上にすでにinstanceが動作している場合は、そのhostの情報がjsonで出力されるはずです。
また、以下のコマンドでさらに詳細な情報が出力されます。
$ cd ~/gce_ansible $ export GCE_INI_PATH=$HOME/gce_ansible/inventory/gce.ini $ ansible all -i inventory/gce.py -m setup hostname | success >> { "ansible_facts": { "ansible_all_ipv4_addresses": [ "x.x.x.x" ], .... } }
master.yml | playbook本体
いよいよplaybookの作成です。
今回は、GCEのinstanceを生成するだけにしておきます。
master.yml
- name: Create new GCE instances hosts: localhost gather_facts: no vars_files: - "vars/instance.yml" - "vars/gce_auth.yml" tasks: - name: Launch instances local_action: module: gce instance_names: "{{ names }}" machine_type: "{{ type }}" image: "{{ image }}" zone: "{{ zone }}" service_account_email: "{{ service_account_email }}" pem_file: "{{ pem_file }}" project_id: "{{ project_id }}" tags: webserver
vars | 変数の管理
playbook内の二重波括弧 {{ … }} で囲っている部分は変数で、
var_files: として指定している以下の2ファイルに値を記載しています。
vars/gce_auth.yml
(credentials/secrets.py と内容がかぶってますが気にせず…)
service_account_email: i...@project.googleusercontent.com pem_file: ~/gce_ansible/credentials/pkey.pem project_id: project-name
vars/instance.yml
names: www1 type: f1-micro image: debian-7 zone: us-central1-b
play.sh | playbook実行用シェルスクリプト
playbookを実行する前に、実行するためのシェルスクリプトを作成しておきます。
#!/bin/bash PLAYBOOK="$1" if [ -z $PLAYBOOK ]; then echo "You need to pass a playback as argument to this script." exit 1 fi export GCE_INI_PATH=$(pwd)/inventory/gce.ini export SSL_CERT_FILE=$(pwd)/credentials/cacert.pem export ANSIBLE_HOST_KEY_CHECKING=False if [ ! -f "$SSL_CERT_FILE" ]; then curl -O http://curl.haxx.se/ca/cacert.pem fi ansible-playbook -v -i inventory/ "$PLAYBOOK"
実行!
$ cd ~/gce_ansible $ ./play.sh master.yml PLAY [Create new GCE instances] ****************** ...(略)... PLAY RECAP ******************************************************************** 127.0.0.1 : ok=1 changed=1 unreachable=0 failed=0
実行後、ふたたび Google Developer Console にアクセスして
該当プロジェクトの
[Compute Engine] > [VMインスタンス]
を見ると、www1 という名前のinstanceが生成されているはずです。
ということで、今回はこの辺りでおしまいです。
次回は、Google Compute Engine(GCE)に生成したinstanceに
アプリケーションをセッティングしていく予定です。
このブログに関して不明点やご意見などはコメントをお願いします。
また、横浜のコワーキングスペース「タネマキ」での勉強会に
参加していますので、お気軽にお立ち寄りください。
タネマキGAE - connpass
Google App Engine, Google Compute Engine, Python, Golangなどの
もくもく勉強会です。
master.yml の vars_files の指定が “vars/common.yml” になってるけど、これって “vars/instance.yml” ですね、たぶん
ご指摘ありがとうございます!確かにその通りです。
修正しました。 m(_ _)m