diff --git a/builtin/providers/aws/resource_aws_elb.go b/builtin/providers/aws/resource_aws_elb.go index b54dac60f..4601d83b5 100644 --- a/builtin/providers/aws/resource_aws_elb.go +++ b/builtin/providers/aws/resource_aws_elb.go @@ -425,9 +425,15 @@ func resourceAwsElbUpdate(d *schema.ResourceData, meta interface{}) error { err := resource.Retry(1*time.Minute, func() error { log.Printf("[DEBUG] ELB Create Listeners opts: %s", createListenersOpts) if _, err := elbconn.CreateLoadBalancerListeners(createListenersOpts); err != nil { - if awserr, ok := err.(awserr.Error); ok && awserr.Code() == "DuplicateListener" { - log.Printf("[DEBUG] Duplicate listener found for ELB (%s), retrying", d.Id()) - return awserr + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "DuplicateListener" { + log.Printf("[DEBUG] Duplicate listener found for ELB (%s), retrying", d.Id()) + return awsErr + } + if awsErr.Code() == "CertificateNotFound" && strings.Contains(awsErr.Message(), "Server Certificate not found for the key: arn") { + log.Printf("[DEBUG] SSL Cert not found for given ARN, retrying") + return awsErr + } } // Didn't recognize the error, so shouldn't retry. diff --git a/builtin/providers/aws/resource_aws_iam_server_certificate.go b/builtin/providers/aws/resource_aws_iam_server_certificate.go index 69f4d18a5..c747df619 100644 --- a/builtin/providers/aws/resource_aws_iam_server_certificate.go +++ b/builtin/providers/aws/resource_aws_iam_server_certificate.go @@ -51,9 +51,33 @@ func resourceAwsIAMServerCertificate() *schema.Resource { }, "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) > 128 { + errors = append(errors, fmt.Errorf( + "%q cannot be longer than 128 characters", k)) + } + return + }, + }, + + "name_prefix": &schema.Schema{ Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, + ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { + value := v.(string) + if len(value) > 30 { + errors = append(errors, fmt.Errorf( + "%q cannot be longer than 30 characters, name is limited to 128", k)) + } + return + }, }, "arn": &schema.Schema{ @@ -68,10 +92,19 @@ func resourceAwsIAMServerCertificate() *schema.Resource { func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn + var sslCertName string + if v, ok := d.GetOk("name"); ok { + sslCertName = v.(string) + } else if v, ok := d.GetOk("name_prefix"); ok { + sslCertName = resource.PrefixedUniqueId(v.(string)) + } else { + sslCertName = resource.UniqueId() + } + createOpts := &iam.UploadServerCertificateInput{ CertificateBody: aws.String(d.Get("certificate_body").(string)), PrivateKey: aws.String(d.Get("private_key").(string)), - ServerCertificateName: aws.String(d.Get("name").(string)), + ServerCertificateName: aws.String(sslCertName), } if v, ok := d.GetOk("certificate_chain"); ok { @@ -92,6 +125,7 @@ func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interfac } d.SetId(*resp.ServerCertificateMetadata.ServerCertificateId) + d.Set("name", sslCertName) return resourceAwsIAMServerCertificateRead(d, meta) } @@ -135,7 +169,8 @@ func resourceAwsIAMServerCertificateDelete(d *schema.ResourceData, meta interfac if err != nil { if awsErr, ok := err.(awserr.Error); ok { if awsErr.Code() == "DeleteConflict" && strings.Contains(awsErr.Message(), "currently in use by arn") { - return fmt.Errorf("[WARN] Conflict deleting server certificate: %s, retrying", awsErr.Message()) + log.Printf("[WARN] Conflict deleting server certificate: %s, retrying", awsErr.Message()) + return err } } return resource.RetryError{Err: err} diff --git a/builtin/providers/aws/resource_aws_iam_server_certificate_test.go b/builtin/providers/aws/resource_aws_iam_server_certificate_test.go index 5982a8b6c..11780ded7 100644 --- a/builtin/providers/aws/resource_aws_iam_server_certificate_test.go +++ b/builtin/providers/aws/resource_aws_iam_server_certificate_test.go @@ -32,6 +32,25 @@ func TestAccAWSIAMServerCertificate_basic(t *testing.T) { }) } +func TestAccAWSIAMServerCertificate_name_prefix(t *testing.T) { + var cert iam.ServerCertificate + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIAMServerCertificateDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccIAMServerCertConfig_random, + Check: resource.ComposeTestCheckFunc( + testAccCheckCertExists("aws_iam_server_certificate.test_cert", &cert), + testAccCheckAWSServerCertAttributes(&cert), + ), + }, + }, + }) +} + func testAccCheckCertExists(n string, cert *iam.ServerCertificate) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -60,7 +79,7 @@ func testAccCheckCertExists(n string, cert *iam.ServerCertificate) resource.Test func testAccCheckAWSServerCertAttributes(cert *iam.ServerCertificate) resource.TestCheckFunc { return func(s *terraform.State) error { - if !strings.HasPrefix(*cert.ServerCertificateMetadata.ServerCertificateName, "terraform-test-cert") { + if !strings.Contains(*cert.ServerCertificateMetadata.ServerCertificateName, "terraform-test-cert") { return fmt.Errorf("Bad Server Cert Name: %s", *cert.ServerCertificateMetadata.ServerCertificateName) } @@ -189,3 +208,75 @@ O57Z0RUNQ8DRyymhLd2t5nAHTfpcFA1sBeKE6CziLbZB EOF } `, rand.New(rand.NewSource(time.Now().UnixNano())).Int()) + +var testAccIAMServerCertConfig_random = ` +resource "aws_iam_server_certificate" "test_cert" { + name_prefix = "terraform-test-cert" + certificate_body = <