0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Terraform × AAP】Terraform actionsでAWS環境のインフラ構築から構成管理までを自動化したい

0
Last updated at Posted at 2026-10-14

はじめに

クラウド環境におけるインフラの自動化において、「Terraformでリソースを作成し、AnsibleでOSやミドルウェアを設定する」 という組み合わせをしているのをよく目にします。
しかし実装方法によっては、以下のような課題が発生します。

  • terraform apply 完了後、Ansibleの動的インベントリの更新やPlaybookの手動実行をする手間が発生する
  • CI/CD パイプライン上で、Terraform 実行後にPlaybook(またはAAP API)を呼び出す処理を実装する必要がある

そこで登場したのが、2025年秋に HashiCorp と Red Hat から発表された 「Terraform actions」 です。

Terraform actions を活用すると、.tf ファイル内にアクションを定義しておくだけで、terraform apply でEC2 インスタンスが作成された直後(after_create)に、Ansible Automation Platform(以下、AAP)上の Job Template を自動で呼び出し、設定完了まで待機するという一気通貫の処理が実現できます。
本記事では、「AWS上へのEC2インスタンスの作成 ~ AAPのJob Template実行」 までの実装手順を解説します。

TL;DR

この記事を読めば、以下のことができるようになります

  • Terraform actions の概要と aap プロバイダーの書き方
  • terraform applyの中で、リソース作成 ~ AAPの Job Template まで自動実行させる方法

前提条件

  • Ansible実行環境が、EC2インスタンスの作成権限以上を所有していること
    • 本記事では、検証用にAmazonEC2FullAccessを所有しています
  • AAPにアクセスするユーザーがAAPオブジェクトの操作権限以上を所有していること
    • 本記事では、検証用にadminユーザーを使用しています
  • SSH接続用のキーペアがAWS上に作成済みであること

実行環境

  • Ansible Automation Platform: 2.7
    • Automation Controller: 4.8.6
  • Ansible
    • ansible-core: 2.19.8

詳細

1. フォルダ構造

フォルダ構造は下記です。ファイルの中身は後程解説します。

.
├── aap.tf
├── ec2.tf
├── main.tf
├── outputs.tf
├── terraform.tfvars
└── variables.tf

2. ファイル説明

./main.tf

ここでは、TerraformのバージョンやAWS/AAPプロバイダーの定義のみをします。
EC2インスタンスの作成に必要な情報やAAPの情報は別ファイルにわけることで視認性の向上に役立ちます。

terraform {
  required_version = ">= 1.14.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
    aap = {
      source  = "ansible/aap"
      version = "~> 1.4.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

provider "aap" {}

./ec2.tf

作成対象となるEC2インスタンス本体を定義するファイルです。

resource "aws_instance" "my_instance" {
  ami                         = var.ami_id
  instance_type               = var.instance_type
  subnet_id                   = aws_subnet.my_subnet.id
  vpc_security_group_ids      = [aws_security_group.my_sg.id]
  associate_public_ip_address = true
  key_name                    = var.key_name

  root_block_device {
    volume_size = 8
    volume_type = "gp3"
    tags = {
      Name = "${var.instance_name}-root-volume"
    }
  }

  depends_on = [
    aws_internet_gateway.my_igw,
    aws_security_group.my_sg
  ]

  tags = {
    Name = "${var.instance_name}-instance"
  }
}

resource "aws_vpc" "my_vpc" {
  cidr_block = var.vpc_cidr

  tags = {
    Name = "${var.instance_name}-vpc"
  }
}

resource "aws_subnet" "my_subnet" {
  vpc_id                  = aws_vpc.my_vpc.id
  cidr_block              = var.subnet_cidr
  map_public_ip_on_launch = true
  availability_zone       = "ap-northeast-1a"

  tags = {
    Name = "${var.instance_name}-subnet"
  }
}

resource "aws_internet_gateway" "my_igw" {
  vpc_id = aws_vpc.my_vpc.id

  tags = {
    Name = "${var.instance_name}-igw"
  }
}

resource "aws_route_table" "my_rt" {
  vpc_id = aws_vpc.my_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.my_igw.id
  }

  tags = {
    Name = "${var.instance_name}-rt"
  }
}

resource "aws_route_table_association" "my_rta" {
  subnet_id      = aws_subnet.my_subnet.id
  route_table_id = aws_route_table.my_rt.id
}

resource "aws_security_group" "my_sg" {
  name        = "${var.instance_name}-sg"
  description = "Security group for ${var.instance_name}"
  vpc_id      = aws_vpc.my_vpc.id

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.instance_name}-sg"
  }
}

./aap.tf

Job Templateの自動実行(action)を定義する、本記事の核心となるファイルです。
actionであるaap_job_launchの詳細は、TerraformのドキュメントTerraform Registry > aap_job_launchで確認可能です。

data "aap_organization" "organization" {
  name = var.aap_organization_name
}

data "aap_inventory" "inventory" {
  name              = var.aap_inventory_name
  organization_name = data.aap_organization.organization.name
}

data "aap_job_template" "job_template" {
  name              = var.aap_job_template_name
  organization_name = data.aap_organization.organization.name
}

resource "aap_host" "host" {
  inventory_id = data.aap_inventory.inventory.id
  name         = aws_instance.my_instance.tags["Name"]

  variables = jsonencode({
    ansible_host        = aws_instance.my_instance.public_ip
  })

  depends_on = [aws_route_table_association.my_rta]

  lifecycle {
    replace_triggered_by = [aws_instance.my_instance]

    action_trigger {
      events  = [after_create]
      actions = [action.aap_job_launch.job_launch]
    }
  }
}

action "aap_job_launch" "job_launch" {
  config {
    job_template_id                     = data.aap_job_template.job_template.id
    wait_for_completion                 = true
    wait_for_completion_timeout_seconds = var.aap_job_timeout_seconds
    ignore_job_results                  = false
  }
}

ポイントは以下の通りです。

  1. resource "aap_host"における、variablesの活用
    • 作成された EC2 インスタンスのホスト名や IP アドレス(ansible_host)などの情報を、AAP 上のインベントリに登録します。
  2. resource "aap_host"における、depends_onの活用
    • ルーティング設定(aws_route_table_association)の完了を待つことで、EC2作成直後にAAPから到達不能になるエラーを防いでいます。
  3. resource "aap_host"における、lifecycle.action_trigger.eventsの活用
    • EC2インスタンスの作成が完了した直後(after_create)に、aap_job_launch を自動呼び出しします。

./terraform.tfvars

環境ごとに固有となる変数の具体的な値を定義するファイルです。

instance_name = "test-ec2"
key_name = "test_key"
aap_inventory_name = "inv_terraform"
aap_job_template_name = "Terraform Test Job"

./variables.tf

本設定で利用する各変数の型やデフォルト値を定義するファイルです。

# vars for EC2
variable "ami_id" {
  description = "The AMI to use for the instance."
  type        = string
  default     = "ami-XXXXXXXXXXXXXXXXX"
}

variable "instance_type" {
  description = "The type of instance."
  type        = string
  default     = "t2.micro"
}

variable "instance_name" {
  description = "Name of the EC2 instance."
  type        = string
  default     = "test-ec2-instance"
}

variable "vpc_cidr" {
  description = "The CIDR block for the VPC."
  type        = string
  default     = "10.0.0.0/16"
}

variable "subnet_cidr" {
  description = "The CIDR block for the subnet."
  type        = string
  default     = "10.0.1.0/24"
}

variable "key_name" {
  description = "Key name for the EC2 instance."
  type        = string
}

# vars for AAP
variable "aap_organization_name" {
  description = "AAP organization containing the job template."
  type        = string
  default     = "Default"
}

variable "aap_inventory_name" {
  description = "Existing AAP inventory name in aap_organization_name. Terraform does not create or delete this inventory."
  type        = string
}

variable "aap_job_template_name" {
  description = "Existing AAP job template with a machine credential matching key_name."
  type        = string
}

variable "aap_job_timeout_seconds" {
  description = "Maximum time to wait for the AAP job to complete."
  type        = number
  default     = 600
}

./outputs.tf

terraform apply 完了後に、作成されたEC2インスタンスのIDやパブリックIPを表示するための出力定義ファイルです。

output "instance_id" {
  description = "The ID of the EC2 instance."
  value       = aws_instance.my_instance.id
}

output "public_ip" {
  description = "The public IP address of the EC2 instance."
  value       = aws_instance.my_instance.public_ip
}

3. AAPにTerraform連携用オブジェクトを作成

Inventoryの作成

Ansible実行対象の情報はTerraformのaap_hostによって登録されるので、インベントリの箱だけを作っておきます。

  1. AAPにてAutomation Execution > Infrastructure > インベントリーを選択
  2. [インベントリーの作成]の後、さらに[インベントリーの作成]を選択
  3. 以下を入力して、[インベントリーの作成]を選択
    • 名前: inv_terraform
    • 組織: Default

Credentialの作成

Ansible実行対象への接続に必要な認証情報を定義します。

  1. AAPにてAutomation Execution > Infrastructure > 認証情報を選択
  2. [認証情報の作成]を選択
  3. 以下を入力して、[認証情報の作成]を選択
    • 名前: cred_target_node
    • 組織: Default
    • ユーザー名: ec2-user
    • SSH Private Key: 秘密鍵の中身を添付

Job Templateの作成

  1. AAPにてAutomation Execution > テンプレートを選択
  2. [テンプレートの作成]の後、さらに[ジョブテンプレートの作成]を選択
  3. 以下を入力して、[ジョブテンプレートの作成]を選択
    • 名前: Terraform Test Job
    • インベントリー: inv_terraform
    • プロジェクト: 任意のプロジェクト
    • Playbook: 任意のPlaybook
      • サンプル用Playbook(display_facts.yml)は後述
    • 認証情報: cred_target_node

今回のサンプル用Playbook(display_facts.yml)は以下のように、ファクトを収集してDistributionを表示します。

---
- hosts: all
  gather_facts: false
  tasks:
    - name: Gather minimal facts
      ansible.builtin.setup:
        gather_subset:
          - '!all'

    - name: Display distribution
      ansible.builtin.debug:
        var: ansible_facts['distribution']

4. Terraformの実行

  1. Terraformを実行する環境で、環境変数を定義します

    export AAP_HOST=https://<aap_ip_address>
    export AAP_USERNAME=admin
    export AAP_PASSWORD=<admin_password>
    export AAP_INSECURE_SKIP_VERIFY=true
    
  2. Terraformを実行します

    $ terraform init
    $ terraform plan
    $ terraform apply
    

5. 実行結果の確認

Terraform実行画面

実行結果の最後の方を見ると、Action startedでAAPのJob Templateが実行されたことが見受けられます。

Action started: action.aap_job_launch.job_launch (triggered by aap_host.host)
Action complete: action.aap_job_launch.job_launch (triggered by aap_host.host)
╷
│ Warning: Unable to determine EDA API endpoint
│
│   with provider["registry.terraform.io/ansible/aap"],
│   on main.tf line 20, in provider "aap":
│   20: provider "aap" {}
│
│ The EDA endpoint is missing from response
╵

Apply complete! Resources: 8 added, 0 changed, 0 destroyed. Actions: 1 invoked.

Outputs:

instance_id = "i-XXXXXXXXXXXXXXXXX"
public_ip = "XXX.XXX.XXX.XXX"

実行結果でWarningが出ていますが、今回はEDAを使用していないので無視して問題ありません

Job Template実行結果

Terraform actionsによってJob Templateが実行されて、ファクトを収集できていることが確認できます。

PLAY [all] ********************************************************************* 13:30:50

TASK [Gather minimal facts] **************************************************** 13:30:50
ok: [test-ec2-instance]

TASK [Display distribution] **************************************************** 13:30:52
ok: [test-ec2-instance] => {
"ansible_facts['distribution']": "Amazon"
}

PLAY RECAP *********************************************************************
test-ec2-instance : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

さいごに

本記事では、Terraform actionsとaap プロバイダーを活用し、terraform applyでEC2 インスタンスの作成から AAP による Playbook の実行までを一気通貫で自動化する手順を解説しました。
Terraform actions を活用すれば、複雑な CI/CD パイプラインを組んだりすることなく、インフラの構築からJob Templateの実行までを1つのワークフローとしてシンプルに完結できます。
今後インフラの構築から初期設定までを一気に自動化したいと考えている方は、ぜひ今回の Terraform actionsを試してみてください!

参考URL


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?