Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: consideration for retry v2 #745

Merged
merged 45 commits into from
Mar 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5313bf8
add 429 as an retryable status code
hqhqhqhqhqhqhqhqhqhqhq Dec 24, 2024
e42c144
update
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
22eb738
update
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
e00a32f
Update azapi_data_plane_resource.go
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
d7fc5da
update
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
f35993b
Update azapi_resource.go
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
a85c864
update
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
108022b
Update azapi_data_plane_resource.go
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
9ef5f6f
Update azapi_data_plane_resource.go
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
ff6455a
Update azapi_data_plane_resource.go
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
a6e8458
Update azapi_resource_action_ephemeral.go
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
6fbdad7
update
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
c6a456f
Update azapi_resource.go
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
ad6d6ac
Update azapi_data_plane_resource.go
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
4068e45
Update azapi_data_plane_resource.go
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
535f225
Update common.go
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
2caa155
Update common.go
hqhqhqhqhqhqhqhqhqhqhq Jan 22, 2025
88219a4
feat: retryv2
matt-FFFFFF Jan 31, 2025
604a459
style: go lint
matt-FFFFFF Jan 31, 2025
c3c0145
test: remove old test
matt-FFFFFF Jan 31, 2025
510ff7c
feat: update default retry
matt-FFFFFF Jan 31, 2025
5cf4c45
fix: incorrect doc defaults
matt-FFFFFF Jan 31, 2025
e5d7e26
fix: make error messages optional
matt-FFFFFF Jan 31, 2025
6c4f815
docs: updates following review
matt-FFFFFF Jan 31, 2025
b11892c
feat: add skip external request
matt-FFFFFF Feb 1, 2025
22c07b1
docs: remove duplicate sentence
matt-FFFFFF Feb 1, 2025
3be6445
test: fix test and move skip package to correct location
matt-FFFFFF Feb 1, 2025
4f9e7d9
refactor: change name of provider retry attribute
matt-FFFFFF Feb 1, 2025
13919be
docs: update guide with new attr name
matt-FFFFFF Feb 1, 2025
f6594d1
Revert "test: fix test and move skip package to correct location"
matt-FFFFFF Feb 24, 2025
4473c4d
Revert "feat: add skip external request"
matt-FFFFFF Feb 24, 2025
de9956c
Merge branch 'main' of https://github.com/matt-FFFFFF/terraform-provi…
matt-FFFFFF Feb 24, 2025
0499042
refactor: update retry based on feedback
matt-FFFFFF Feb 24, 2025
fafe386
Merge branch 'main' into feat/retryv2
matt-FFFFFF Feb 24, 2025
ecb1f64
docs: make docs
matt-FFFFFF Feb 24, 2025
404956b
chore: lint
matt-FFFFFF Feb 24, 2025
d35f29d
feat: adopt agreed 2.3 retry
matt-FFFFFF Feb 28, 2025
11e96ba
test: update tests
matt-FFFFFF Feb 28, 2025
f38270c
test: improve tests
matt-FFFFFF Feb 28, 2025
bcecd66
fix: make err message required
matt-FFFFFF Feb 28, 2025
c95a0ba
Merge remote-tracking branch 'upstream/main' into feat/retryv2
matt-FFFFFF Feb 28, 2025
6dfbbff
vendor
matt-FFFFFF Feb 28, 2025
d830967
docs: docs
matt-FFFFFF Feb 28, 2025
4df3d6b
chore: refactor client retry configure func due to linter
matt-FFFFFF Feb 28, 2025
7d12095
fix: updates following PR review
matt-FFFFFF Mar 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/data-sources/resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ output "quarantine_policy" {
```

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `retry` (Attributes) The retry block supports the following arguments: (see [below for nested schema](#nestedatt--retry))
- `retry` (Attributes) The retry object supports the following attributes: (see [below for nested schema](#nestedatt--retry))
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))

### Read-Only
Expand Down Expand Up @@ -136,7 +136,7 @@ To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).

Required:

- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the error is considered retryable.
- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the request will be retried.

Optional:

Expand Down
4 changes: 2 additions & 2 deletions docs/data-sources/resource_action.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ data "azapi_resource_action" "example" {
```

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `retry` (Attributes) The retry block supports the following arguments: (see [below for nested schema](#nestedatt--retry))
- `retry` (Attributes) The retry object supports the following attributes: (see [below for nested schema](#nestedatt--retry))
- `sensitive_response_export_values` (Dynamic) The attribute can accept either a list or a map.

- **List**: A list of paths that need to be exported from the response body. Setting it to `["*"]` will export the full response body. Here's an example. If it sets to `["properties.loginServer", "properties.policies.quarantinePolicy.status"]`, it will set the following HCL object to the computed property sensitive_output.
Expand Down Expand Up @@ -154,7 +154,7 @@ To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).

Required:

- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the error is considered retryable.
- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the request will be retried.

Optional:

Expand Down
4 changes: 2 additions & 2 deletions docs/data-sources/resource_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ data "azapi_resource_list" "listSubnetsByVnet" {
```

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `retry` (Attributes) The retry block supports the following arguments: (see [below for nested schema](#nestedatt--retry))
- `retry` (Attributes) The retry object supports the following attributes: (see [below for nested schema](#nestedatt--retry))
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))

### Read-Only
Expand All @@ -138,7 +138,7 @@ To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).

Required:

- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the error is considered retryable.
- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the request will be retried.

Optional:

Expand Down
4 changes: 2 additions & 2 deletions docs/ephemeral-resources/resource_action.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ ephemeral "azapi_resource_action" "listKeys" {
```

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `retry` (Attributes) The retry block supports the following arguments: (see [below for nested schema](#nestedatt--retry))
- `retry` (Attributes) The retry object supports the following attributes: (see [below for nested schema](#nestedatt--retry))
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))

### Read-Only
Expand All @@ -123,7 +123,7 @@ To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).

Required:

- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the error is considered retryable.
- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the request will be retried.

Optional:

Expand Down
61 changes: 55 additions & 6 deletions docs/guides/feature_customized_retry.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,64 @@ description: |-

---

The AzAPI provider can digest the intermittent API errors and retry the requests based on the customized retry configuration. This feature is useful when you need to handle the API errors gracefully and improve the reliability of the Terraform deployments.
## Why retry?

Sometimes, when managing cloud infrastructure, requests to the cloud provider may fail due to transient issues such as network problems, timeouts, eventual consistency, or rate limiting. In these cases, it can be beneficial to retry the request a few times before giving up.

The AzAPI provider can digest these intermittent API errors and retry the requests based on the customized retry configuration. This feature is useful when you need to handle the API errors gracefully and improve the reliability of the Terraform deployments.

## Prerequisites

- [Terraform AzAPI provider](https://registry.terraform.io/providers/azure/azapi) version 2.1.0 or later
- [Terraform AzAPI provider](https://registry.terraform.io/providers/azure/azapi) version 2.1.0 or later. Some features are only available from version 2.3.0.

## Retry configuration

There are two types of retry configurations available in the AzAPI provider:

1. Provider retry configuration
2. Resource-specific retry configuration

### Provider retry configuration

The provider retry configuration is a global configuration that applies to all resources managed by the provider. You can configure the provider retry behavior by setting the following provider values:

- `maximum_busy_retry_attempts`

This value controls the number of times the provider will retry a failed request. The default value is `3`.
A retry will be triggered if the request fails with HTTP 408, 429, 500, 502, 503, or 504.

In the case that the response header contains a `Retry-After` value, the provider will wait for the specified duration before retrying the request.

### Resource-specific retry configuration

In addition to the provider retry configuration, you can also configure the retry behavior for individual resources. This allows you to fine-tune the retry behavior for specific resources.

## Customized Retry for Resource Creation
The resource-specific retry comes after the provider retry, that is to say that the provider retry will be attempted first, and if it fails or exceeds the maximum attempts, the resource-specific retry will be attempted.
Note that the resource-specific retry does not honour the `Retry-After` header and is exponential backoff based.

Resource specific retry is configured using the `retry` attribute.

If you configure a retry configuration, the maximum elapsed time for the retry will be set to the resource's timeout value for that operation (create, update, read, delete).

With `azapi_resource` and `azapi_data_plane_resource`, the provider performs a read operation after the resource has been created so that we can store the read-only values.

The schema of these retry attributes is as follows:

- `error_message_regex` - A list of regular expressions to match against error messages. If any of the regular expressions match, the request will be retried.
- `interval_seconds` - The initial number of seconds to wait before the 1st retry. The default value is `10`.
- `max_interval_seconds` - The maximum number of seconds to wait before retrying a request. The default value is `180`.
- `multiplier` - The multiplier to apply to the interval between retries. The default value is `1.5`.
- `randomization_factor` - The randomization factor to apply to the interval between retries. The default value is `0.5`. The formula for the randomized interval is: `RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor])`. Set to zero `0.0` for no randomization.

## Default resource-specific retry configuration

If you do not configure any retry values, the provider will use the following:

For the initial create/read/update/delete operation we will only retry on the provider's `maximum_busy_retry_attempts` value.

For the read-after-create, the provider will retry on HTTP 404 and 403 status codes up to the operation timeout. This is logical as, if we have just successfully created the resource, we should not be getting a 404 or 403 on any subsequent GET request.

## Example - Customized Retry for Resource Creation

The virtual network link resource may not be available immediately after the virtual network is created. In this case, you can configure the customized retry configuration to handle the `ResourceNotFound` error and retry the request.

Expand Down Expand Up @@ -41,9 +91,9 @@ resource "azapi_resource" "privateDnsZoneLinkBlob" {
}
```

Above configuration is only used for demonstration purposes. From the `2.0.1` version, the AzAPI provider will automatically retry the GET requests when the `ResourceNotFound` error occurs after the resource creation.
Above configuration is only used for demonstration purposes. From the `2.0.1` version, the AzAPI provider will automatically retry the GET requests when the `ResourceNotFound` error occurs after the resource creation.

## Customized Retry for Resource Deletion
## Example - Customized Retry for Resource Deletion

The private DNS zone may not be deleted immediately after the nested virtual network link is deleted. In this case, you can configure the customized retry configuration to handle the `CannotDeleteResource` error and retry the request.

Expand All @@ -62,4 +112,3 @@ resource "azapi_resource" "privateDnsZoneQueue" {
}
}
```

1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ provider "azapi" {
- `enable_preflight` (Boolean) Enable Preflight Validation. The default is false. When set to true, the provider will use Preflight to do static validation before really deploying a new resource. When set to false, the provider will disable this validation. This can also be sourced from the `ARM_ENABLE_PREFLIGHT` Environment Variable.
- `endpoint` (Attributes List) The Azure API Endpoint Configuration. (see [below for nested schema](#nestedatt--endpoint))
- `environment` (String) The Cloud Environment which should be used. Possible values are `public`, `usgovernment` and `china`. Defaults to `public`. This can also be sourced from the `ARM_ENVIRONMENT` Environment Variable.
- `maximum_busy_retry_attempts` (Number) The maximum number of retries to attempt if the Azure API returns an HTTP 408, 429, 500, 502, 503, or 504 response. The default is `3`. The resource-specific retry configuration may additionally be used to retry on other errors and conditions.
- `oidc_azure_service_connection_id` (String) The Azure Pipelines Service Connection ID to use for authentication. This can also be sourced from the `ARM_ADO_PIPELINE_SERVICE_CONNECTION_ID` or `ARM_OIDC_AZURE_SERVICE_CONNECTION_ID` Environment Variables.
- `oidc_request_token` (String) The bearer token for the request to the OIDC provider. This can also be sourced from the `ARM_OIDC_REQUEST_TOKEN` or `ACTIONS_ID_TOKEN_REQUEST_TOKEN` Environment Variables.
- `oidc_request_url` (String) The URL for the OIDC provider from which to request an ID token. This can also be sourced from the `ARM_OIDC_REQUEST_URL` or `ACTIONS_ID_TOKEN_REQUEST_URL` Environment Variables.
Expand Down
4 changes: 2 additions & 2 deletions docs/resources/data_plane_resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ resource "azapi_data_plane_resource" "example" {
```

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `retry` (Attributes) The retry block supports the following arguments: (see [below for nested schema](#nestedatt--retry))
- `retry` (Attributes) The retry object supports the following attributes: (see [below for nested schema](#nestedatt--retry))
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
- `update_headers` (Map of String) A mapping of headers to be sent with the update request.
- `update_query_parameters` (Map of List of String) A mapping of query parameters to be sent with the update request.
Expand All @@ -164,7 +164,7 @@ To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).

Required:

- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the error is considered retryable.
- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the request will be retried.

Optional:

Expand Down
4 changes: 2 additions & 2 deletions docs/resources/resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ resource "azapi_resource" "example" {
```

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `retry` (Attributes) The retry block supports the following arguments: (see [below for nested schema](#nestedatt--retry))
- `retry` (Attributes) The retry object supports the following attributes: (see [below for nested schema](#nestedatt--retry))
- `schema_validation_enabled` (Boolean) Whether enabled the validation on `type` and `body` with embedded schema. Defaults to `true`.
- `tags` (Map of String) A mapping of tags which should be assigned to the Azure resource.
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
Expand Down Expand Up @@ -208,7 +208,7 @@ Read-Only:

Required:

- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the error is considered retryable.
- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the request will be retried.

Optional:

Expand Down
4 changes: 2 additions & 2 deletions docs/resources/resource_action.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ description: |-
```

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `retry` (Attributes) The retry block supports the following arguments: (see [below for nested schema](#nestedatt--retry))
- `retry` (Attributes) The retry object supports the following attributes: (see [below for nested schema](#nestedatt--retry))
- `sensitive_response_export_values` (Dynamic) The attribute can accept either a list or a map.

- **List**: A list of paths that need to be exported from the response body. Setting it to `["*"]` will export the full response body. Here's an example. If it sets to `["properties.loginServer", "properties.policies.quarantinePolicy.status"]`, it will set the following HCL object to the computed property output.
Expand Down Expand Up @@ -175,7 +175,7 @@ To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).

Required:

- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the error is considered retryable.
- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the request will be retried.

Optional:

Expand Down
4 changes: 2 additions & 2 deletions docs/resources/update_resource.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ This resource can manage a subset of any existing Azure resource manager resourc
```

To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).
- `retry` (Attributes) The retry block supports the following arguments: (see [below for nested schema](#nestedatt--retry))
- `retry` (Attributes) The retry object supports the following attributes: (see [below for nested schema](#nestedatt--retry))
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
- `update_headers` (Map of String) A mapping of headers to be sent with the update request.
- `update_query_parameters` (Map of List of String) A mapping of query parameters to be sent with the update request.
Expand All @@ -167,7 +167,7 @@ To learn more about JMESPath, visit [JMESPath](https://jmespath.org/).

Required:

- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the error is considered retryable.
- `error_message_regex` (List of String) A list of regular expressions to match against error messages. If any of the regular expressions match, the request will be retried.

Optional:

Expand Down
24 changes: 12 additions & 12 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ require (
github.com/hashicorp/terraform-plugin-framework v1.13.0
github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1
github.com/hashicorp/terraform-plugin-framework-validators v0.13.0
github.com/hashicorp/terraform-plugin-go v0.25.0
github.com/hashicorp/terraform-plugin-go v0.26.0
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0
github.com/jmespath/go-jmespath v0.4.0
github.com/stretchr/testify v1.10.0
)
Expand All @@ -35,7 +35,7 @@ require (
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
github.com/cloudflare/circl v1.6.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.17.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/go-git/go-git/v5 v5.14.0 // indirect
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect
Expand All @@ -51,17 +51,17 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/hashicorp/hc-install v0.9.0 // indirect
github.com/hashicorp/hcl/v2 v2.21.0 // indirect
github.com/hashicorp/hcl/v2 v2.22.0 // indirect
github.com/hashicorp/logutils v1.0.0 // indirect
github.com/hashicorp/terraform-exec v0.21.0 // indirect
github.com/hashicorp/terraform-json v0.23.0 // indirect
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
github.com/hashicorp/terraform-registry-address v0.2.4 // indirect
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/huandu/xstrings v1.3.3 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
Expand All @@ -84,17 +84,17 @@ require (
github.com/zclconf/go-cty v1.15.0 // indirect
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect
golang.org/x/crypto v0.35.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/mod v0.23.0 // indirect
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.35.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/tools v0.30.0 // indirect
golang.org/x/tools v0.26.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
google.golang.org/grpc v1.67.1 // indirect
google.golang.org/protobuf v1.35.1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
google.golang.org/grpc v1.69.4 // indirect
google.golang.org/protobuf v1.36.3 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Expand Down
Loading
Loading