APC Automation blog

ネットワーク自動化支援のAutomation Coordinatorを提供する、エーピーコミュニケーションズ ACTの自動化ブログ

TerraformとAnsibleの連携「効率的なITインフラ運用の実現」

はじめに

こんにちは、iTOC事業部ACTのエンジニアKです。
IaCツールで有名なものとしてTerraformとAnsibleがありますが、これらはどちらもコードとしてインフラを定義し管理します。
そのため、どちらか片方のツールのみでもインフラプロビジョニングは可能です。
ですが、AnsibleとTerraformを組み合わせることで効率的なITインフラ運用を実現することができます。
そこで今回はAnsibleとTerraformの連携について紹介します。
業務等でAnsibleやTerraformを使用されている方に読んでいただきたい内容です。

AnsibleとTerraformの違いについて

まずは本記事で扱うAnsibleとTerraformの違いについて簡単に説明します。
・得意な領域が異なるため、自動化を行いたい対象や範囲によって使うツールを選び使い分ける ・オンプレミスのNW機器やセキュリティ製品、OSレイヤ以上の自動化はAnsibleが得意とする領域 ・ハイパーバイザーやクラウドサービス上のインフラリソースの自動化はTerraformが得意とする領域 違いについて、より詳細に知りたい方は、弊ブログにそれぞれを解説した記事があるのでそちらを参照してください。
AnsibleとTerraformの違い、使い分けについて

連携することのメリット

ここからはAnsibleとTerraformの得意領域について言及しつつ、連携することのメリットを説明します。

①インフラのプロビジョニングと構成管理の統合

Terraformはインフラのプロビジョニングに優れており、クラウドリソースの作成や管理をコードで行います。
一方、Ansibleは構成管理に強く、サーバやアプリケーションの設定をコードで自動化します。
AnsibleとTerraformを連携することにより、インフラのセットアップからアプリケーションのデプロイまで、一貫した自動化が可能になります。

②柔軟性の向上

Terraformの宣言型アプローチとAnsibleの手続き型アプローチを組み合わせることで、複雑なインフラとアプリケーションの管理がより柔軟に行えます。
Terraformでインフラの状態を定義し、Ansibleで詳細な設定やデプロイを行うことで、より細かい制御が可能になります。

③一貫性と再現性の確保

両ツールを併せて使用することで、インフラとアプリケーションの設定がコードとして管理されるため、一貫性と再現性が向上します。
これにより、環境間での差異を減らし、デプロイの信頼性を高めることができます。

3点のメリットを簡単にまとめると、「AnsibleはGUIで管理をするがTerraformはコードで管理をするため、AnsibleとTerraformを連携すると、インターフェースがひとつに統一できるから管理が楽になる」です。

連携の方法

AnsibleからTerraformを呼び出す方法にはいくつかのアプローチがあります。以下にその方法を説明します。

①ansible.builtin.shellモジュールの利用

ansible.builtin.shellモジュールを使用して、シェルコマンドとしてTerraformを実行する方法もあります。
この方法では、Ansibleタスク内で直接terraform initやterraform applyなどのコマンドを実行します。

②cloud.terraformコレクションの利用

Ansibleのcloud.terraform.terraformモジュールを利用して、Terraformプロジェクトを呼び出すことができます。
このモジュールを使うことで、Ansible Playbook内で直接Terraformの操作を行うことが可能です。   cloud.terraformモジュールはterraformを呼び出す際の設定をyaml形式で入れることができるため視認性が上がります。
またoutputを構造化してくれるのでその後の処理などでも使いやすくなります。
次項目にてcloud.terraformモジュールを詳しく紹介します。

cloud.terraformモジュールの紹介

Ansibleでcloud.terraformモジュールを使用してTerraformを実行する簡単なコードを例に説明します。

以下のコード例は、AnsibleのPlaybookでTerraformを実行し、指定されたプロジェクトパス内のTerraform設定ファイルを適用するものです。

まず、ディレクトリ構成は以下のようにします。

.
├── terraform_test_playbook.yml
└── terraform
    └── main.tf

Terraform設定ファイル(main.tfと) main.tfとvariables.tfには、Terraformの設定を記述します。 ここでは簡単な例として、「sample_instance」というNameタグを持つAWS EC2インスタンスオハイオリージョン(us-east-2)に作成する設定を示します。
AWSの認証については今回省略しています。)

main.tf
provider "aws" {
  region = "us-east-2"
}

resource "aws_instance" "example" {
  ami           = "ami-037774efca2da0726"
  instance_type = "t2.micro"
  tags = {
    Name = "sample_instance"
  }
}

Ansible Playbook(terraform_test_playbook.yml) 次に、Ansible Playbookを作成します。このPlaybookは、ローカルホストでTerraformを実行します。

terraform_test_playbook.yml
---
- name: Execute Terraform from Ansible
  hosts: localhost
  connection: local
  tasks:
    - name: Run Terraform
      cloud.terraform.terraform:
        project_path: "./terraform"
        state: present
        force_init: true

このようにして、AnsibleからTerraformを実行することができるようになります。

Automation ControllerからTerraformを実行する場合の例

ここまではオープンソースのAnsibleでの連携を紹介してきました。 しかし、商用導入する場合はRed Hatからエンタープライズ版の製品群であるAnsible Automation Platformを使用する場合が多いです。
AnsibleとAnsible Automation Platformについて AAPの中でAnsibleを用いた自動化の製品としてAutomation Controllerが提供されているので、 Automation ControllerからTerraformを実行する例を紹介します。
Automation ControllerからTerraformを 実行する際には、Terraformが導入されたコンテナ環境(Execution Environment 以下 EE)を構築する必要があります。

EEの構築

AnsibleのEEを利用して、Terraformを実行するためには、EE内にTerraformをインストールする必要があります。
Automation Controllerで使用されているデフォルトの EEにはTerraformが含まれていないため、独自にビルドする必要があります。

execution-environment.ymlの作成

・execution-environment.ymlファイルを作成し、必要なパッケージや依存関係を定義します。 ・ansible-builderを使用して、EEをビルドします。 以下に簡単な例を紹介します。

exection-environment.ymlのファイルを作成し、下記を記述します。

version: 3
images:
  base_image:
    name: quay.io/centos/centos:stream9
dependencies:
  ansible_core:
    package_pip: ansible-core
  ansible_runner:
    package_pip: ansible-runner
  galaxy:
    collections:
      - name: cloud.terraform
additional_build_steps:
  append_base: |
    RUN yum install -y git
    RUN curl https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo | tee /etc/yum.repos.d/terraform.repo
    RUN yum install -y terraform


EEのビルド

上記の設定でansible-builder buildコマンドを実行し、Terraformが含まれたEEを作成します。

$ ansible-builder build -t localhost/terraform-ee


Terraformがインストールされていることを確認

ビルドしたEEにTerraformがインストールされているかを確認します。
例えば、以下のコマンドでバージョン確認ができればTerraformがインストールされています。

$ docker run localhost/terraform-ee terraform –version
Terraform v1.9.6
on linux_amd64

このEEを用いることで、AAPからTerraformを用いたジョブを実行することが可能になります。

作成したEEを利用してEC2を構築する

TerraformがインストールされたEEを作成できたので、これでAutomation Controller上から先ほど作成した、AnsibleとTerraformを連携させたPlaybookも実行できるようになります。

細かい設定についてはこの記事内では割愛しますが、最終的には下記のようにボタン一つでクラウドリソースの構築ができるようになります。

上記はAutomation Controllerに設定したAWS EC2インスタンスをプロビジョニングするジョブテンプレートの詳細画面です。 ジョブテンプレートには先ほど紹介したPlaybookを設定しています。

画面下部にある起動ボタンをクリックすることで、ジョブが起動して下記の画面に移ります。

Playbookで設定されているTerraformを利用したEC2プロビジョニングのタスクの結果が「changed」となり、成功していることがわかります。

Automation Controllerのジョブによって「sample_instance」という名前のEC2インスタンスオハイオリージョン(us-east-2)に作成されていることがわかります。

まとめ

本記事ではAnsibleとTerraformの連携について説明してきました。 内容を簡単にまとめると

・インフラのプロビジョニングと構成管理の統合が可能になる
・複雑なインフラとアプリケーションの管理が柔軟に行える
・インフラとアプリケーションの設定がコードとして管理されるため一貫性と再現性が確保できる

となります。 AnsibleとTerraformはどちらか一方を選択するのではなく、AnsibleとTerraformを連携させることで、それぞれのツールの強みを活かしつつ、自動化の範囲を広げられるだけでなく、自動化フローを1つのツールに集約できるため、インフラとアプリケーションの管理がより効率的になります。

これから自動化を進める方だけでなく、AnsibleやTerraform単体で自動化を進めていた方は、是非TerraformとAnsibleの連携もご一考ください。