Skip to content
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: aws_organizations_account #3524

Merged
merged 13 commits into from
Apr 6, 2018

Conversation

asedge
Copy link
Contributor

@asedge asedge commented Feb 25, 2018

A new resource to implement AWS Organizations member accounts: #571.

I updated the branch based on feedback from #903. There's probably more to fix up because this branch hadn't been touched in quite a while. This is quite a bit more difficult to test because once you create a member account in an organization that organization cannot be deleted. The member accounts themselves cannot be deleted, only suspended, and each account creation consumes an email address that cannot be reused.

Originally attempted a PR at: hashicorp/terraform#14147.

CC: @bflad

@ghost ghost added the size/L Managed by automation to categorize the size of a PR. label Feb 25, 2018
@bflad bflad added new-resource Introduces a new resource. service/organizations Issues and PRs that pertain to the organizations service. labels Feb 26, 2018
Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @asedge, thanks so much again! You rock. I left some initial feedback below. Same as before, if you do not have time to complete this or have any questions, please let me know! 👍

I think the biggest changes to this PR are reworking the deletion to call RemoveAccountFromOrganization and removing the import specific test (since its very likely we'll have lots of trouble acceptance testing this with AWS limits).


var err error
var resp *organizations.CreateAccountOutput
err = resource.Retry(4*time.Minute, func() *resource.RetryError {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, how was 4 minutes decided here?

Copy link
Contributor Author

@asedge asedge Feb 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't remember 100% because this code is nearly a year old. After looking at it for a little bit I think the issue was that there's no API action to check the status of CreateOrganization. I didn't realize this could be a problem until I wrote this resource, because I was creating an organization and immediately adding an account, so I put the poll here. Allowing organizations.ErrCodeFinalizingOrganizationException as a RetryableError seems to back that up.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome information! If that's the case, maybe we (more like I 😄 ) should setup the organization resource to wait until the organization is finalized before returning that its done on creation. I'll make a note to check that myself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you create an issue and assign it to me, I will get it done.

resp, err = conn.CreateAccount(createOpts)

if err != nil {
ec2err, ok := err.(awserr.Error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can drop this and just work with err below in the isAWSErr and log.Printf calls

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may have been a mistake to leave in.


if err != nil {
ec2err, ok := err.(awserr.Error)
if !ok {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please remove this? I don't think this is valid here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may have been a mistake from when I was trying to clean up.

Config: testAccAwsOrganizationsAccountConfig(name, email),
},

{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to the likely issues we'll have with account number limits, can you please remove this explicit separate test and instead move this test step to the end of the _basic test? Thanks!

t.Skip("'TEST_AWS_ORGANIZATION_ACCOUNT_EMAIL' not set, skipping test.")
}

name := "my_new_account"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to randomize this, which means maybe we'll want to accept just the email domain as an environment variable as well. e.g.

rInt := acctest.RandInt()
name := fmt.Sprintf("tf_acctest_%s", rInt)
email := fmt.Sprintf("tf-acctest+%d@%s", rInt, orgsEmailDomain)

For starters though, let's at least get the rInt bits in for now as we'll already need to do some other special changes to support repeatable acceptance testing.

website/aws.erb Outdated
@@ -1377,6 +1377,9 @@
<li<%= sidebar_current("docs-aws-resource-organizations-organization") %>>
<a href="/docs/providers/aws/r/organizations_organization.html">aws_organizations_organization</a>
</li>
<li<%= sidebar_current("docs-aws-resource-organizations-account") %>>
<a href="/docs/providers/aws/r/organizations_account.html">aws_organizations_account</a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nitpick: Can you sort this alphabetically please?

Provides a resource to create a member account in the current AWS Organization.
---

# aws\_organizations\_account
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nitpick: Backslashes are no longer required in documentation titles


-> **Note:** Account creation must be done from the organization's master account.

-> **Note:** AWS member accounts must be deleted manually by following these steps: 1) Perform a root account password recovery for the email address that was specified for the account in Organizations. 2) Login to the account as that root user. 3) Navigate to "My Organization" in the account menu top-right. 4) Leave the organization. 5) Once the account has successfully left the organization, delete the account as usual.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should link to the AWS Organizations documentation for this information, e.g.

~> **Note:** Deleting this Terraform resource will only remove an AWS account from an organization. Terraform will not close the account. The member account must be prepared to be a standalone account beforehand. See the [AWS Organizations documentation](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_accounts_remove.html) for more information.


# aws\_organizations\_account

-> **Note:** Account creation must be done from the organization's master account.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should imply this for all account management, e.g.

~> **Note:** Account management must be done from the organization's master account.

return nil
}

func resourceAwsOrganizationsAccountDelete(d *schema.ResourceData, meta interface{}) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to how the AWS Organizations service and closing AWS accounts in general works, we should probably set up the Terraform deletion function here to call RemoveAccountFromOrganization and pass along the error to the Terraform user. I put a review comment to update the documentation appropriately as well. e.g.

func resourceAwsOrganizationsAccountDelete(d *schema.ResourceData, meta interface{}) error {
  conn := meta.(*AWSClient).organizationsconn

  input := &organizations.RemoveAccountFromOrganizationInput{
    AccountId: aws.String(d.Id()),
  }
  log.Printf("[DEBUG] Removing AWS account from organization: %s", input)
  _, err := conn.RemoveAccountFromOrganization(input)
  if err != nil {
    if isAWSErr(err, organizations.ErrCodeAccountNotFoundException, "") {
      return nil
    }
    return err
  }
  return nil
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I can do that. In fact, since you wrote the code feel free to update the PR. Let me know either way, thanks.

@ghost ghost added the size/L Managed by automation to categorize the size of a PR. label Mar 2, 2018
@asedge
Copy link
Contributor Author

asedge commented Mar 2, 2018

@bflad I took care of nearly all the feedback you provided. I provided a response about the 4 minute retry timeout but haven't made any changes on it just yet.

@bflad
Copy link
Contributor

bflad commented Mar 2, 2018

@asedge thank you so much again for your work here! You've really gone above and beyond here. 😄

At this point, I need to temporarily put this PR on hold while I work with AWS support on how we can regularly acceptance test this in a designated AWS account. No clue what their response will be like yet 😂.

If people are feeling brave, maybe they could try this out themselves in a custom build? terraform state rm is always an option to back out the account management with Terraform. At the current time, I don't think there will be much in the line of "breaking changes" to the resource (e.g. attribute changes), but I cannot make a 100% promise yet until I get more details from AWS.

@bflad bflad self-assigned this Mar 2, 2018
@bflad bflad added the upstream Addresses functionality related to the cloud provider. label Mar 2, 2018
@lorengordon
Copy link
Contributor

I might be able to play with this. Would be awesome to be able to manage accounts as resources (and data sources) through Terraform. Would someone be able to create a Windows binary from this branch?

@jeffnappi
Copy link
Contributor

Thanks for the hard work on this, looking forward to seeing it released!

@ghost ghost added the size/L Managed by automation to categorize the size of a PR. label Apr 6, 2018
@bflad bflad added this to the v1.14.0 milestone Apr 6, 2018
Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bringing this in after I changed three things:

  • Add d.Set("email", resp.Account.Email) to fix import
  • Prevent crash if resp.Account is nil for some reason
  • Upgraded the deletion message in the docs to a nice red WARNING

Verified manually using my personal AWS accounts 😉 .

aws_organizations_account.bflad-dev2: Creating...
  arn:              "" => "<computed>"
  email:            "" => "--OMITTED--"
  joined_method:    "" => "<computed>"
  joined_timestamp: "" => "<computed>"
  name:             "" => "bflad-dev2"
  status:           "" => "<computed>"
aws_organizations_account.bflad-dev2: Still creating... (10s elapsed)
aws_organizations_account.bflad-dev2: Creation complete after 11s (ID: --OMITTED--)
# Complete all the "sign up steps" required to make account standalone
aws_organizations_account.bflad-dev2: Destroying... (ID: --OMITTED--)
aws_organizations_account.bflad-dev2: Destruction complete after 4s
# Able to invite back and accept invite in AWS Console, then reimport into Terraform

@bflad bflad merged commit 4ae5dc1 into hashicorp:master Apr 6, 2018
bflad added a commit that referenced this pull request Apr 6, 2018
@asedge
Copy link
Contributor Author

asedge commented Apr 6, 2018

@bflad Thanks for the review and merge!

@bflad
Copy link
Contributor

bflad commented Apr 6, 2018

This has been released in version 1.14.0 of the AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

@asedge asedge deleted the resource_aws_organizations_account branch April 10, 2018 16:38
@Flowman
Copy link

Flowman commented Apr 11, 2018

Can we extend this with add account to specific OU?

@ghost
Copy link

ghost commented Apr 6, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@ghost ghost locked and limited conversation to collaborators Apr 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
new-resource Introduces a new resource. service/organizations Issues and PRs that pertain to the organizations service. size/L Managed by automation to categorize the size of a PR. upstream Addresses functionality related to the cloud provider.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants