Terraform continues to evolve beyond plan/apply into an event-driven workflow engine. With Terraform Actions, we can declaratively bind provider-specific actions to lifecycle events like after_create and after_update. In this post, I'll cover what Terraform Actions are and introduce the new AAP provider features. Released in v1.4.0, aap_job_launch can trigger job templates, and coming in a future release, aap_workflow_job_launch, will trigger workflow job templates directly from Terraform.
What are Terraform Actions?
Terraform Actions let you register operations that run when resources change state. This allows clean orchestration patterns: provision infrastructure first, then call downstream APIs to perform post-provision configuration, registrations, or notifications.
sequenceDiagram
participant TF as Terraform
participant Prov as Provider Action
participant AAP as AAP
participant Infra as Cloud Resource
TF->>Infra: Create resource (apply)
TF->>Prov: Lifecycle event: after_create
Prov->>AAP: Launch Job/Workflow
AAP-->>Prov: Job ID / Workflow ID
loop Poll until final state
Prov->>AAP: Get status
AAP-->>Prov: running | successful | failed
end
Prov-->>TF: Completion (success/failure)
Why pair Terraform with AAP?
AAP centralizes automation with RBAC, audit trails, execution environments, and logging. Many teams want infrastructure to be provisioned by Terraform, then configured by Ansible. Actions provide a clean bridge: Terraform creates infrastructure; AAP performs the operational configuration.
New AAP Actions
Along with the maintainers, I contributed two new actions:
- aap_job_launch: Launches a job template.
- aap_workflow_job_launch: Launches a workflow job template.
Trigger a notification for host creation
Bind an AAP job to the instance's after_create event and pass instance attributes into extra_vars. The extra_vars parameter allows you to pass dynamic data from your Terraform resources to your Ansible playbooks, enabling your playbooks to access infrastructure details like instance IDs, IP addresses, and other resource attributes.
terraform {
required_providers {
aap = {
source = "ansible/aap"
}
}
}
provider "aap" {
host = "https://myaap.example.com"
token = "aap-token" # or set AAP_TOKEN
}
action "aap_job_launch" "notify_host_creation" {
config {
job_template_id = var.notification_job
extra_vars = jsonencode({
instance_id = aws_instance.web.id
private_ip = aws_instance.web.private_ip
})
wait_for_completion = true
wait_for_completion_timeout_seconds = 300
}
}
resource "aws_instance" "web" {
ami = "ami-02029c87fa31fb148"
instance_type = "t3.micro"
subnet_id = "subnet-0b6f49a6b1e635b18"
lifecycle {
action_trigger {
events = [after_create]
actions = [action.aap_job_launch.notify_host_creation]
}
}
}
Workflow Based Configuration
Alternatively, after the instance is provisioned, you can trigger an Ansible Automation Platform (AAP) Workflow Job to apply multiple tasks such as applying final security settings, registering the instance with monitoring tools, or deploying application-specific dependencies. Workflows are ideal when you need to orchestrate multiple job templates in sequence or parallel.
action "aap_workflow_job_launch" "last_mile" {
config {
workflow_job_template_id = var.workflow_template_id
extra_vars = jsonencode({
instance_id = aws_instance.web.id
monitoring_tier = "production"
})
wait_for_completion = true
wait_for_completion_timeout_seconds = 900
}
}
resource "aws_instance" "web" {
ami = "ami-0123456789abcdef0"
instance_type = "t3.micro"
lifecycle {
action_trigger {
events = [after_create]
actions = [action.aap_workflow_job_launch.last_mile]
}
}
}
Utilization Tips
-
Inventory scoping: Set
inventory_idor encode target selection inextra_varsconsumed by your templates. This allows your playbooks to dynamically target the newly created infrastructure. -
Fire-and-forget notifications: Set
wait_for_completion = falseto launch jobs asynchronously without blocking Terraform execution. For notifications that shouldn't block your apply, this prevents timeouts on long-running jobs. -
Error handling: When
wait_for_completion = true, failed jobs will cause Terraform to fail. Useignore_job_results = trueif you want Terraform to proceed even if the job fails (useful for non-critical notifications). -
Choosing jobs vs workflows: Use
aap_job_launchfor single playbook execution. Useaap_workflow_job_launchwhen you need to orchestrate multiple job templates, handle conditional logic, or run tasks in parallel.