Terraform と Ansible を連携させてIBM Cloudの仮想サーバーを構築する手順

Terraform, Ansible, IBM Cloud CLI を使用できる仮想サーバーをパソコン上に作り、Terraform でIBM Cloud の仮想サーバーを構築する手順とツールを試してみましたので、メモを残しておきます。

![スクリーンショット 2019-03-21 20.13.15.png](https://qiita-image-store.s3.amazonaws.com/0/42829/98ef793f-2d9e-1db2-b9b5-119076bd3d70.png)


## Terraform用のワークステーションを起動

GitHub https://github.com/takara9/vagrant-terraform に、Terraform で作業するためのワークステーションを構築するための Vagrantfile と Ansible playbook を作成しました。これを利用して、Ubuntu仮想サーバーを起動します。

~~~console
imac:work3 maho$ git clone https://github.com/takara9/vagrant-terraform
imac:work3 maho$ cd vagrant-terraform/
imac:vagrant-terraform maho$ vagrant up
imac:vagrant-terraform maho$ vagrant ssh
~~~

次のようなTerraform変数ファイル `secret.tfvars` を作成します。sl_usernameは IBM Cloud Classic Infrastructure のユーザーID、sl_api_keyは、同じくClassic の API-KEY 、そして、ic_api_keyは、terraformの実行に権限を与えるために、生成します。 これらの値は、IBM Cloudのコンソール画面の上部にある「管理」-> 「アクセス(IAM)」-> 「APIキー」から取得または生成できます。

~~~console
vagrant@workstation:~$ vi secret.tfvars
vagrant@workstation:~$ cat secret.tfvars
sl_username = "IBM999999"
sl_api_key  = "1234567890123456789012345678901234567890123456789012345678901234"
ic_api_key  = "abcdefghijklmnopqrstuvwxyz1234567890"
~~~


## テンプレートをプロビジョニング単位にクローン

Ansibleと連携して仮想サーバーを構築するためのテンプレートを GitHub https://github.com/takara9/terraform-ibmcloud-vsi に置きました。前述のvagrant upで、/home/vagrant/vsiにクローンしてあります。


## 仮想サーバー構築の実行手順

先にクローンしたディレクトリには以下のファイルが入っています。

~~~
vagrant@workstation:~/vsi$ tree
.
├── ansible.cfg             Ansible 設定ファイル
├── install.yml   TFプロビジョニング時にインストールするパッケージ
├── main.tf       TF仮想サーバーのプロビジョニング設定ファイル
├── playbooks               Ansible プレイブック
│   ├── hosts                 hostsファイル
│   ├── setup.yml             プレイブック本体
│   └── versions.yml          変数ファイル
├── terraform.tfvars   TF変数ファイル
└── tfstate2hosts.py   TFの terraform.tfstate から Ansible の hosts を生成するプログラム
~~~

ここから、次の手順で、Dockerホストとなる仮想サーバーを構築します。

* Terraform の main.tf, install.yml, terraform.tfvars を編集
* Ansible の プレイブックを置き換え、または、編集
* Terraform のプラグインを取得
* terraformコマンドで仮想サーバーをプロビジョニング
* プロビジョニング後に、Terraform で仮想サーバーをプロビジョニングした後に生成される `terraform.tfstate` から Ansible の hostsファイルを生成します。
* `ansible -m ping -i playbooks/hosts nodes` で疎通確認
* `ansible-playbook -i playbooks/hosts playbooks/setup.yml` で自動設定


## Terraform のプロジェクト初期化

このコマンドでIBM Cloud プラグインとの対応づけが完了します。

~~~console
vagrant@workstation:~$ cd vsi
vagrant@workstation:~/vsi$ terraform init
~~~


## Terraform でプロビジョニングを実行

次のコマンドで、APIKEYの変数ファイルを指定して、仮想サーバーを構築します。

~~~console
$ terraform plan -var-file=/vagrant/secret.tfvars -var-file=terraform.tfvars
<中略>
$ terraform apply -var-file=/vagrant/secret.tfvars -var-file=terraform.tfvars
<中略>
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

base_name = node
hostname = [
    node-0
]
public_ip = [
    165.***.**.*
]
~~~

## Ansible hostsファイルの生成

`terraform.tfstate` から Ansible の hostsファイルを生成して、Ansibleを実行できるようにします。

~~~console
$ python tfstate2hosts.py
~~~

次のansibleコマンドで、仮想サーバーと疎通確認を実行します。

~~~console
$ ansible -m ping -i playbooks/hosts nodes
node-0 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
~~~

## Ansible で自動設定実行

プロビジョニングされた仮想サーバーに、必要な設定を施します。ここでは、Docker CE をインストールします。

~~~console
$ ansible-playbook -i playbooks/hosts playbooks/setup.yml
~~~



## サーバーにログインして動作確認

Ansibleの自動設定の結果を確認します。

~~~console
$ ssh -i ~/keys/key root@***.***.**.*
# docker system info
~~~

Rancherを起動してみます。

~~~console
# docker run -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                      NAMES
ee50590f1e47        rancher/rancher     "entrypoint.sh"     7 seconds ago       Up 6 seconds        0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   vibrant_bell
~~~

## 参考資料
* Terraform + Cloud-init + Ansible で IBM Cloud VSIプロビジョニング自動化 https://qiita.com/MahoTakara/items/0b23d9bca3edcfe0081c
*

以上