見出し画像

AnsibleとTerraformと

Ansible Night in Tokyo 2019.07 でのLT内容詳細です。

LT資料はこちら

■ 概要

Ansible Terraform をどのように使い分けるべきか考察してみます。

■ Ansible とTerraform とを扱っている記事について

以下にいくつか記事がありますが、どの記事も2つのツールを呼び出せると言う技術的観点でのみ説明されているだけで、どのような組み合わせで使い分けるべきか、その際の課題などは明言されていません。

① HashiCorp Terraform and Red Hat Ansible Automation (Redhat の記事)

Terraform からAnsible Playbook を呼び出すこと」、「Ansible からTerraform モジュールを使ってTerraform を呼び出すこと」という2パターンの形態があると記載されています。

>Terraform からAnsible を呼び出す

HCL(HashiCorp Configuration Language) の記述例:

hcl
resource “aws_instance” “web” {
  # ...
  provisioner “local-exec” {
    command = “ansible-playbook -u ubuntu -i ‘${aws_instance.web.public_dns},’ main.yml”
  }
}

AWSインスタンス(EC2) が作成された後の処理として、Playbook実行を行う定義例です。provisioner という実行定義は、ローカル実行とリモート実行を選択できます。上記の例では、Terraform と同じサーバ上にあるAnsibleを使用して、Terraform が生成したEC2に対してコンフィグを行なっています。

Playbook 実行でエラーとなると、上記のインスタンスは"Tainted" と言う状態となります。エラー原因を除去後再度Terraform apply を実行すると、EC2 は一旦削除され再生成後、Playbookが実行されることとなります。

>Ansible からTerraform を呼び出す

Playbookの記述例:

---
- name: main
  hosts: all
  gather_facts: false
  connection: local
  tasks:
  - name: plan
    terraform:
      project_path: ‘terraform/’
      plan_file: “{{playbook_dir}}/tfplan”
      locktrue
      state: planned

  - name: apply
    terraform:
       project_path: ‘terraform/’
       locktrue
       state: present

  - name: destroy
    terraform:
       project_path: ‘terraform/’
       locktrue
       state: absent

AnsibleとしてTerraform 用モジュールが提供されています。上記のplaybookは、Terraformモジュールを使用して、Terraform を呼び出す例です。Terraform でインフラを構築し、そのインフラに対して別のPlaybookから設定をする必要がある場合、Dynamic Inventory を活用することで情報の受け渡しを行うことになります。

Dynamic Inventoryに関する参考記事:AnsibleTerraform moduleを考察してみる

② Ansible and HashiCorp: Better Together (HashiCorp の講演資料とビデオ映像)

聴講者から、Ansible Terraform を連動させる理由を聞かれているが、明確な回答をしていません。
TerraformからAnsible を呼び出して使っている人が会場内にいるか確認したところ数名いた模様

③ The Right Way to DevOps with Terraform and Ansible (HashiCorp YouTube)

このビデオは、2つのツールを使う理由が語られています。説明は以下のようなポイント

Why Both ?
1. Stateful architecture of Terraform
  * Avoid Config drift at infrastructure layer
2. Declarative Code
  * Increasing number of cloud services and their dependencies
3. Procedural behavior of Ansible
  * Useful for installing packages in a sequence as desired by the app
  * Allows conditional statements in Ansible Playbook like "when"
4. Day 2 Operations and Management
  * Upgrading of artifacts
5. Dev/Test for large environments
  * Quicker test cycles

Terraform は、ステートフルなアーキテクチャとなっていて、構成ドリフト(サーバの内容が時間とともに定義とかけ離れて変化していくこと)を防ぐ
宣言的モデルのため依存関係を意識しなくて良い
Ansibleは、べき等性をもつプロセスベース。if-then といった制御が可。

④ Using Terraform, Packer, and Ansible Together - Aaron Krauss: DevOps OKC (YouTube)

Packer からAnsible playbookを使用する方法、Terraform からAnsible Playbookを使用する方法を説明している。Ansibleはサーバー構成管理ツールとして使用することをお勧めしている

■ Infrastructure as Code の位置付け整理

AnsibleTerraformの位置付けを整理するために、IaC(Infrastructure as Code) について、オライリージャパン:Infrastructure as Code をベースとして以下のページにまとめてみました。
IaC(Infrastructure as Code) における Declarative vs. Imperative (Qiita)

■ Ansible Tower とTerraform Enterprise

通常の文脈で Ansible  Terraform を語る場合は、OSS版を指している場合が多いと思います。事業会社で実際に利用する場合、商用版を利用することがあるためこの組み合わせでの「有り・無し」を考えてみます。

No.1: Ansible Tower + Terraform Enterprise

高機能なWebベースGUIを双方保有しています。同じ利用者が両方のツールを使用するのは混乱すると思われるため併用することはしない方が良いでしょう。利用者が異なる(例えば管理対象が要員ごとに異なる)場合は、それぞれが干渉することなく使い分けると言うことはあり得ると思います。

No.2: Ansible Tower + Terraform OSS版

Towerを主体として運用するイメージ。ジョブテンプレートを管理対象ごとに整理し、ジョブ実行でTerraformAnsible(Engine) を呼び出します。この組み合わせは、宣言的モデルをうまく活用することで複雑なインフラ構築をTerraformの価値を活かすことができると思います。

Ansible Tower Workshop / Ansible to wrap Terraform, for provisioning AWS infrastructure and nodes での例では、一つのPlaybookでインフラ構築とサーバー設定を行なっています。

No.3: Ansible Engine + Terraform Enterprise

Terraform を主体として運用するイメージ。Terraform HCL からAnsible Playbook を呼び出すことは可能であるが、設計が悪いとPlaybookの呼び出しが意図しない箇所で発生する可能性があります。メンテナンス性も悪くなると考えられるため、このパターンはあまりお勧めできません。

No.4: Ansible Engine + Terraform OSS版

No.1 と同じく、それぞれが干渉することなく使い分けるのであればこのパターンはあり得ると思います。

■ 考察

Terraform Ansible は以下のような観点から使い分けた方が良いと思います。

・制御対象となるリソースのライフサイクルに合わせてツールを使い分ける方が見通しが良い
Terraformは宣言的なモデル定義(HCL) でインフラを構築・変更するのが筋の良い使い方と思う (後処理(provisioner)Playbook を呼び出すのは違和感あり)
AnsibleTerraformモジュールを使う場合は、Ansible Towerを使うと見通しが良くなる思う
・複数のDSLを覚える壁は意外と大きい。Playbook(YAML)HCLを覚える必要があり、現場の抵抗が発生する可能性がある

■ 結論

IaC ツールは、適材適所での使用を!
PlaybookHCLもある意味、ソースコードです。疎連携でモノリス化を避けよう!
・アプリケーション開発と同じように、IaCツールのコードも美しいソースコードとしたいです(保守性、可読性、結合度・凝集度など)

■ 参考資料

AnsibleTerraformPackerで作るSelf-Hosted Kubernetes / JKD1812 Kubernetes 環境を構築する際にAnsibleTerraformを使った詳細な事例。連携をさせるのではなく、別々に得意なリソースに対する制御を行なっている例を説明していて分かりやすいです。

その他、今回参考とさせて頂いた資料は以下にまとめてあります。

Terraform のブックマーク一覧

この記事が気に入ったらサポートをしてみませんか?