From 7c59f7e282caa2ef2ecf45ad2a8db681993abdd1 Mon Sep 17 00:00:00 2001 From: Clint Date: Fri, 28 Apr 2017 16:28:49 -0500 Subject: [PATCH] provider/aws: Add EMR Security Configuration Resource (#14080) * provider/aws: Add EMR Security Configuration * provider/aws: Document EMR security configuration * small refactoring and add an import test --- ...ort_aws_emr_security_configuration_test.go | 28 ++++ builtin/providers/aws/provider.go | 1 + ...resource_aws_emr_security_configuration.go | 132 ++++++++++++++++++ ...rce_aws_emr_security_configuration_test.go | 111 +++++++++++++++ .../emr_security_configuration.html.markdown | 63 +++++++++ website/source/layouts/aws.erb | 4 + 6 files changed, 339 insertions(+) create mode 100644 builtin/providers/aws/import_aws_emr_security_configuration_test.go create mode 100644 builtin/providers/aws/resource_aws_emr_security_configuration.go create mode 100644 builtin/providers/aws/resource_aws_emr_security_configuration_test.go create mode 100644 website/source/docs/providers/aws/r/emr_security_configuration.html.markdown diff --git a/builtin/providers/aws/import_aws_emr_security_configuration_test.go b/builtin/providers/aws/import_aws_emr_security_configuration_test.go new file mode 100644 index 0000000000..72ddddf513 --- /dev/null +++ b/builtin/providers/aws/import_aws_emr_security_configuration_test.go @@ -0,0 +1,28 @@ +package aws + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccAWSEmrSecurityConfiguration_importBasic(t *testing.T) { + resourceName := "aws_emr_security_configuration.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckEmrSecurityConfigurationDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccEmrSecurityConfigurationConfig, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/builtin/providers/aws/provider.go b/builtin/providers/aws/provider.go index 6f847fb263..99240ea31c 100644 --- a/builtin/providers/aws/provider.go +++ b/builtin/providers/aws/provider.go @@ -313,6 +313,7 @@ func Provider() terraform.ResourceProvider { "aws_elb_attachment": resourceAwsElbAttachment(), "aws_emr_cluster": resourceAwsEMRCluster(), "aws_emr_instance_group": resourceAwsEMRInstanceGroup(), + "aws_emr_security_configuration": resourceAwsEMRSecurityConfiguration(), "aws_flow_log": resourceAwsFlowLog(), "aws_glacier_vault": resourceAwsGlacierVault(), "aws_iam_access_key": resourceAwsIamAccessKey(), diff --git a/builtin/providers/aws/resource_aws_emr_security_configuration.go b/builtin/providers/aws/resource_aws_emr_security_configuration.go new file mode 100644 index 0000000000..0002d5d294 --- /dev/null +++ b/builtin/providers/aws/resource_aws_emr_security_configuration.go @@ -0,0 +1,132 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/emr" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceAwsEMRSecurityConfiguration() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsEmrSecurityConfigurationCreate, + Read: resourceAwsEmrSecurityConfigurationRead, + Delete: resourceAwsEmrSecurityConfigurationDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ConflictsWith: []string{"name_prefix"}, + ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + if len(value) > 10280 { + errors = append(errors, fmt.Errorf( + "%q cannot be longer than 10280 characters", k)) + } + return + }, + }, + "name_prefix": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + if len(value) > 10000 { + errors = append(errors, fmt.Errorf( + "%q cannot be longer than 10000 characters, name is limited to 10280", k)) + } + return + }, + }, + + "configuration": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateJsonString, + }, + + "creation_date": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceAwsEmrSecurityConfigurationCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).emrconn + + var emrSCName string + if v, ok := d.GetOk("name"); ok { + emrSCName = v.(string) + } else { + if v, ok := d.GetOk("name_prefix"); ok { + emrSCName = resource.PrefixedUniqueId(v.(string)) + } else { + emrSCName = resource.PrefixedUniqueId("tf-emr-sc-") + } + } + + resp, err := conn.CreateSecurityConfiguration(&emr.CreateSecurityConfigurationInput{ + Name: aws.String(emrSCName), + SecurityConfiguration: aws.String(d.Get("configuration").(string)), + }) + + if err != nil { + return err + } + + d.SetId(*resp.Name) + return resourceAwsEmrSecurityConfigurationRead(d, meta) +} + +func resourceAwsEmrSecurityConfigurationRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).emrconn + + resp, err := conn.DescribeSecurityConfiguration(&emr.DescribeSecurityConfigurationInput{ + Name: aws.String(d.Id()), + }) + if err != nil { + if isAWSErr(err, "InvalidRequestException", "does not exist") { + log.Printf("[WARN] EMR Security Configuraiton (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + return err + } + + d.Set("creation_date", resp.CreationDateTime) + d.Set("name", resp.Name) + d.Set("configuration", resp.SecurityConfiguration) + + return nil +} + +func resourceAwsEmrSecurityConfigurationDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).emrconn + + _, err := conn.DeleteSecurityConfiguration(&emr.DeleteSecurityConfigurationInput{ + Name: aws.String(d.Id()), + }) + if err != nil { + if isAWSErr(err, "InvalidRequestException", "does not exist") { + d.SetId("") + return nil + } + return err + } + d.SetId("") + + return nil +} diff --git a/builtin/providers/aws/resource_aws_emr_security_configuration_test.go b/builtin/providers/aws/resource_aws_emr_security_configuration_test.go new file mode 100644 index 0000000000..c17fb806ff --- /dev/null +++ b/builtin/providers/aws/resource_aws_emr_security_configuration_test.go @@ -0,0 +1,111 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/emr" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAWSEmrSecurityConfiguration_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckEmrSecurityConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccEmrSecurityConfigurationConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckEmrSecurityConfigurationExists("aws_emr_security_configuration.foo"), + ), + }, + }, + }) +} + +func testAccCheckEmrSecurityConfigurationDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).emrconn + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_emr_security_configuration" { + continue + } + + // Try to find the Security Configuration + resp, err := conn.DescribeSecurityConfiguration(&emr.DescribeSecurityConfigurationInput{ + Name: aws.String(rs.Primary.ID), + }) + if err == nil { + if resp.Name != nil && *resp.Name == rs.Primary.ID { + // assume this means the resource still exists + return fmt.Errorf("Error: EMR Security Configuration still exists: %s", *resp.Name) + } + return nil + } + + // Verify the error is what we want + if err != nil { + if isAWSErr(err, "InvalidRequestException", "does not exist") { + return nil + } + return err + } + } + + return nil +} + +func testAccCheckEmrSecurityConfigurationExists(n string) 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("No EMR Security Configuration ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).emrconn + resp, err := conn.DescribeSecurityConfiguration(&emr.DescribeSecurityConfigurationInput{ + Name: aws.String(rs.Primary.ID), + }) + if err != nil { + return err + } + + if resp.Name == nil { + return fmt.Errorf("EMR Security Configuration had nil name which shouldn't happen") + } + + if *resp.Name != rs.Primary.ID { + return fmt.Errorf("EMR Security Configuration name mismatch, got (%s), expected (%s)", *resp.Name, rs.Primary.ID) + } + + return nil + } +} + +const testAccEmrSecurityConfigurationConfig = ` +resource "aws_emr_security_configuration" "foo" { + configuration = <> aws_emr_instance_group + + > + aws_emr_security_configuration +