TIL: Forcing Terraform to deploy a aws_api_gateway_deployment

Terraform’s aws_api_gateway_deployment won’t deploy subsequent releases in the event that something has changed in an integration, method, etc because nothing in the actual aws_api_gateway_deployment module changed. This is by design so that you can have a shared definition of your API across stages, but then do environment/stage specific deployments.

Where this gets annoying with Terraform is there isn’t really an easy way to force a deployment other than manually tainting the resource.

One easy way to trigger a change to the deployment is by adding a variable to the deployments variables map including some sort of version for the release. Now you can set a TF_VAR_* for a release version and terraform will detect a change in the deployment allowing you to apply it.

Then in your terminal:

export TF_VAR_deployed_at=$(date +%s)
terraform plan

And you should see similar output:

-/+ resource.aws_api_gateway_deployment.instance
created_date: "2017-03-16T18:06:57Z" => "<computed>"
rest_api_id: "YOUR_ID" => "YOUR_ID"
stage_name: "prod" => "prod"
variables.%: "1" => "1"
variables.version: "1489687441" => "1489687500" (forces new resource)

Hooray.

Update:

This is still an open issue we ended up using the git hash of terraform module to force a deployment on change.

export TF_VAR_version=$(git hash-object ./path/to/my/module.tf | awk '{ print substr($1,0,6) }')

If you have multiple files that make up a deployment you could do something like:

export TF_VAR_version=$(git hash-object ./file/one.tf ./file/two.tf | awk '{ print substr($1,0,6) }' | paste -sd ":" -)

As noted in the comments there its a timestamp() method which is very helpful for always forcing a deployment.