前書き
Ansible 2.0が最近リリースされ、version 2 of the DigitalOcean APIのサポートが付属しています。 これは、Webアプリケーションをプロビジョニングするだけでなく、ドロップレットを自動的にプロビジョニングおよび管理するためにAnsibleを使用できることを意味します。
[。注意]##
Note: Ubuntu 14.04を使用する場合は、古いバージョンのDigitalOcean API Pythonラッパーdopy
を使用する必要があります。 新しいバージョンは機能しませんが、古いバージョンには、プライベートネットワーキングの問題を解決するなど、一部の機能とバグ修正がありません。
ただし、Ubuntu 16.04では最新バージョンのdopy
を使用できます。 代わりにthis tutorial written for 16.04のバージョンを使用でき、upgrade from Ubuntu 14.04 to 16.04も使用できます。
DigitalOceanはSSHキーのセットアップとDropletの作成のためのシンプルなWebインターフェイスを提供しますが、新しいサーバーをプロビジョニングするたびに実行する必要がある手動プロセスです。 アプリケーションが多数のサーバーを含むように拡張され、オンデマンドで拡大および縮小する機能が必要な場合、各サーバーのアプリケーション展開スクリプトを手動で作成および構成する必要はありません。
Ansibleなどのプロビジョニングツールを使用する利点は、このプロセスを完全に自動化できることと、単一のコマンドを実行するだけで簡単に開始できることです。 このチュートリアルでは、DigitalOcean API v2のAnsibleのサポートの使用方法を例で示します。
特に、このチュートリアルでは、DOアカウントに新しいSSHキーをセットアップし、2つの異なるドロップレットをプロビジョニングして、Webアプリケーションのデプロイに使用できるようにするプロセスについて説明します。 このチュートリアルに従うと、これらのタスクを変更して、既存のアプリケーション展開スクリプトに統合できるようになります。
前提条件
このチュートリアルはAnsibleの基本的な知識に基づいているため、Ansibleを初めて使用する場合は、最初にthis section of the Ansible installation tutorialを読むことができます。
このチュートリアルを実行するには、次のものが必要です。
-
sudo non-root userを持つ1つのUbuntu14.04ドロップレット。
-
サーバーにインストールされているAnsible。this step from a previous Ansible tutorialに従って設定できます。
-
APIの読み取りおよび書き込みPersonal Access Token。 トークンは安全な場所に書き留めてください。このチュートリアルの後半で必要になります。
[[step-1 -—- configuring-ansible]] ==ステップ1—Ansibleの構成
このステップでは、DigitalOcean APIと通信するようにAnsibleを構成します。
通常、AnsibleはSSHを使用して異なるサーバーに接続し、コマンドを実行するだけです。 つまり、Ansibleの使用を開始するために必要な構成は、一般的にすべてのモジュールの標準です。 ただし、DigitalOcean APIとの通信は単なるSSHシェルコマンドではないため、少し追加のセットアップを行う必要があります。 dopy
(DigitalOcean API Python Wrapper)Pythonモジュールは、AnsibleがAPIと通信できるようにするものです。
dopy
をインストールするには、最初にPythonパッケージマネージャーpip
をインストールします。
sudo apt-get install python-pip
次に、pip
を使用してdopy
をインストールします。
sudo pip install 'dopy>=0.3.5,<=0.3.5'
[.note]#Note:dopy
のバージョン0.3.5を指定しています。 執筆時点では、dopy
の新しいバージョンは壊れており、Ansibleでは機能しません。
#
次に、作業を整理するために作業する新しいディレクトリを作成し、基本的なAnsible構成ファイルを設定します。
デフォルトでは、Ansibleは/etc/ansible/hosts
にあるhostsファイルを使用します。このファイルには、管理しているすべてのサーバーが含まれています。 このファイルは一部のユースケースには適していますが、グローバルです。 これはグローバル構成であり、一部のユースケースでは問題ありませんが、このチュートリアルではローカルホストファイルを使用します。 このようにして、AnsibleのDO APIサポートについて学び、テストしている間に、既存の構成を誤って壊すことはありません。
新しいディレクトリを作成して移動します。このディレクトリは、このチュートリアルの残りの部分で使用します。
mkdir ~/ansible-do-api
cd ~/ansible-do-api/
Ansibleを実行すると、実行されているディレクトリでansible.cfg
ファイルが検索され、見つかった場合は、それらの構成設定が適用されます。 これは、個々のユースケースごとに、hostfile
オプションなどのオプションを簡単にオーバーライドできることを意味します。
ansible.cfg
という名前の新しいファイルを作成し、nano
またはお気に入りのテキストエディタを使用して編集するために開きます。
nano ansible.cfg
以下をansible.cfg
に貼り付け、ファイルを保存して閉じます。
ansible.cfgを更新しました
[defaults]
hostfile = hosts
[defaults]
グループでhostfile
オプションを設定すると、Ansibleはグローバルファイルの代わりに特定のhostsファイルを使用するようになります。 このansible.cfg
は、Ansibleに同じディレクトリでhosts
というホストファイルを探すように指示します。
次に、hosts
ファイルを作成します。
nano hosts
このチュートリアルではDigitalOceanAPIのみを扱うため、Ansibleにlocalhost
で実行するように指示できます。これにより、作業が簡単になり、リモートホストに接続する必要がなくなります。 これは、Ansibleにlocalhost
を使用するように指示し、ansible_connection
をlocal
として指定することで実行できます。 以下のコードをhosts
に貼り付けてから、ファイルを保存して閉じます。
更新されたホストファイル
[digitalocean]
localhost ansible_connection=local
最後に、前提条件で作成されたAPIトークンを使用して、AnsibleがDigitalOcean APIと通信できるようにします。 APIトークンについてAnsibleに伝える方法は3つあります。
-
api_token
パラメータを使用して、各DigitalOceanタスクに直接提供します。 -
プレイブックまたはhostsファイルで変数として定義し、その変数を
api_token
パラメータに使用します。 -
DO_API_TOKEN
またはDO_API_KEY
のいずれかとして、環境変数としてエクスポートします。
オプション1は最も直接的なアプローチであり、変数を作成したくない場合は魅力的に聞こえるかもしれません。 ただし、APIトークンは、使用されている各タスクにコピーする必要があることを意味します。 さらに重要なことは、これが変更された場合、すべてのインスタンスを見つけてすべて置き換える必要があることを意味します。
オプション2では、オプション1と同様に、プレイブック内でAPIトークンを直接設定できます。 オプション1とは異なり、変数を使用して1か所で定義するだけです。これは、より便利で更新が容易です。 最も簡単なアプローチであるため、このチュートリアルではオプション2を使用します。
ただし、オプション3がAPIトークンを保護するために使用するのに最適な方法であることは、価値がありません。誤ってAPIトークンをリポジトリ(誰かと共有される可能性があります)にコミットするのがはるかに難しくなります。 これにより、トークンをシステムレベルで構成し、それぞれにトークンを含めることなく、異なるプレイブック間で動作することができます。
digitalocean.yml
という基本的なプレイブックを作成します。
nano digitalocean.yml
次のコードをファイルに貼り付けて、APIトークンを置き換えてください。
更新されたdigitalocean.yml
---
- hosts: digitalocean
vars:
do_token: your_API_token
tasks:
このファイルは次のステップで引き続き作業するため、エディターで開いたままにしておくことができます。
[[step-2 -—- setting-up-an-ssh-key]] ==ステップ2—SSHキーの設定
このステップでは、サーバー上に新しいSSHキーを作成し、Ansibleを使用してDigitalOceanアカウントに追加します。
最初に行う必要があるのは、ユーザーにSSHキーペアがあることを確認することです。SSHキーペアをDigitalOceanにプッシュして、新しいDropletにデフォルトでインストールできるようにします。 これはコマンドラインから簡単に実行できますが、Ansibleのusersモジュールでも同じように簡単に実行できます。 Ansibleを使用すると、使用前にキーが存在することを確認できるという利点もあります。これにより、異なるホストでプレイブックを実行する際の問題を回避できます。
プレイブックに、以下のuser
タスクを追加します。これを使用して、SSHキーが存在することを確認してから、ファイルを保存して閉じます。
更新されたdigitalocean.yml
---
- hosts: digitalocean
vars:
do_token: your_API_token
tasks:
- name: ensure ssh key exists
user: >
name={{ ansible_user_id }}
generate_ssh_key=yes
ssh_key_file=.ssh/id_rsa
[.note]#~/.ssh/id_rsa
。
以外のものを使用したい場合は、キーの名前を変更できます#
プレイブックを実行します。
ansible-playbook digitalocean.yml
出力は次のようになります。
出力
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [ensure ssh key exists] ***************************************************
changed: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0
それが終了したら、次を実行してキーが存在することを手動で確認できます。
ls -la ~/.ssh/id_rsa*
id_rsa*
に一致するすべてのファイルが一覧表示されます。 SSHキーが存在することを示すid_rsa
とid_rsa.pub
がリストされているはずです。
次に、キーをDigitalOceanアカウントにプッシュするため、Playbookを開いて再度編集します。
nano digitalocean.yml
digital_ocean Ansibleモジュールを使用してSSHキーをアップロードします。また、後のステップで必要になるため、タスクの出力をmy_ssh_key
変数として登録します。
ファイルの下部にタスクを追加し、ファイルを保存して閉じます。
更新されたdigitalocean.yml
---
. . .
- name: ensure ssh key exists
user: >
name={{ ansible_user_id }}
generate_ssh_key=yes
ssh_key_file=.ssh/id_rsa
- name: ensure key exists at DigitalOcean
digital_ocean: >
state=present
command=ssh
name=my_ssh_key
ssh_pub_key={{ lookup('file', '~/.ssh/id_rsa.pub') }}
api_token={{ do_token }}
register: my_ssh_key
[.note]#キーにid_rsa
以外の名前を付けた場合は、このタスクのssh_pub_key
行の名前を更新してください。
#
ここでは、digital_ocean
モジュールのさまざまなオプションを使用しています。
-
state —これは、存在、アクティブ、不在、または削除できます。 この場合、SSHキーをアカウントに存在させたいので、
present
が必要です。 -
command —これはドロップレットまたはsshのいずれかです。 アカウント内のSSHキーの状態を管理できる
ssh
が必要です。 -
name —これはSSHキーを保存するための名前です。これは一意である必要があり、APIおよびWebインターフェイスを介してキーを識別するために使用されます。
-
ssh_pub_key —これはSSH公開鍵であり、ユーザーモジュールを使用してその存在を保証した鍵になります。
-
api_token —これはDigitalOcean APIトークンであり、変数としてアクセスできます(
do_token
、vars
セクションで定義)。
次に、プレイブックを実行します。
ansible-playbook digitalocean.yml
出力は次のようになります。
出力
. . .
TASK [ensure key exists at digital ocean] **************************************
changed: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0
それが完了したら、コントロールパネルに移動し、(歯車メニューから)Settingsをクリックし、次に(User内のSecurityをクリックして、SSHキーがDigitalOceanアカウントに存在することを手動で確認できます)左側のサイドバーのカテゴリ)。 SSH Keysの下に新しいキーが表示されます。
[[step-3 -—- creating-a-new-droplet]] ==ステップ3—新しい液滴の作成
このステップでは、新しいドロップレットを作成します。
手順2でdigital_ocean
モジュールについて簡単に触れました。 このステップでは、このモジュールに別のオプションセットを使用します。
-
command —前のステップで
`+ssh+
を使用してこのオプションを使用しました。今回は、これをdroplet
とともに使用して、このモジュールを介してドロップレットを管理します。 -
state —前のステップでもこれを使用しました。ここでは、
present
になりたいドロップレットの状態を表します。 -
image_id —これは、
ubuntu-14-04-x64
のように、新しいドロップレットに使用するイメージです。 -
name —これはドロップレットを作成するときに使用するホスト名です。
-
region_id —これは、
NYC3
のように、ドロップレットを作成する領域です。 -
size_id —これは、
512mb
のように、作成するドロップレットのサイズです。 -
sshkeyids —これは、サーバーの作成時にサーバーに設定されるSSHキーID(または複数のID)です。
このチュートリアルで扱っているオプション以外にも多くのオプションがあります(すべてAnsibleのドキュメントページにあります)が、これらのオプションをガイドとして使用して、新しいタスクを作成できます。
編集用にプレイブックを開きます。
nano digitalocean.yml
下の赤で強調表示されている新しいタスクでPlaybookを更新し、ファイルを保存して閉じます。 サイズ、地域、画像などのオプションをアプリケーションに合わせて変更できます。 以下のオプションは、前の手順で作成したSSHキーを使用して、droplet-oneという名前の512MBのUbuntu14.04サーバーを作成します。
更新されたdigitalocean.yml
. . .
api_token={{ do_token }}
register: my_ssh_key
- name: ensure droplet one exists
digital_ocean: >
state=present
command=droplet
name=droplet-one
size_id=512mb
region_id=sgp1
image_id=ubuntu-14-04-x64
ssh_key_ids={{ my_ssh_key.ssh_key.id }}
api_token={{ do_token }}
register: droplet_one
- debug: msg="IP is {{ droplet_one.droplet.ip_address }}"
{{ my_ssh_key.ssh_key.id }}
を使用して、以前に設定したSSHキーのIDを取得し、それを新しいドロップレットに渡すことに注意してください。 これは、SSHキーが新しく作成された場合、または既に存在する場合に機能します。
次に、プレイブックを実行します。 これは、ドロップレットを作成するため、以前よりも実行に少し時間がかかります。
ansible-playbook digitalocean.yml
出力は次のようになります。
. . .
TASK [ensure key exists at DigitalOcean] **************************************
ok: [localhost]
TASK [ensure droplet one exists] ******************************************************
changed: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "IP is 111.111.111.111"
}
PLAY RECAP *********************************************************************
localhost : ok=5 changed=1 unreachable=0 failed=0
Ansibleは、返信メッセージで新しいDropletのIPアドレスを提供しました。 実行されていることを確認するには、SSHを使用して直接ログインします。
これにより、新しいサーバーに接続されます(手順2でAnsibleサーバーに作成したSSHキーを使用)。 その後、CTRL+D
を押して、Ansibleサーバーに戻ることができます。
[[ステップ-4 -—-液滴が存在することを確認する]] ==ステップ4—液滴が存在することを確認する
このステップでは、べき等の概念と、AnsibleでDropletをプロビジョニングする方法との関係について説明します。
Ansibleは、べき等の概念を使用して動作することを目指しています。 これは、同じタスクを複数回実行できることを意味し、変更は必要な場合にのみ行う必要があります。これは通常、初めて実行されるときです。 このアイデアは、サーバーのプロビジョニング、パッケージのインストール、およびその他のサーバー管理にうまく対応しています。
プレイブックを再度実行すると(まだ実行しないでください!)、現在の構成を前提として、プレイブックは先に進み、droplet-one
とも呼ばれる2番目のドロップレットをプロビジョニングします。 もう一度実行すると、3番目のドロップレットが作成されます。 これは、DigitalOceanが同じ名前の複数のドロップレットを許可するという事実によるものです。 これを回避するには、unique_name
パラメータを使用できます。
unique_name
パラメーターは、サーバーに一意のホスト名が必要であることをAnsibleとDigitalOceanに通知します。 つまり、プレイブックを再度実行すると、べき等性が尊重され、既にプロビジョニングされたドロップレットが考慮されるため、同じ名前の2番目のサーバーは作成されません。
編集用にプレイブックを開きます。
nano digitalocean.yml
unique_name
パラメータを追加します。
更新されたdigitalocean.yml
. . .
- name: ensure droplet one exists
digital_ocean: >
state=present
command=droplet
name=droplet-one
unique_name=yes
size_id=512mb
. . .
プレイブックを保存して実行します。
ansible-playbook digitalocean.yml
出力の結果、タスクは変更されませんが、IPアドレスを含むデバッグ出力が表示されたままになります。 DigitalOceanアカウントを確認すると、1つのdroplet-oneドロップレットのみがプロビジョニングされていることがわかります。
[[ステップ-5 --- 2番目のドロップレットの作成]] ==ステップ5—2番目のドロップレットの作成
この手順では、既存の構成を複製して、個別のドロップレットをプロビジョニングします。
別のドロップレットをプロビジョニングするには、最初のドロップレットからAnsibleタスクを複製するだけです。 ただし、プレイブックをもう少し堅牢にするために、ドロップレットのリストを使用してプロビジョニングし、必要に応じてフリートを簡単にスケールアウトできるように変換します。
まず、ドロップレットのリストを定義する必要があります。
編集用にプレイブックを開きます。
nano digitalocean.yml
vars
セクションでプロビジョニングするドロップレット名のリストを追加します。
更新されたdigitalocean.yml
---
- hosts: digitalocean
vars:
do_token:
droplets:
- droplet-one
- droplet-two
tasks:
. . .
次に、タスクを更新して、ドロップレットのリストをループし、存在するかどうかを確認してから、結果を変数に保存する必要があります。 その後、debug
タスクを変更して、各アイテムの変数に格納されている情報を出力する必要もあります。
これを行うには、プレイブックのensure droplet one existsタスクを次のように更新します。
更新されたdigitalocean.yml
. . .
- name: ensure droplets exist
digital_ocean: >
state=present
command=droplet
name={{ item }}
unique_name=yes
size_id=512mb
region_id=sgp1
image_id=ubuntu-14-04-x64
ssh_key_ids={{ my_ssh_key.ssh_key.id }}
api_token={{ do_token }}
with_items: droplets
register: droplet_details
- debug: msg="IP is {{ item.droplet.ip_address }}"
with_items: droplet_details.results
プレイブックを保存して実行します。
ansible-playbook digitalocean.yml
結果は次のようになります。
出力
. . .
TASK [ensure droplets exists] **************************************************
ok: [localhost] => (item=droplet-one)
changed: [localhost] => (item=droplet-two)
TASK [debug] *******************************************************************
. . .
"msg": "IP is 111.111.111.111"
. . .
"msg": "IP is 222.222.222.222"
}
PLAY RECAP *********************************************************************
localhost : ok=5 changed=1 unreachable=0 failed=0
debug
の出力には、最初よりも多くの情報が含まれていることに気付くかもしれません。 これは、debug
モジュールがデバッグに役立つ追加情報を出力するためです。これは、このモジュールで登録変数を使用することの小さな欠点です。
それとは別に、2番目のDropletがプロビジョニングされ、1番目のDropletがすでに実行されていたことがわかります。 Ansibleのみを使用して2つのDigitalOcean Dropletsをプロビジョニングしました!
ドロップレットの削除も同様に簡単です。 タスクの状態パラメーターは、ドロップレットの状態をAnsibleに指示します。 present
に設定すると、ドロップレットが確実に存在し、まだ存在しない場合は作成されます。 absent
に設定すると、指定された名前notのドロップレットが確実に存在し、指定された名前に一致するドロップレットがすべて削除されます(unique_name
が設定されている場合)。
このチュートリアルで作成した2つのドロップレットの例を削除する場合は、作成タスクの状態をabsent
に変更して、プレイブックを再実行してください。
更新されたdigitalocean.yml
. . .
- name: ensure droplets exist
digital_ocean: >
state=absent
command=droplet
. . .
プレイブックを再実行する前に、デバッグ行を削除することもできます。 削除しない場合、ドロップレットは削除されますが、debugコマンドからエラーが表示されます(返されるIPアドレスがないため)。
ansible-playbook digitalocean.yml
これで、2つのサンプルドロップレットが削除されます。
結論
Ansibleは、非常に強力で非常に柔軟なプロビジョニングツールです。 標準のAnsibleコンセプトとビルトインモジュールのみを使用して、DigitalOcean APIを使用してドロップレットをプロビジョニング(およびプロビジョニング解除)することがどれほど簡単かを見てきました。
present
に設定されたstateパラメーターは、ドロップレットがどの状態にあるべきかをAnsibleに指示します。 present
に設定すると、ドロップレットが確実に存在し、まだ存在しない場合は作成されます。これをabsent
に設定すると、Ansibleは指定された名前notのドロップレットが存在することを確認し、指定された名前に一致するドロップレットを削除します(unique_name
が設定されている場合)。
管理するドロップレットの数が増えると、プロセスを自動化できるため、自動プロセスの一部としてドロップレットを作成、設定、および破棄する時間が節約されます。 このチュートリアルの例を調整および拡張して、セットアップに合わせてプロビジョニングスクリプトをカスタマイズできます。