I am attempting to use the terraform-provider-http to fill in some gaps within the Heroku Terraform provider. This data item allows for an HTTP POST against an API endpoint. I would like to restrict the creation of this data resource to only fire once. I don’t want that POST to ever be fired again.
With a standard resource that follows Terraform lifecycle rules, this is easy:
lifecycle {
ignore_changes = all
}
However with a data resource, this is not possible.
Is there a way to only fire a data resource when that resource doesn’t already exist in state?
One of the things I am using this to do is to initiate an API call to seed the database. This CANNOT be done more than once; once the initial setup and configuration of the database is done, this should never be done again.
No, this is not possible. Although I wish Terraform posessed the ability to re-use data source data from the state, it doesn’t, and the presence of data source data in the state file is only used for visualizing the results or debugging.
I think I have a solution that doesn’t require the use of a null_resource or building a custom provider. I have the following inside each of the data resources I want to run once:
count = var.first_apply ? 1 : 0
Then that variable is defined with a default of false.
For the first run, I explicitly set the variable to true in a tfvars file; then after that apply, I remove the variable from the tfvars file and the default takes over. It is not pretty, but I think it will accomplish the goals I have.
In general, I’m not a fan of the count keyword, but in this case, it’s a transparent/obvious way to pull this off. I would be curious if someone has a better idea - I’m all ears.
Something to consider here is that the intent of a data source is to only read data. The dependency resolution and evaluation in Terraform counts on the fact that a data source cannot have any side effects. Data sources implemented with side effects can cause other confusing situations where it takes multiple applies to converge on a stable state (if it reaches that point at all), or the apply fails entirely when the final state is not valid for the given plan. If side effects are required, then the action should be accomplished with a managed resource.