-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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_organization #903
Changes from 7 commits
009d501
a463708
878b1c3
9288b29
54f122b
6cb09ad
7c0539e
5d70149
b36c873
12c692d
1cb414e
306de02
31f379f
153b712
37d64f5
c0a0c61
a53e483
754238e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package aws | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
) | ||
|
||
func TestAccAWSOrganizationImportBasic(t *testing.T) { | ||
resourceName := "aws_organization.test" | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSOrganizationDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSOrganizationConfig(), | ||
}, | ||
|
||
{ | ||
ResourceName: resourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -454,6 +454,7 @@ func Provider() terraform.ResourceProvider { | |
"aws_opsworks_user_profile": resourceAwsOpsworksUserProfile(), | ||
"aws_opsworks_permission": resourceAwsOpsworksPermission(), | ||
"aws_opsworks_rds_db_instance": resourceAwsOpsworksRdsDbInstance(), | ||
"aws_organization": resourceAwsOrganization(), | ||
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. Its going to look ugly at first and Naming is Hard, but we should probably also rename this
Ideally the resource function names will be updated to long form as well: 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. I think I handled all the other feedback you provided. I'm not against doing this but it seemed like more work than I was willing to put in tonight. |
||
"aws_placement_group": resourceAwsPlacementGroup(), | ||
"aws_proxy_protocol_policy": resourceAwsProxyProtocolPolicy(), | ||
"aws_rds_cluster": resourceAwsRDSCluster(), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package aws | ||
|
||
import ( | ||
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. Nitpick: can you please structure the imports as: import (
// stdlib ones
// others
) FYI many folks here are using |
||
"fmt" | ||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/awserr" | ||
"github.com/aws/aws-sdk-go/service/organizations" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
"github.com/hashicorp/terraform/helper/validation" | ||
"log" | ||
) | ||
|
||
func resourceAwsOrganization() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsOrganizationCreate, | ||
Read: resourceAwsOrganizationRead, | ||
Update: resourceAwsOrganizationUpdate, | ||
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. As written, this resource does not support updates. We should remove this line from the resource and its associated function. |
||
Delete: resourceAwsOrganizationDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"arn": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"master_account_arn": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"master_account_email": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"master_account_id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
"feature_set": { | ||
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. Please set |
||
Type: schema.TypeString, | ||
Optional: true, | ||
Default: "ALL", | ||
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. Minor nitpick: we should use the SDK constant here too: |
||
ValidateFunc: validation.StringInSlice([]string{organizations.OrganizationFeatureSetAll, organizations.OrganizationFeatureSetConsolidatedBilling}, true), | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsOrganizationCreate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).organizationsconn | ||
|
||
createOpts := &organizations.CreateOrganizationInput{ | ||
FeatureSet: aws.String(d.Get("feature_set").(string)), | ||
} | ||
log.Printf("[DEBUG] Creating Organization: %#v", createOpts) | ||
|
||
resp, err := conn.CreateOrganization(createOpts) | ||
if err != nil { | ||
return fmt.Errorf("Error creating organization: %s", err) | ||
} | ||
|
||
org := resp.Organization | ||
d.SetId(*org.Id) | ||
log.Printf("[INFO] Organization ID: %s", d.Id()) | ||
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. Can you please remove this line or set it to |
||
|
||
return resourceAwsOrganizationUpdate(d, meta) | ||
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. This should go right to calling |
||
} | ||
|
||
func resourceAwsOrganizationRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).organizationsconn | ||
|
||
log.Printf("[INFO] Reading Organization: %s", d.Id()) | ||
org, err := conn.DescribeOrganization(&organizations.DescribeOrganizationInput{}) | ||
if err != nil { | ||
if orgerr, ok := err.(awserr.Error); ok && orgerr.Code() == "AWSOrganizationsNotInUseException" { | ||
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. Minor nitpick: We can simplify this with |
||
log.Printf("[WARN] Organization does not exist, removing from state: %s", d.Id()) | ||
d.SetId("") | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
d.Set("arn", org.Organization.Arn) | ||
d.Set("feature_set", org.Organization.FeatureSet) | ||
d.Set("master_account_arn", org.Organization.MasterAccountArn) | ||
d.Set("master_account_email", org.Organization.MasterAccountEmail) | ||
d.Set("master_account_id", org.Organization.MasterAccountId) | ||
return nil | ||
} | ||
|
||
func resourceAwsOrganizationUpdate(d *schema.ResourceData, meta interface{}) error { | ||
return resourceAwsOrganizationRead(d, meta) | ||
} | ||
|
||
func resourceAwsOrganizationDelete(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).organizationsconn | ||
|
||
log.Printf("[INFO] Deleting Organization: %s", d.Id()) | ||
|
||
_, err := conn.DeleteOrganization(&organizations.DeleteOrganizationInput{}) | ||
if err != nil { | ||
return fmt.Errorf("Error deleting Organization: %s", err) | ||
} | ||
|
||
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. Nitpick: While its still around in a bunch of the codebase, this is actually not necessary on deletion 👍 |
||
|
||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/service/organizations" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccAWSOrganization_basic(t *testing.T) { | ||
var organization organizations.Organization | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSOrganizationDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSOrganizationConfig(), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSOrganizationExists("aws_organization.test", &organization), | ||
resource.TestCheckResourceAttr("aws_organization.test", "feature_set", organizations.OrganizationFeatureSetAll), | ||
resource.TestCheckResourceAttrSet("aws_organization.test", "arn"), | ||
resource.TestCheckResourceAttrSet("aws_organization.test", "master_account_arn"), | ||
resource.TestCheckResourceAttrSet("aws_organization.test", "master_account_email"), | ||
resource.TestCheckResourceAttrSet("aws_organization.test", "feature_set"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccAWSOrganization_consolidatedBilling(t *testing.T) { | ||
var organization organizations.Organization | ||
|
||
feature_set := organizations.OrganizationFeatureSetConsolidatedBilling | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckAWSOrganizationDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSOrganizationConfigConsolidatedBilling(feature_set), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSOrganizationExists("aws_organization.test", &organization), | ||
resource.TestCheckResourceAttr("aws_organization.test", "feature_set", feature_set), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckAWSOrganizationDestroy(s *terraform.State) error { | ||
conn := testAccProvider.Meta().(*AWSClient).organizationsconn | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "aws_organization" { | ||
continue | ||
} | ||
|
||
params := &organizations.DescribeOrganizationInput{} | ||
|
||
resp, err := conn.DescribeOrganization(params) | ||
|
||
if err != nil || resp == nil { | ||
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. This should be checking and returning errors: if err != nil {
if isAWSErr(err, organizations.ErrCodeAWSOrganizationsNotInUseException, "") {
return nil
}
return err
}
if resp != nil && resp.Organization != nil {
return fmt.Errorf("Organization still exists: %q", rs.Primary.ID)
} |
||
return nil | ||
} | ||
|
||
if resp.Organization != nil { | ||
return fmt.Errorf("Bad: Organization still exists: %q", rs.Primary.ID) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func testAccCheckAWSOrganizationExists(n string, a *organizations.Organization) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[n] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", n) | ||
} | ||
|
||
if rs.Primary.ID == "" { | ||
return fmt.Errorf("Organization ID not set") | ||
} | ||
|
||
conn := testAccProvider.Meta().(*AWSClient).organizationsconn | ||
params := &organizations.DescribeOrganizationInput{} | ||
|
||
resp, err := conn.DescribeOrganization(params) | ||
|
||
if err != nil || resp == nil { | ||
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. This should be returning errors: if err != nil {
return err
}
if resp == nil || resp.Organization == nil {
return fmt.Errorf("Organization %q does not exist", rs.Primary.ID)
} |
||
return nil | ||
} | ||
|
||
if resp.Organization == nil { | ||
return fmt.Errorf("Organization %q does not exist", rs.Primary.ID) | ||
} | ||
|
||
a = resp.Organization | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccAWSOrganizationConfig() string { | ||
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. Nitpick: this can just be a |
||
return fmt.Sprintf(` | ||
resource "aws_organization" "test" {} | ||
`) | ||
} | ||
|
||
func testAccAWSOrganizationConfigConsolidatedBilling(feature_set string) string { | ||
return fmt.Sprintf(` | ||
resource "aws_organization" "test" { | ||
feature_set = "%s" | ||
} | ||
`, feature_set) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
--- | ||
layout: "aws" | ||
page_title: "AWS: aws_organization | ||
sidebar_current: "docs-aws-resource-organization|" | ||
description: |- | ||
Provides a resource to create an organization. | ||
--- | ||
|
||
# aws\_organization | ||
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. Nitpick: Backslashes are no longer required for documentation titles |
||
|
||
Provides a resource to create an organization. | ||
|
||
## Example Usage: | ||
|
||
```hcl | ||
resource "aws_organization" "org" { | ||
feature_set = "ALL" | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `feature_set` - (Optional) Specify "ALL" (default) or "CONSOLIDATED_BILLING". | ||
|
||
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. Can you please add all the other attributes here? e.g.
|
||
## Import | ||
|
||
The AWS organization can be imported by using the `account_id`, e.g. | ||
|
||
``` | ||
$ terraform import aws_organization.my_org 111111111111 | ||
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. While the read function will currently work with anything here at the moment, we should be encouraging importing by the organization ID ( |
||
``` |
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 rename this to
_importBasic
please? Thanks!