From 3c384af92cc616f91b9d3fe7730cb70548494619 Mon Sep 17 00:00:00 2001 From: Roberth Kulbin <6707630+roberth-k@users.noreply.github.com> Date: Fri, 26 Aug 2022 20:06:16 +0100 Subject: [PATCH 1/3] r/aws_cloudfront_origin_access_control: new resource --- internal/provider/provider.go | 1 + .../cloudfront/origin_access_control.go | 195 +++++++++++ .../cloudfront/origin_access_control_test.go | 324 ++++++++++++++++++ ...dfront_origin_access_control.html.markdown | 52 +++ 4 files changed, 572 insertions(+) create mode 100644 internal/service/cloudfront/origin_access_control.go create mode 100644 internal/service/cloudfront/origin_access_control_test.go create mode 100644 website/docs/r/cloudfront_origin_access_control.html.markdown diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 74405cf216ed..c4d622e4b189 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1098,6 +1098,7 @@ func New(_ context.Context) (*schema.Provider, error) { "aws_cloudfront_function": cloudfront.ResourceFunction(), "aws_cloudfront_key_group": cloudfront.ResourceKeyGroup(), "aws_cloudfront_monitoring_subscription": cloudfront.ResourceMonitoringSubscription(), + "aws_cloudfront_origin_access_control": cloudfront.ResourceOriginAccessControl(), "aws_cloudfront_origin_access_identity": cloudfront.ResourceOriginAccessIdentity(), "aws_cloudfront_origin_request_policy": cloudfront.ResourceOriginRequestPolicy(), "aws_cloudfront_public_key": cloudfront.ResourcePublicKey(), diff --git a/internal/service/cloudfront/origin_access_control.go b/internal/service/cloudfront/origin_access_control.go new file mode 100644 index 000000000000..13ee52519fdd --- /dev/null +++ b/internal/service/cloudfront/origin_access_control.go @@ -0,0 +1,195 @@ +package cloudfront + +import ( + "context" + "errors" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/cloudfront" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func ResourceOriginAccessControl() *schema.Resource { + return &schema.Resource{ + CreateWithoutTimeout: resourceOriginAccessControlCreate, + ReadWithoutTimeout: resourceOriginAccessControlRead, + UpdateWithoutTimeout: resourceOriginAccessControlUpdate, + DeleteWithoutTimeout: resourceOriginAccessControlDelete, + + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: map[string]*schema.Schema{ + "description": { + Type: schema.TypeString, + Optional: true, + Default: "Managed by Terraform", + ValidateFunc: validation.StringLenBetween(0, 256), + }, + "etag": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 64), + }, + "origin_access_control_origin_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(cloudfront.OriginAccessControlOriginTypes_Values(), false), + }, + "signing_behavior": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(cloudfront.OriginAccessControlSigningBehaviors_Values(), false), + }, + "signing_protocol": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(cloudfront.OriginAccessControlSigningProtocols_Values(), false), + }, + }, + } +} + +const ( + ResNameOriginAccessControl = "Origin Access Control" +) + +func resourceOriginAccessControlCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).CloudFrontConn + + in := &cloudfront.CreateOriginAccessControlInput{ + OriginAccessControlConfig: &cloudfront.OriginAccessControlConfig{ + Description: aws.String(d.Get("description").(string)), + Name: aws.String(d.Get("name").(string)), + OriginAccessControlOriginType: aws.String(d.Get("origin_access_control_origin_type").(string)), + SigningBehavior: aws.String(d.Get("signing_behavior").(string)), + SigningProtocol: aws.String(d.Get("signing_protocol").(string)), + }, + } + + out, err := conn.CreateOriginAccessControlWithContext(ctx, in) + if err != nil { + return create.DiagError(names.CloudFront, create.ErrActionCreating, ResNameOriginAccessControl, d.Get("name").(string), err) + } + + if out == nil || out.OriginAccessControl == nil { + return create.DiagError(names.CloudFront, create.ErrActionCreating, ResNameOriginAccessControl, d.Get("name").(string), errors.New("empty output")) + } + + d.SetId(aws.StringValue(out.OriginAccessControl.Id)) + + return resourceOriginAccessControlRead(ctx, d, meta) +} + +func resourceOriginAccessControlRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).CloudFrontConn + + out, err := findOriginAccessControlByID(ctx, conn, d.Id()) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] CloudFront Origin Access Control (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return create.DiagError(names.CloudFront, create.ErrActionReading, ResNameOriginAccessControl, d.Id(), err) + } + + if out.OriginAccessControl == nil || out.OriginAccessControl.OriginAccessControlConfig == nil { + return create.DiagError(names.CloudFront, create.ErrActionReading, ResNameOriginAccessControl, d.Id(), errors.New("empty output")) + } + + config := out.OriginAccessControl.OriginAccessControlConfig + + d.Set("description", config.Description) + d.Set("etag", out.ETag) + d.Set("name", config.Name) + d.Set("origin_access_control_origin_type", config.OriginAccessControlOriginType) + d.Set("signing_behavior", config.SigningBehavior) + d.Set("signing_protocol", config.SigningProtocol) + + return nil +} + +func resourceOriginAccessControlUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).CloudFrontConn + + in := &cloudfront.UpdateOriginAccessControlInput{ + Id: aws.String(d.Id()), + IfMatch: aws.String(d.Get("etag").(string)), + OriginAccessControlConfig: &cloudfront.OriginAccessControlConfig{ + Description: aws.String(d.Get("description").(string)), + Name: aws.String(d.Get("name").(string)), + OriginAccessControlOriginType: aws.String(d.Get("origin_access_control_origin_type").(string)), + SigningBehavior: aws.String(d.Get("signing_behavior").(string)), + SigningProtocol: aws.String(d.Get("signing_protocol").(string)), + }, + } + + log.Printf("[DEBUG] Updating CloudFront Origin Access Control (%s): %#v", d.Id(), in) + _, err := conn.UpdateOriginAccessControlWithContext(ctx, in) + if err != nil { + return create.DiagError(names.CloudFront, create.ErrActionUpdating, ResNameOriginAccessControl, d.Id(), err) + } + + return resourceOriginAccessControlRead(ctx, d, meta) +} + +func resourceOriginAccessControlDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).CloudFrontConn + + log.Printf("[INFO] Deleting CloudFront Origin Access Control %s", d.Id()) + + _, err := conn.DeleteOriginAccessControlWithContext(ctx, &cloudfront.DeleteOriginAccessControlInput{ + Id: aws.String(d.Id()), + IfMatch: aws.String(d.Get("etag").(string)), + }) + + if tfawserr.ErrCodeEquals(err, cloudfront.ErrCodeNoSuchOriginAccessControl) { + return nil + } + + if err != nil { + return create.DiagError(names.CloudFront, create.ErrActionDeleting, ResNameOriginAccessControl, d.Id(), err) + } + + return nil +} + +func findOriginAccessControlByID(ctx context.Context, conn *cloudfront.CloudFront, id string) (*cloudfront.GetOriginAccessControlOutput, error) { + in := &cloudfront.GetOriginAccessControlInput{ + Id: aws.String(id), + } + out, err := conn.GetOriginAccessControlWithContext(ctx, in) + if tfawserr.ErrCodeEquals(err, cloudfront.ErrCodeNoSuchOriginAccessControl) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: in, + } + } + + if err != nil { + return nil, err + } + + if out == nil || out.OriginAccessControl == nil { + return nil, tfresource.NewEmptyResultError(in) + } + + return out, nil +} diff --git a/internal/service/cloudfront/origin_access_control_test.go b/internal/service/cloudfront/origin_access_control_test.go new file mode 100644 index 000000000000..4f022f6fd874 --- /dev/null +++ b/internal/service/cloudfront/origin_access_control_test.go @@ -0,0 +1,324 @@ +package cloudfront_test + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/cloudfront" + "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + tfcloudfront "github.com/hashicorp/terraform-provider-aws/internal/service/cloudfront" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccCloudFrontOriginAccessControl_basic(t *testing.T) { + var originaccesscontrol cloudfront.OriginAccessControl + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_cloudfront_origin_access_control.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(cloudfront.EndpointsID, t) + testAccPreCheck(t) + }, + ErrorCheck: acctest.ErrorCheck(t, cloudfront.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckOriginAccessControlDestroy, + Steps: []resource.TestStep{ + { + Config: testAccOriginAccessControlConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckOriginAccessControlExists(resourceName, &originaccesscontrol), + resource.TestCheckResourceAttr(resourceName, "description", "Managed by Terraform"), + resource.TestCheckResourceAttrSet(resourceName, "etag"), + resource.TestCheckResourceAttrWith(resourceName, "id", func(value string) error { + if value == "" { + return fmt.Errorf("expected attribute to be set") + } + + if id := aws.StringValue(originaccesscontrol.Id); value != id { + return fmt.Errorf("expected attribute to be equal to %s", id) + } + + return nil + }), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "origin_access_control_origin_type", "s3"), + resource.TestCheckResourceAttr(resourceName, "signing_behavior", "always"), + resource.TestCheckResourceAttr(resourceName, "signing_protocol", "sigv4"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccCloudFrontOriginAccessControl_disappears(t *testing.T) { + var originaccesscontrol cloudfront.OriginAccessControl + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_cloudfront_origin_access_control.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(cloudfront.EndpointsID, t) + testAccPreCheck(t) + }, + ErrorCheck: acctest.ErrorCheck(t, cloudfront.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckOriginAccessControlDestroy, + Steps: []resource.TestStep{ + { + Config: testAccOriginAccessControlConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckOriginAccessControlExists(resourceName, &originaccesscontrol), + acctest.CheckResourceDisappears(acctest.Provider, tfcloudfront.ResourceOriginAccessControl(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccCloudFrontOriginAccessControl_Name(t *testing.T) { + rName1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_cloudfront_origin_access_control.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(cloudfront.EndpointsID, t) + testAccPreCheck(t) + }, + ErrorCheck: acctest.ErrorCheck(t, cloudfront.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckOriginAccessControlDestroy, + Steps: []resource.TestStep{ + { + Config: testAccOriginAccessControlConfig_name(rName1), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", rName1), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccOriginAccessControlConfig_name(rName2), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "name", rName2), + ), + }, + }, + }) +} + +func TestAccCloudFrontOriginAccessControl_Description(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_cloudfront_origin_access_control.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(cloudfront.EndpointsID, t) + testAccPreCheck(t) + }, + ErrorCheck: acctest.ErrorCheck(t, cloudfront.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckOriginAccessControlDestroy, + Steps: []resource.TestStep{ + { + Config: testAccOriginAccessControlConfig_description(rName, "Acceptance Test 1"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "description", "Acceptance Test 1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccOriginAccessControlConfig_description(rName, "Acceptance Test 2"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "description", "Acceptance Test 2"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccOriginAccessControlConfig_description(rName, ""), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "description", ""), + ), + }, + }, + }) +} + +func TestAccCloudFrontOriginAccessControl_SigningBehavior(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_cloudfront_origin_access_control.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(cloudfront.EndpointsID, t) + testAccPreCheck(t) + }, + ErrorCheck: acctest.ErrorCheck(t, cloudfront.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckOriginAccessControlDestroy, + Steps: []resource.TestStep{ + { + Config: testAccOriginAccessControlConfig_signingBehavior(rName, "never"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "signing_behavior", "never"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccOriginAccessControlConfig_signingBehavior(rName, "no-override"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "signing_behavior", "no-override"), + ), + }, + }, + }) +} + +func testAccCheckOriginAccessControlDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).CloudFrontConn + ctx := context.Background() + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_cloudfront_origin_access_control" { + continue + } + + _, err := conn.GetOriginAccessControlWithContext(ctx, &cloudfront.GetOriginAccessControlInput{ + Id: aws.String(rs.Primary.ID), + }) + if err != nil { + if tfawserr.ErrCodeEquals(err, cloudfront.ErrCodeNoSuchOriginAccessControl) { + return nil + } + return err + } + + return create.Error(names.CloudFront, create.ErrActionCheckingDestroyed, tfcloudfront.ResNameOriginAccessControl, rs.Primary.ID, errors.New("not destroyed")) + } + + return nil +} + +func testAccCheckOriginAccessControlExists(name string, originaccesscontrol *cloudfront.OriginAccessControl) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return create.Error(names.CloudFront, create.ErrActionCheckingExistence, tfcloudfront.ResNameOriginAccessControl, name, errors.New("not found")) + } + + if rs.Primary.ID == "" { + return create.Error(names.CloudFront, create.ErrActionCheckingExistence, tfcloudfront.ResNameOriginAccessControl, name, errors.New("not set")) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).CloudFrontConn + ctx := context.Background() + resp, err := conn.GetOriginAccessControlWithContext(ctx, &cloudfront.GetOriginAccessControlInput{ + Id: aws.String(rs.Primary.ID), + }) + + if err != nil { + return create.Error(names.CloudFront, create.ErrActionCheckingExistence, tfcloudfront.ResNameOriginAccessControl, rs.Primary.ID, err) + } + + *originaccesscontrol = *resp.OriginAccessControl + + return nil + } +} + +func testAccPreCheck(t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).CloudFrontConn + ctx := context.Background() + + input := &cloudfront.ListOriginAccessControlsInput{} + _, err := conn.ListOriginAccessControlsWithContext(ctx, input) + + if acctest.PreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) + } + + if err != nil { + t.Fatalf("unexpected PreCheck error: %s", err) + } +} + +func testAccOriginAccessControlConfig_basic(rName string) string { + return fmt.Sprintf(` +resource "aws_cloudfront_origin_access_control" "test" { + name = %[1]q + origin_access_control_origin_type = "s3" + signing_behavior = "always" + signing_protocol = "sigv4" +} +`, rName) +} + +func testAccOriginAccessControlConfig_name(rName string) string { + return fmt.Sprintf(` +resource "aws_cloudfront_origin_access_control" "test" { + name = %[1]q + origin_access_control_origin_type = "s3" + signing_behavior = "always" + signing_protocol = "sigv4" +} +`, rName) +} + +func testAccOriginAccessControlConfig_description(rName, description string) string { + return fmt.Sprintf(` +resource "aws_cloudfront_origin_access_control" "test" { + name = %[1]q + description = %[2]q + origin_access_control_origin_type = "s3" + signing_behavior = "always" + signing_protocol = "sigv4" +} +`, rName, description) +} + +func testAccOriginAccessControlConfig_signingBehavior(rName, signingBehavior string) string { + return fmt.Sprintf(` +resource "aws_cloudfront_origin_access_control" "test" { + name = %[1]q + origin_access_control_origin_type = "s3" + signing_behavior = %[2]q + signing_protocol = "sigv4" +} +`, rName, signingBehavior) +} diff --git a/website/docs/r/cloudfront_origin_access_control.html.markdown b/website/docs/r/cloudfront_origin_access_control.html.markdown new file mode 100644 index 000000000000..9599f6efc226 --- /dev/null +++ b/website/docs/r/cloudfront_origin_access_control.html.markdown @@ -0,0 +1,52 @@ +--- +subcategory: "CloudFront" +layout: "aws" +page_title: "AWS: aws_cloudfront_origin_access_control" +description: |- + Terraform resource for managing an AWS CloudFront Origin Access Control. +--- + +# Resource: aws_cloudfront_origin_access_control + +Manages an AWS CloudFront Origin Access Control, which is used by CloudFront Distributions with an Amazon S3 bucket as the origin. + +Read more about Origin Access Control in the [CloudFront Developer Guide](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html). + +## Example Usage + +### Basic Usage + +```terraform +resource "aws_cloudfront_origin_access_control" "example" { + name = "example" + description = "Example Policy" + origin_access_control_origin_type = "s3" + signing_behavior = "always" + signing_protocol = "sigv4" +} +``` + +## Argument Reference + +The following arguments are required: + +* `name` - (Required) A name that identifies the Origin Access Control. +* `description` - (Required) The description of the Origin Access Control. It may be empty. +* `origin_access_control_origin_type` - (Required) The type of origin that this Origin Access Control is for. The only valid value is `s3`. +* `signing_behavior` - (Required) Specifies which requests CloudFront signs. Specify `always` for the most common use case. Allowed values: `always`, `never`, `no-override`. +* `signing_protocol` - (Required) Determines how CloudFront signs (authenticates) requests. Valid values: `sigv4`. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The unique identifier of this Origin Access Control. +* `etag` - The current version of this Origin Access Control. + +## Import + +CloudFront Origin Access Control can be imported using the `id`. For example: + +``` +$ terraform import aws_cloudfront_origin_access_control.example E327GJI25M56DG +``` From 0a973dcd34b78655f11e933a9496826804922774 Mon Sep 17 00:00:00 2001 From: Roberth Kulbin <6707630+roberth-k@users.noreply.github.com> Date: Fri, 26 Aug 2022 22:35:39 +0100 Subject: [PATCH 2/3] r/aws_cloudfront_origin_access_control: add sweeper --- internal/service/cloudfront/list.go | 17 +++++++ internal/service/cloudfront/sweep.go | 66 ++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/internal/service/cloudfront/list.go b/internal/service/cloudfront/list.go index effbd1fdfa85..49b4b117232a 100644 --- a/internal/service/cloudfront/list.go +++ b/internal/service/cloudfront/list.go @@ -108,3 +108,20 @@ func ListResponseHeadersPoliciesPages(conn *cloudfront.CloudFront, input *cloudf } return nil } + +func ListOriginAccessControlsPages(conn *cloudfront.CloudFront, input *cloudfront.ListOriginAccessControlsInput, fn func(*cloudfront.ListOriginAccessControlsOutput, bool) bool) error { + for { + output, err := conn.ListOriginAccessControls(input) + if err != nil { + return err + } + + lastPage := aws.StringValue(output.OriginAccessControlList.NextMarker) == "" + if !fn(output, lastPage) || lastPage { + break + } + + input.Marker = output.OriginAccessControlList.NextMarker + } + return nil +} diff --git a/internal/service/cloudfront/sweep.go b/internal/service/cloudfront/sweep.go index 911b061bd0fe..f20e93da730e 100644 --- a/internal/service/cloudfront/sweep.go +++ b/internal/service/cloudfront/sweep.go @@ -4,6 +4,7 @@ package cloudfront import ( + "context" "fmt" "log" @@ -58,6 +59,14 @@ func init() { F: sweepMonitoringSubscriptions, }) + resource.AddTestSweepers("aws_cloudfront_origin_access_control", &resource.Sweeper{ + Name: "aws_cloudfront_origin_access_control", + F: sweepOriginAccessControls, + Dependencies: []string{ + "aws_cloudfront_distribution", + }, + }) + resource.AddTestSweepers("aws_cloudfront_origin_request_policy", &resource.Sweeper{ Name: "aws_cloudfront_origin_request_policy", F: sweepOriginRequestPolicies, @@ -640,3 +649,60 @@ func sweepResponseHeadersPolicies(region string) error { return nil } + +func sweepOriginAccessControls(region string) error { + client, err := sweep.SharedRegionalSweepClient(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*conns.AWSClient).CloudFrontConn + input := &cloudfront.ListOriginAccessControlsInput{} + sweepResources := make([]*sweep.SweepResource, 0) + + err = ListOriginAccessControlsPages(conn, input, func(page *cloudfront.ListOriginAccessControlsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.OriginAccessControlList.Items { + id := aws.StringValue(v.Id) + + output, err := findOriginAccessControlByID(context.Background(), conn, id) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + log.Printf("[WARN] %s", err) + continue + } + + r := ResourceOriginAccessControl() + d := r.Data(nil) + d.SetId(id) + d.Set("etag", output.ETag) + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + log.Printf("[WARN] Skipping CloudFront Origin Access Control sweep for %s: %s", region, err) + return nil + } + + if err != nil { + return fmt.Errorf("error listing CloudFront Origin Access Controls (%s): %w", region, err) + } + + err = sweep.SweepOrchestrator(sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping CloudFront Origin Access Controls (%s): %w", region, err) + } + + return nil +} From 20c9526a59eade30d291d90c039f7fba1c4c687a Mon Sep 17 00:00:00 2001 From: Roberth Kulbin <6707630+roberth-k@users.noreply.github.com> Date: Sun, 28 Aug 2022 23:08:58 +0100 Subject: [PATCH 3/3] add changelog entry for #26508 --- .changelog/26508.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/26508.txt diff --git a/.changelog/26508.txt b/.changelog/26508.txt new file mode 100644 index 000000000000..1a227f010dd9 --- /dev/null +++ b/.changelog/26508.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_cloudfront_origin_access_control +```