-
Notifications
You must be signed in to change notification settings - Fork 9.2k
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
New Resource: aws_organizations_account #3524
Conversation
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.
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 { |
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.
Out of curiosity, how was 4 minutes decided here?
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.
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.
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.
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.
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.
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) |
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.
We can drop this and just work with err
below in the isAWSErr
and log.Printf
calls
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.
This may have been a mistake to leave in.
|
||
if err != nil { | ||
ec2err, ok := err.(awserr.Error) | ||
if !ok { |
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.
Can you please remove this? I don't think this is valid here
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.
This may have been a mistake from when I was trying to clean up.
Config: testAccAwsOrganizationsAccountConfig(name, email), | ||
}, | ||
|
||
{ |
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.
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" |
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.
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> |
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.
Minor nitpick: Can you sort this alphabetically please?
Provides a resource to create a member account in the current AWS Organization. | ||
--- | ||
|
||
# aws\_organizations\_account |
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.
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. |
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.
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. |
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.
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 { |
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.
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
}
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.
OK, I can do that. In fact, since you wrote the code feel free to update the PR. Let me know either way, thanks.
…esource will be challenging.
…ions documentation rather than spell it out.
… accidentally left in the old awserr check.
…user rather than issuing a pointless warning.
@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. |
@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? |
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? |
Thanks for the hard work on this, looking forward to seeing it released! |
…event crash from empty account result
… warning and other minor formatting fixes
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.
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 Thanks for the review and merge! |
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. |
Can we extend this with add account to specific OU? |
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! |
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