Custom providers for highly async resources

Has anyone ever written a Terraform provider for highly asynchronous resources that take a very long time to create, and may require additional processing or approvals outside of the Terraform flow?

I’m thinking about enterprisey use cases, such as:

  • Issue a TLS certificate from an internal CA with a multi-stage API requiring human approvals
  • Configure something on an internal OpenID identity provider (with a multi-stage API requiring human approvals)
  • Creating service accounts in Active Directory (you guessed it - human approvals)
  • Creating firewall rules

Approvals would obviously be handled outside Terraform, and I suppose from a Terraform perspective, the resource would have to show as created while it was still going through approvals and processing.

Has anyone done anything similar? Is this doomed to failure?

Hi @Oli_UK,

Since Terraform is designed for automating a sequence of operations with information propagated between them automatically, it isn’t well suited to situations like you described here where each step includes an unbounded amount of time waiting for a separate approval.

The only design that I can think of for a situation like that is to implement a resource type representing the creation of an approval request – that is, it only starts the process – where that resource type would take the inputs required to file the request in the usual way, but would not export any result attributes because it will not be able to generate a useful result in a timely manner, and so “creation complete” here means that the request was logged, not that the whole process is complete.

You could potentially then couple each request resource type with a data source which can retrieve results once a request is complete. I imagine that such a data source would return an error until the target object is complete enough to proceed with the next step, but would succeed if the target object is ready to use.

Putting those together then, I’d then write a separate Terraform configuration for each of your steps here, where all but the last one ends by creating a request, and all but the first one starts by consuming the result of a previous request using a data source. The Terraform-based equivalent of your list would then be:

  1. Apply the configuration which declares a TLS certificate request, thus starting the approval process. Wait for approval before continuing.
  2. Apply the configuration which declares the request to create the OpenID provider object. Wait for approval before continuing.
  3. Apply the configuration which declarers the request to create the service accounts. Wait for approval before continuing.
  4. Apply the configuration which creates the firewall rules.

For steps 2 through 4, you would see an error from the data source if you try to apply the change before the previous approval is completed, but once approved you can run the next step to nudge the process along one stage, until you reach the end.

Whether such a thing would be useful and better than the corresponding manual process I’m not sure. One potential advantage of using Terraform here is that you can include extra resources and data sources to help maintain and transfer state between the steps, so that the inputs required by steps 2 through 4 will be minimal.