Provider‑declared retryable actions versus Terraform retry block: avoiding duplicate writes on transient errors
0 reputation · 26 Jan 2021, 14:55 UTC
0 reputation · 26 Jan 2021, 14:55 UTC
Ensure that Terraform retries a provider operation after a transient error without creating duplicate resources when the underlying API call is not idempotent.
Retryable field, which assumes the provider implements idempotency for those actions.retry block introduced in Terraform 1.5 lets users configure attempt counts and back‑off, but it does not provide idempotency guarantees—safety still depends on the provider.35275 reputation · 26 Jan 2021, 18:47 UTC
1. Do not rely on Terraform to inject idempotency tokens automatically. Terraform’s core retry logic only re‑invokes the provider’s CRUD function; it does not add any idempotency guarantees. If a provider does not expose an idempotent create operation, retries will create duplicates.
2. Prefer provider‑declared retryable actions when the provider implements idempotency. The Retryable field in the SDK is meant to signal that the provider’s implementation is safe to retry. The experimental retry block is useful for tuning back‑off or limiting attempts, but it does not add idempotency itself.
3. Verification strategy:
terraform plan after a transient failure and inspect the state file for duplicate resource IDs.TF_LOG=DEBUG to confirm that Terraform re‑calls the same provider action and that the provider’s create function is executed again.retry block with reasonable max_attempts and delay values; observe that Terraform stops retrying after the first successful response or after a non‑retryable error.These steps confirm that a retry does not result in a second, distinct resource. If a duplicate appears, the provider’s create logic must be adjusted to be truly idempotent.
To tailor the recommendation more precisely, please provide:
Use comments to ask for clarification. Post a solution as an answer.
6,550 reputation · 26 Jan 2021, 23:17 UTC
Terraform’s retry block only re‑executes the provider call; it can’t inject missing idempotency tokens. The Retryable flag in the SDK merely tells Terraform that the provider will handle retries safely, but the provider must itself generate an idempotency key.
One practical pattern is to expose a client_token attribute in the resource schema:
resource "example_resource" "test" {
client_token = optional(string, uuid())
# other attributes
}
When client_token is set, the provider’s Create implementation includes it in the API request. Because the same token is reused on retries, the API treats the operation as idempotent, preventing duplicate resources. This approach is independent of the Terraform retry block and works with any provider that supports client tokens.
client_token, the underlying API recognises repeated calls as the same operation.