-
Notifications
You must be signed in to change notification settings - Fork 9.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New Resource: aws_s3_account_public_access_block
This implements Public Access Block configuration within the new S3 Control API, which is separate from the existing S3 API. The S3 Control API features the same eventual consistency complexity as the existing S3 API across all operations. The resource and acceptance testing try handling the eventual consistency as best as possible up to a minute. The resource is named `aws_s3_account_public_access_block` instead of `aws_s3control_public_access_block` to be more operator friendly with respect to it working at the account level. Changes: * provider: Implement S3 Control custom endpoint, session, and connection * New Resource: aws_s3_account_public_access_block Output from acceptance testing: ``` --- PASS: TestAccAWSS3Account (169.55s) --- PASS: TestAccAWSS3Account/PublicAccessBlock (169.55s) --- PASS: TestAccAWSS3Account/PublicAccessBlock/basic (13.01s) --- PASS: TestAccAWSS3Account/PublicAccessBlock/disappears (7.95s) --- PASS: TestAccAWSS3Account/PublicAccessBlock/AccountId (11.47s) --- PASS: TestAccAWSS3Account/PublicAccessBlock/BlockPublicAcls (25.04s) --- PASS: TestAccAWSS3Account/PublicAccessBlock/BlockPublicPolicy (25.33s) --- PASS: TestAccAWSS3Account/PublicAccessBlock/IgnorePublicAcls (25.33s) --- PASS: TestAccAWSS3Account/PublicAccessBlock/RestrictPublicBuckets (26.40s) ```
- Loading branch information
Showing
7 changed files
with
699 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/s3control" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsS3AccountPublicAccessBlock() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsS3AccountPublicAccessBlockCreate, | ||
Read: resourceAwsS3AccountPublicAccessBlockRead, | ||
Update: resourceAwsS3AccountPublicAccessBlockUpdate, | ||
Delete: resourceAwsS3AccountPublicAccessBlockDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"account_id": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: true, | ||
ForceNew: true, | ||
ValidateFunc: validateAwsAccountId, | ||
}, | ||
"block_public_acls": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Default: false, | ||
}, | ||
"block_public_policy": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Default: false, | ||
}, | ||
"ignore_public_acls": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Default: false, | ||
}, | ||
"restrict_public_buckets": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Default: false, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsS3AccountPublicAccessBlockCreate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).s3controlconn | ||
|
||
accountID := meta.(*AWSClient).accountid | ||
if v, ok := d.GetOk("account_id"); ok { | ||
accountID = v.(string) | ||
} | ||
|
||
input := &s3control.PutPublicAccessBlockInput{ | ||
AccountId: aws.String(accountID), | ||
PublicAccessBlockConfiguration: &s3control.PublicAccessBlockConfiguration{ | ||
BlockPublicAcls: aws.Bool(d.Get("block_public_acls").(bool)), | ||
BlockPublicPolicy: aws.Bool(d.Get("block_public_policy").(bool)), | ||
IgnorePublicAcls: aws.Bool(d.Get("ignore_public_acls").(bool)), | ||
RestrictPublicBuckets: aws.Bool(d.Get("restrict_public_buckets").(bool)), | ||
}, | ||
} | ||
|
||
log.Printf("[DEBUG] Creating S3 Account Public Access Block: %s", input) | ||
_, err := conn.PutPublicAccessBlock(input) | ||
if err != nil { | ||
return fmt.Errorf("error creating S3 Account Public Access Block: %s", err) | ||
} | ||
|
||
d.SetId(accountID) | ||
|
||
return resourceAwsS3AccountPublicAccessBlockRead(d, meta) | ||
} | ||
|
||
func resourceAwsS3AccountPublicAccessBlockRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).s3controlconn | ||
|
||
input := &s3control.GetPublicAccessBlockInput{ | ||
AccountId: aws.String(d.Id()), | ||
} | ||
|
||
// Retry for eventual consistency on creation | ||
var output *s3control.GetPublicAccessBlockOutput | ||
err := resource.Retry(1*time.Minute, func() *resource.RetryError { | ||
var err error | ||
output, err = conn.GetPublicAccessBlock(input) | ||
|
||
if d.IsNewResource() && isAWSErr(err, s3control.ErrCodeNoSuchPublicAccessBlockConfiguration, "") { | ||
return resource.RetryableError(err) | ||
} | ||
|
||
if err != nil { | ||
return resource.NonRetryableError(err) | ||
} | ||
|
||
return nil | ||
}) | ||
|
||
if isAWSErr(err, s3control.ErrCodeNoSuchPublicAccessBlockConfiguration, "") { | ||
log.Printf("[WARN] S3 Account Public Access Block (%s) not found, removing from state", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("error reading S3 Account Public Access Block: %s", err) | ||
} | ||
|
||
if output == nil || output.PublicAccessBlockConfiguration == nil { | ||
return fmt.Errorf("error reading S3 Account Public Access Block (%s): missing public access block configuration", d.Id()) | ||
} | ||
|
||
d.Set("account_id", d.Id()) | ||
d.Set("block_public_acls", output.PublicAccessBlockConfiguration.BlockPublicAcls) | ||
d.Set("block_public_policy", output.PublicAccessBlockConfiguration.BlockPublicPolicy) | ||
d.Set("ignore_public_acls", output.PublicAccessBlockConfiguration.IgnorePublicAcls) | ||
d.Set("restrict_public_buckets", output.PublicAccessBlockConfiguration.RestrictPublicBuckets) | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsS3AccountPublicAccessBlockUpdate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).s3controlconn | ||
|
||
input := &s3control.PutPublicAccessBlockInput{ | ||
AccountId: aws.String(d.Id()), | ||
PublicAccessBlockConfiguration: &s3control.PublicAccessBlockConfiguration{ | ||
BlockPublicAcls: aws.Bool(d.Get("block_public_acls").(bool)), | ||
BlockPublicPolicy: aws.Bool(d.Get("block_public_policy").(bool)), | ||
IgnorePublicAcls: aws.Bool(d.Get("ignore_public_acls").(bool)), | ||
RestrictPublicBuckets: aws.Bool(d.Get("restrict_public_buckets").(bool)), | ||
}, | ||
} | ||
|
||
log.Printf("[DEBUG] Updating S3 Account Public Access Block: %s", input) | ||
_, err := conn.PutPublicAccessBlock(input) | ||
if err != nil { | ||
return fmt.Errorf("error updating S3 Account Public Access Block (%s): %s", d.Id(), err) | ||
} | ||
|
||
// Workaround API eventual consistency issues. This type of logic should not normally be used. | ||
// We cannot reliably determine when the Read after Update might be properly updated. | ||
// Rather than introduce complicated retry logic, we presume that a lack of an update error | ||
// means our update succeeded with our expected values. | ||
d.Set("block_public_acls", input.PublicAccessBlockConfiguration.BlockPublicAcls) | ||
d.Set("block_public_policy", input.PublicAccessBlockConfiguration.BlockPublicPolicy) | ||
d.Set("ignore_public_acls", input.PublicAccessBlockConfiguration.IgnorePublicAcls) | ||
d.Set("restrict_public_buckets", input.PublicAccessBlockConfiguration.RestrictPublicBuckets) | ||
|
||
// Skip normal Read after Update due to eventual consistency issues | ||
return nil | ||
} | ||
|
||
func resourceAwsS3AccountPublicAccessBlockDelete(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).s3controlconn | ||
|
||
input := &s3control.DeletePublicAccessBlockInput{ | ||
AccountId: aws.String(d.Id()), | ||
} | ||
|
||
_, err := conn.DeletePublicAccessBlock(input) | ||
|
||
if isAWSErr(err, s3control.ErrCodeNoSuchPublicAccessBlockConfiguration, "") { | ||
return nil | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("error deleting S3 Account Public Access Block (%s): %s", d.Id(), err) | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.