Skip to content

Commit

Permalink
feat: add option for closing accounts on delete
Browse files Browse the repository at this point in the history
AWS Organizations has added an API for closing accounts, which allows us
to fully manage the account lifecycle in Terraform now.

Refs: SHUTTLE-672
  • Loading branch information
heiko.rothe authored and mKeRix committed Apr 8, 2022
1 parent 76f517f commit 75a75b5
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/resources/aws_account.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ resource "controltower_aws_account" "account" {

### Optional

- `close_account_on_delete` (Boolean) If enabled, this will close the AWS account on resource deletion, beginning the 90-day suspension period. Otherwise, the account will just be unenrolled from Control Tower.
- `id` (String) The ID of this resource.
- `organizational_unit_on_delete` (String) Name of the Organizational Unit to which the account should be moved when the resource is deleted. If no value is provided, the account will not be moved.
- `path_id` (String) Name of the path identifier of the product. This value is optional if the product has a default path, and required if the product has more than one path. To list the paths for a product, use ListLaunchPaths.
Expand Down
28 changes: 25 additions & 3 deletions internal/provider/resource_aws_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ func resourceAWSAccount() *schema.Resource {
Type: schema.TypeString,
Optional: true,
},
"close_account_on_delete": {
Description: "If enabled, this will close the AWS account on resource deletion, beginning the 90-day suspension period. Otherwise, the account will just be unenrolled from Control Tower.",
Type: schema.TypeBool,
Optional: true,
Default: false,
},
"account_id": {
Description: "ID of the AWS account.",
Type: schema.TypeString,
Expand Down Expand Up @@ -317,7 +323,7 @@ func resourceAWSAccountUpdate(ctx context.Context, d *schema.ResourceData, m int
scconn := m.(*AWSClient).scconn
organizationsconn := m.(*AWSClient).organizationsconn

if d.HasChangesExcept("tags", "organizational_unit_on_delete") {
if d.HasChangesExcept("tags", "organizational_unit_on_delete", "close_account_on_delete") {
productId, artifactId, err := findServiceCatalogAccountProductId(scconn)
if err != nil {
return diag.FromErr(err)
Expand Down Expand Up @@ -396,14 +402,16 @@ func resourceAWSAccountUpdate(ctx context.Context, d *schema.ResourceData, m int

func resourceAWSAccountDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
scconn := m.(*AWSClient).scconn
organizationsconn := m.(*AWSClient).organizationsconn

// Get the name from the config.
name := d.Get("name").(string)

accountMutex.Lock()
defer accountMutex.Unlock()

if ou, ok := d.GetOk("organizational_unit_on_delete"); ok {
accountId, accountExists := d.GetOk("acccount_id")
if ou, ok := d.GetOk("organizational_unit_on_delete"); ok && accountExists {
productId, artifactId, err := findServiceCatalogAccountProductId(scconn)
if err != nil {
return diag.FromErr(err)
Expand Down Expand Up @@ -466,7 +474,21 @@ func resourceAWSAccountDelete(_ context.Context, d *schema.ResourceData, m inter

// Wait for the provisioning to finish.
_, diags := waitForProvisioning(name, account.RecordDetail.RecordId, m)
return diags
if diags.HasError() {
return diags
}

closeAccount := d.Get("close_account_on_delete").(bool)
if closeAccount && accountExists {
_, err := organizationsconn.CloseAccount(&organizations.CloseAccountInput{
AccountId: aws.String(accountId.(string)),
})
if err != nil {
return diag.Errorf("error closing account %s: %v", accountId, err)
}
}

return nil
}

// waitForProvisioning waits until the provisioning finished.
Expand Down

0 comments on commit 75a75b5

Please sign in to comment.