While Red Hat® Ansible Automation Platform (AAP)® can certainly handle your Day 1 cloud native provisioning tasks end to end, sometimes you just want Terraform® to hand off a server it just built to AAP, maybe to do something like register the host in an inventory and then run an AAP job template, without bouncing between tools.

Two methods are available:

  1. The pre-AAP 2.5 method: null_resource + local-exec + AAP REST API calls (works anywhere).
  2. The new official Red Hat provider method: the ansible/aap provider.

1. The pre-AAP 2.5 Method: local-exec + API Calls

When you’re running AAP prior to 2.5 and you can’t (or simply don’t want to) use a provider (e.g., in an environment with no extra dependencies) you can make raw API calls from Terraform using the tried-and-true null_resource + local-exec pattern.

Classic example:

# main.tf
variable "aap_url" {}
variable "aap_token" {}
variable "inventory_id" {}
variable "new_host_name" {}
variable "job_template_id" {}

resource "null_resource" "aap_add_host" {
  provisioner "local-exec" {
    command = <<EOT
      curl -s -X POST \
        -H "Authorization: Bearer ${var.aap_token}" \
        -H "Content-Type: application/json" \
        -d '{"name": "${var.new_host_name}"}' \
        "${var.aap_url}/api/v2/inventories/${var.inventory_id}/hosts/"
    EOT
  }
}

resource "null_resource" "aap_launch_job" {
  provisioner "local-exec" {
    command = <<EOT
      curl -s -X POST \
        -H "Authorization: Bearer ${var.aap_token}" \
        -H "Content-Type: application/json" \
        "${var.aap_url}/api/v2/job_templates/${var.job_template_id}/launch/"
    EOT
  }
  depends_on = [null_resource.aap_add_host]
}
  • Works with any Terraform install
  • No provider install needed
  • No stateful tracking of job runs

2. The New Official Provider Method: ansible/aap

Red Hat’s new official ansible/aap provider for Terraform Enterprise brings stateful, typed resources for AAP objects and jobs, and it works with the default terraform program as well.

Provider block

# provider block
terraform {
  required_providers {
    aap = {
      source  = "ansible/aap"
      version = "1.3.0-prerelease2" # or newer
    }
  }
}

provider "aap" {
  host     = "https://<AAP_IP_OR_FQDN>"
  username = "admin"
  password = "<PASSWORD>"
  # export AAP_INSECURE_SKIP_VERIFY=true to bypass TLS checks (dev only)
}

Full example: create inventory → add host/group → launch job

Note: this .tf file assumes you are running on a Mac Silicon-based macOS and is adapted from https://registry.terraform.io/providers/ansible/aap/latest/docs

# main.tf
# This example creates an inventory named `My new inventory`
# and adds a host `tf_host` and a group `tf_group` to it,
# and then launches a job based on the "Demo Job Template"
# in the "Default" organization using the inventory created.
#
terraform {
  required_providers {
    aap = {
      source = "ansible/aap"
      version = "1.3.0-prerelease2"
    }
  }
}

provider "aap" {
  host     = "https://<AAP_IP_OR_FQDN>"
  username = "admin"
  password = "<PASSWORD>"
}

resource "aap_inventory" "my_inventory" {
  name         = "My new inventory"
  description  = "A new inventory for testing"
  organization = 1
  variables = jsonencode(
    {
      "foo" : "bar"
    }
  )
}

resource "aap_group" "my_group" {
  inventory_id = aap_inventory.my_inventory.id
  name         = "tf_group"
  variables = jsonencode(
    {
      "foo" : "bar"
    }
  )
}

resource "aap_host" "my_host" {
  inventory_id = aap_inventory.my_inventory.id
  name         = "tf_host"
  variables = jsonencode(
    {
      "foo" : "bar"
    }
  )
  groups = [aap_group.my_group.id]
}

data "aap_job_template" "demo_job_template" {
  name              = "Demo Job Template"
  organization_name = "Default"
}

# In order for passing the inventory id to the job template execution, the Inventory on the job template needs to be set to "prompt on launch"
resource "aap_job" "my_job" {
  inventory_id    = aap_inventory.my_inventory.id
  job_template_id = data.aap_job_template.demo_job_template.id
  # This resource creation needs to wait for the host and group to be created in the inventory
  depends_on = [
    aap_host.my_host,
    aap_group.my_group
  ]
}

Platform Notes

  • Apple Silicon: Use ansible/aap >= v1.3.0-prerelease2 to run locally. Older versions lacked darwin_arm64 builds.
  • HCP Terraform / Terraform Enterprise: Runs provider on Linux/amd64, so no local platform issues.
  • TLS with self-signed certs:
    • Dev-only: export AAP_INSECURE_SKIP_VERIFY=true before running Terraform.
    • Better: fix SANs or trust your internal CA.

In order to successfully test using the example above, you’ll need to modify the Demo Job Template which ships with AAP.

Edit Job Template: Inventory: click “Prompt on launch”.

AAP Demo Job Template – Inventory – check “Prompt on Launch”

Steps to test (assumes you have a running AAP controller to target, that you’ve defined a real managed host, with valid Machine credentials attached to your Demo Job Template):

# steps to run in dev-only:
export AAP_INSECURE_SKIP_VERIFY=true
terraform init -upgrade
# vi main.tf # to paste your .tf file
terraform validate
terraform plan
terraform apply

Successful results:

Successful terraform apply

And upon success, you should also see a new inventory in AAP:

New AAP inventory
Successful AAP job run

Wrapping Up

Terraform and AAP each shine in their own rights, but they’re often at their best when combined. When you are looking for Hashicorp’s approach to state management of your cloud native resources, Terraform can lay down cloud infrastructure for you on Day 1, while AAP handles all of your configuration and orchestration needs starting Day 2. And the hand-off between them can be as simple or as sophisticated as your infrastructure as code workflows may demand. Whether you start with a lightweight local-exec hook, or adopt the official provider for full state tracking, the end result is a cleaner and more connected automation pipeline than ever.

If you’re curious about applying more cloud native patterns like this in your own environment, Red Hat Premier Partner Level Up is here for you: arc@levelupla.io.

Get the latest from Level Up delivered to your inbox– DevOps Automation and Cloud news, tips & tricks.

Select list(s) to subscribe to


By submitting this form, you are consenting to receive marketing emails from: Level Up, 20929 Ventura Blvd Ste 47 #265, Woodland Hills, CA, 91364. You can revoke your consent to receive emails at any time by using the SafeUnsubscribe® link, found at the bottom of every email. Emails are serviced by Constant Contact

Spread the word. Share this post!