@@ -3,6 +3,7 @@ package awsmt
33import (
44 "context"
55 "github.com/aws/aws-sdk-go-v2/aws"
6+ "github.com/aws/aws-sdk-go-v2/aws/retry"
67 "github.com/aws/aws-sdk-go-v2/config"
78 "github.com/aws/aws-sdk-go-v2/service/mediatailor"
89 "github.com/hashicorp/terraform-plugin-framework/datasource"
@@ -12,6 +13,7 @@ import (
1213 "github.com/hashicorp/terraform-plugin-framework/types"
1314 "github.com/hashicorp/terraform-plugin-log/tflog"
1415 "os"
16+ "time"
1517)
1618
1719var (
@@ -25,8 +27,9 @@ func New() provider.Provider {
2527type awsmtProvider struct {}
2628
2729type awsmtProviderModel struct {
28- Profile types.String `tfsdk:"profile"`
29- Region types.String `tfsdk:"region"`
30+ Profile types.String `tfsdk:"profile"`
31+ Region types.String `tfsdk:"region"`
32+ MaxRetryAttempts types.Int64 `tfsdk:"max_retry_attempts"`
3033}
3134
3235func (p * awsmtProvider ) Metadata (_ context.Context , _ provider.MetadataRequest , resp * provider.MetadataResponse ) {
@@ -44,6 +47,10 @@ func (p *awsmtProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp
4447 Optional : true ,
4548 Description : "AWS region. defaults to 'eu-central-1'." ,
4649 },
50+ "max_retry_attempts" : schema.Int64Attribute {
51+ Optional : true ,
52+ Description : "The maximum number of times the provider will retry a failed aws operation. Defaults to 10" ,
53+ },
4754 },
4855 }
4956}
@@ -60,6 +67,7 @@ func (p *awsmtProvider) Configure(ctx context.Context, req provider.ConfigureReq
6067
6168 var region = "eu-central-1"
6269 var profile = ""
70+ var maxAttempts = 10
6371
6472 var err error
6573 // New sdk version creation
@@ -68,23 +76,18 @@ func (p *awsmtProvider) Configure(ctx context.Context, req provider.ConfigureReq
6876 if ! providerConfig .Region .IsUnknown () || ! providerConfig .Region .IsNull () {
6977 region = providerConfig .Region .ValueString ()
7078 }
71-
7279 if providerConfig .Profile .IsUnknown () || providerConfig .Profile .IsNull () || providerConfig .Profile .ValueString () == "" {
7380 if os .Getenv ("AWS_PROFILE" ) != "" {
7481 profile = os .Getenv ("AWS_PROFILE" )
7582 }
7683 } else {
7784 profile = providerConfig .Profile .ValueString ()
7885 }
79-
80- tflog .Debug (ctx , "Creating AWS client session" )
81-
82- if profile != "" {
83- cfg , err = config .LoadDefaultConfig (ctx , config .WithSharedConfigProfile (profile ), config .WithRegion (region ))
84- } else {
85- cfg , err = config .LoadDefaultConfig (ctx , config .WithRegion (region ))
86+ if ! providerConfig .MaxRetryAttempts .IsUnknown () || ! providerConfig .MaxRetryAttempts .IsNull () {
87+ maxAttempts = int (providerConfig .MaxRetryAttempts .ValueInt64 ())
8688 }
87-
89+ tflog .Debug (ctx , "Creating AWS client session" )
90+ cfg , err = p .getClientConfig (ctx , region , profile , maxAttempts )
8891 if err != nil {
8992 resp .Diagnostics .AddError ("Failed to Initialize Provider in Region" , "unable to initialize provider in the specified region: " + err .Error ())
9093 return
@@ -98,6 +101,28 @@ func (p *awsmtProvider) Configure(ctx context.Context, req provider.ConfigureReq
98101 tflog .Info (ctx , "AWS MediaTailor client configured" , map [string ]any {"success" : true })
99102}
100103
104+ func (p * awsmtProvider ) getClientConfig (ctx context.Context , region , profile string , maxAttempts int ) (aws.Config , error ) {
105+ backoff := customBackoff {
106+ minDelay : 500 * time .Millisecond ,
107+ }
108+ retryer := retry .NewStandard (func (o * retry.StandardOptions ) {
109+ o .Backoff = backoff
110+ o .MaxAttempts = maxAttempts
111+ o .MaxBackoff = 10 * time .Second
112+ })
113+
114+ var optFns []func (* config.LoadOptions ) error
115+ optFns = append (optFns , config .WithRegion (region ))
116+ optFns = append (optFns , config .WithRetryer (func () aws.Retryer {
117+ return retryer
118+ }))
119+ if profile != "" {
120+ optFns = append (optFns , config .WithSharedConfigProfile (profile ))
121+ }
122+
123+ return config .LoadDefaultConfig (ctx , optFns ... )
124+ }
125+
101126func (p * awsmtProvider ) DataSources (_ context.Context ) []func () datasource.DataSource {
102127 return []func () datasource.DataSource {
103128 DataSourceChannel ,
@@ -118,3 +143,16 @@ func (p *awsmtProvider) Resources(_ context.Context) []func() resource.Resource
118143 ResourceVodSource ,
119144 }
120145}
146+
147+ type customBackoff struct {
148+ minDelay time.Duration
149+ }
150+
151+ func (b customBackoff ) BackoffDelay (attempt int , err error ) (time.Duration , error ) {
152+ jb := retry .NewExponentialJitterBackoff (10 * time .Second )
153+ standardDelay , stdErr := jb .BackoffDelay (attempt , err )
154+ if stdErr != nil {
155+ return 0 , stdErr
156+ }
157+ return max (standardDelay , b .minDelay ), nil
158+ }
0 commit comments