-
Notifications
You must be signed in to change notification settings - Fork 9k
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
New Resource: r/aws_fms_admin_account #4310
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/fms" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsFmsAdminAccount() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsFmsAdminAccountPut, | ||
Read: resourceAwsFmsAdminAccountRead, | ||
Delete: resourceAwsFmsAdminAccountDelete, | ||
|
||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Timeouts: &schema.ResourceTimeout{ | ||
Create: schema.DefaultTimeout(1 * time.Minute), | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"account_id": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
ForceNew: true, | ||
ValidateFunc: validateAwsAccountId, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsFmsAdminAccountPut(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).fmsconn | ||
|
||
accountId := meta.(*AWSClient).accountid | ||
if v, ok := d.GetOk("account_id"); ok && v != "" { | ||
accountId = v.(string) | ||
} | ||
|
||
stateConf := &resource.StateChangeConf{ | ||
Target: []string{accountId}, | ||
Refresh: associateAdminAccountRefreshFunc(conn, accountId), | ||
Timeout: d.Timeout(schema.TimeoutCreate), | ||
Delay: 10 * time.Second, | ||
MinTimeout: 3 * time.Second, | ||
} | ||
|
||
log.Printf("[DEBUG] Waiting for firewall manager admin account association: %v", accountId) | ||
_, sterr := stateConf.WaitForState() | ||
if sterr != nil { | ||
return fmt.Errorf("Error waiting for firewall manager admin account association (%s): %s", accountId, sterr) | ||
} | ||
|
||
d.SetId(accountId) | ||
return nil | ||
} | ||
|
||
func associateAdminAccountRefreshFunc(conn *fms.FMS, accountId string) resource.StateRefreshFunc { | ||
// This is all wrapped in a refresh func since AssociateAdminAccount returns | ||
// success even though it failed if called too quickly after creating an organization | ||
return func() (interface{}, string, error) { | ||
req := &fms.AssociateAdminAccountInput{ | ||
AdminAccount: aws.String(accountId), | ||
} | ||
|
||
_, aserr := conn.AssociateAdminAccount(req) | ||
if aserr != nil { | ||
return nil, "", aserr | ||
} | ||
|
||
res, err := conn.GetAdminAccount(&fms.GetAdminAccountInput{}) | ||
if err != nil { | ||
// FMS returns an AccessDeniedException if no account is associated, | ||
// but does not define this in its error codes | ||
if isAWSErr(err, "AccessDeniedException", "is not currently delegated by AWS FM") { | ||
return nil, "", nil | ||
} | ||
return nil, "", err | ||
} | ||
return *res, *res.AdminAccount, err | ||
} | ||
} | ||
|
||
func resourceAwsFmsAdminAccountRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).fmsconn | ||
|
||
res, err := conn.GetAdminAccount(&fms.GetAdminAccountInput{}) | ||
if err != nil { | ||
// FMS returns an AccessDeniedException if no account is associated, | ||
// but does not define this in its error codes | ||
if isAWSErr(err, "AccessDeniedException", "is not currently delegated by AWS FM") { | ||
log.Printf("[WARN] No associated firewall manager admin account found, removing from state: %s", d.Id()) | ||
d.SetId("") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We no longer need |
||
return nil | ||
} | ||
return err | ||
} | ||
|
||
if d.Id() != aws.StringValue(res.AdminAccount) { | ||
log.Printf("[WARN] FMS Admin Account does not match, removing from state: %s", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
d.Set("account_id", res.AdminAccount) | ||
return nil | ||
} | ||
|
||
func resourceAwsFmsAdminAccountDelete(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).fmsconn | ||
|
||
_, err := conn.DisassociateAdminAccount(&fms.DisassociateAdminAccountInput{}) | ||
if err != nil { | ||
// FMS returns an AccessDeniedException if no account is associated, | ||
// but does not define this in its error codes | ||
if isAWSErr(err, "AccessDeniedException", "is not currently delegated by AWS FM") { | ||
log.Printf("[WARN] No associated firewall manager admin account found, removing from state: %s", d.Id()) | ||
return nil | ||
} | ||
return fmt.Errorf("Error disassociating firewall manager admin account: %s", err) | ||
} | ||
|
||
return nil | ||
} |
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,108 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"regexp" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/service/fms" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func init() { | ||
resource.AddTestSweepers("aws_fms_admin_account", &resource.Sweeper{ | ||
Name: "aws_fms_admin_account", | ||
F: testSweepFmsAdminAccount, | ||
}) | ||
} | ||
|
||
func testSweepFmsAdminAccount(region string) error { | ||
client, err := sharedClientForRegion(region) | ||
if err != nil { | ||
return fmt.Errorf("Error getting client: %s", err) | ||
} | ||
conn := client.(*AWSClient).fmsconn | ||
|
||
_, err = conn.GetAdminAccount(&fms.GetAdminAccountInput{}) | ||
if err != nil { | ||
// FMS returns an AccessDeniedException if no account is associated, | ||
// but does not define this in its error codes | ||
if isAWSErr(err, "AccessDeniedException", "is not currently delegated by AWS FM") { | ||
log.Print("[DEBUG] No associated firewall manager admin account to sweep") | ||
return nil | ||
} | ||
return fmt.Errorf("Error retrieving firewall manager admin account: %s", err) | ||
} | ||
|
||
_, err = conn.DisassociateAdminAccount(&fms.DisassociateAdminAccountInput{}) | ||
if err != nil { | ||
// FMS returns an AccessDeniedException if no account is associated, | ||
// but does not define this in its error codes | ||
if isAWSErr(err, "AccessDeniedException", "is not currently delegated by AWS FM") { | ||
log.Print("[DEBUG] No associated firewall manager admin account to sweep") | ||
return nil | ||
} | ||
return fmt.Errorf("Error disassociating firewall manager admin account: %s", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func TestAccFmsAdminAccount_basic(t *testing.T) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckFmsAdminAccountDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccFmsAdminAccountConfig_basic, | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestMatchResourceAttr("aws_fms_admin_account.example", "account_id", regexp.MustCompile("^\\d{12}$")), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckFmsAdminAccountDestroy(s *terraform.State) error { | ||
conn := testAccProvider.Meta().(*AWSClient).fmsconn | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "aws_fms_admin_account" { | ||
continue | ||
} | ||
|
||
res, err := conn.GetAdminAccount(&fms.GetAdminAccountInput{}) | ||
if err != nil { | ||
// FMS returns an AccessDeniedException if no account is associated, | ||
// but does not define this in its error codes | ||
if isAWSErr(err, "AccessDeniedException", "is not currently delegated by AWS FM") { | ||
log.Print("[DEBUG] No associated firewall manager admin account") | ||
return nil | ||
} | ||
} | ||
|
||
return fmt.Errorf("Firewall manager admin account still exists: %v", res.AdminAccount) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
const testAccFmsAdminAccountConfig_basic = ` | ||
provider "aws" { | ||
region = "us-east-1" | ||
} | ||
|
||
resource "aws_fms_admin_account" "example" { | ||
depends_on = ["aws_organizations_organization.example"] | ||
account_id = "${data.aws_caller_identity.current.account_id}" # Required | ||
} | ||
|
||
resource "aws_organizations_organization" "example" { | ||
feature_set = "ALL" | ||
} | ||
|
||
data "aws_caller_identity" "current" {} | ||
` |
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,33 @@ | ||
--- | ||
layout: "aws" | ||
page_title: "AWS: aws_fms_admin_account" | ||
sidebar_current: "docs-aws-fms-admin-account" | ||
description: |- | ||
Provides a resource to associate/disassociate an AWS Firewall Manager administrator account | ||
--- | ||
|
||
# aws_fms_admin_account | ||
|
||
-> **Note:** There is only a single Firewall Manager administator account allowed per AWS account. Any existing administrator account will be lost when using this resource as an effect of this limitation. | ||
|
||
Provides a resource to associate/disassociate an AWS Firewall Manager administrator account. | ||
|
||
```hcl | ||
resource "aws_fms_admin_account" "example" { | ||
account_id = "123456789012" # Required | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `account_id` - (Required) The AWS account ID to associate with AWS Firewall Manager as the AWS Firewall Manager administrator account. This can be an AWS Organizations master account or a member account. | ||
|
||
## Import | ||
|
||
Firewall Manager administrator account association can be imported using the account ID, e.g. | ||
|
||
``` | ||
$ terraform import aws_fms_admin_account.example 123456789012 | ||
``` |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing
## Import
documentation section