From f7fcee4b373a55cb5a74d7e32dd418ab691865e4 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Sat, 6 Mar 2021 09:52:09 +0200 Subject: [PATCH 1/8] server cert tags --- aws/internal/keyvaluetags/iam_tags.go | 35 ++++ aws/resource_aws_iam_server_certificate.go | 51 +++++- ...esource_aws_iam_server_certificate_test.go | 169 ++++++++++++------ .../r/iam_server_certificate.html.markdown | 1 + 4 files changed, 190 insertions(+), 66 deletions(-) diff --git a/aws/internal/keyvaluetags/iam_tags.go b/aws/internal/keyvaluetags/iam_tags.go index 1059708d280..ab6f08833cc 100644 --- a/aws/internal/keyvaluetags/iam_tags.go +++ b/aws/internal/keyvaluetags/iam_tags.go @@ -80,3 +80,38 @@ func IamUserUpdateTags(conn *iam.IAM, identifier string, oldTagsMap interface{}, return nil } + +// IamServerCertificateUpdateTags updates IAM Server Certificate tags. +// The identifier is the Server Certificate name. +func IamServerCertificateUpdateTags(conn *iam.IAM, identifier string, oldTagsMap interface{}, newTagsMap interface{}) error { + oldTags := New(oldTagsMap) + newTags := New(newTagsMap) + + if removedTags := oldTags.Removed(newTags); len(removedTags) > 0 { + input := &iam.UntagServerCertificateInput{ + ServerCertificateName: aws.String(identifier), + TagKeys: aws.StringSlice(removedTags.Keys()), + } + + _, err := conn.UntagServerCertificate(input) + + if err != nil { + return fmt.Errorf("error untagging resource (%s): %w", identifier, err) + } + } + + if updatedTags := oldTags.Updated(newTags); len(updatedTags) > 0 { + input := &iam.TagServerCertificateInput{ + ServerCertificateName: aws.String(identifier), + Tags: updatedTags.IgnoreAws().IamTags(), + } + + _, err := conn.TagServerCertificate(input) + + if err != nil { + return fmt.Errorf("error tagging resource (%s): %w", identifier, err) + } + } + + return nil +} diff --git a/aws/resource_aws_iam_server_certificate.go b/aws/resource_aws_iam_server_certificate.go index 870d19537f9..dd1df13ede0 100644 --- a/aws/resource_aws_iam_server_certificate.go +++ b/aws/resource_aws_iam_server_certificate.go @@ -16,12 +16,14 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) func resourceAwsIAMServerCertificate() *schema.Resource { return &schema.Resource{ Create: resourceAwsIAMServerCertificateCreate, Read: resourceAwsIAMServerCertificateRead, + Update: resourceAwsIAMServerCertificateUpdate, Delete: resourceAwsIAMServerCertificateDelete, Importer: &schema.ResourceImporter{ State: resourceAwsIAMServerCertificateImport, @@ -79,9 +81,17 @@ func resourceAwsIAMServerCertificate() *schema.Resource { "arn": { Type: schema.TypeString, - Optional: true, Computed: true, }, + "expiration": { + Type: schema.TypeString, + Computed: true, + }, + "upload_date": { + Type: schema.TypeString, + Computed: true, + }, + "tags": tagsSchema(), }, } } @@ -102,6 +112,7 @@ func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interfac CertificateBody: aws.String(d.Get("certificate_body").(string)), PrivateKey: aws.String(d.Get("private_key").(string)), ServerCertificateName: aws.String(sslCertName), + Tags: keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().IamTags(), } if v, ok := d.GetOk("certificate_chain"); ok { @@ -126,6 +137,8 @@ func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interfac func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + resp, err := conn.GetServerCertificate(&iam.GetServerCertificateInput{ ServerCertificateName: aws.String(d.Get("name").(string)), }) @@ -140,16 +153,38 @@ func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{ return fmt.Errorf("error reading IAM Server Certificate (%s): %w", d.Id(), err) } - d.SetId(aws.StringValue(resp.ServerCertificate.ServerCertificateMetadata.ServerCertificateId)) + cert := resp.ServerCertificate + metadata := cert.ServerCertificateMetadata + d.SetId(aws.StringValue(metadata.ServerCertificateId)) - d.Set("certificate_body", resp.ServerCertificate.CertificateBody) - d.Set("certificate_chain", resp.ServerCertificate.CertificateChain) - d.Set("path", resp.ServerCertificate.ServerCertificateMetadata.Path) - d.Set("arn", resp.ServerCertificate.ServerCertificateMetadata.Arn) + d.Set("certificate_body", cert.CertificateBody) + d.Set("certificate_chain", cert.CertificateChain) + d.Set("path", metadata.Path) + d.Set("arn", metadata.Arn) + d.Set("expiration", aws.TimeValue(metadata.Expiration).Format(time.RFC3339)) + d.Set("upload_date", aws.TimeValue(metadata.UploadDate).Format(time.RFC3339)) + + if err := d.Set("tags", keyvaluetags.IamKeyValueTags(cert.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } return nil } +func resourceAwsIAMServerCertificateUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).iamconn + + if d.HasChange("tags") { + o, n := d.GetChange("tags") + + if err := keyvaluetags.IamServerCertificateUpdateTags(conn, d.Id(), o, n); err != nil { + return fmt.Errorf("error updating tags for IAM Server Certificate (%s): %w", d.Id(), err) + } + } + + return resourceAwsIAMServerCertificateRead(d, meta) +} + func resourceAwsIAMServerCertificateDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).iamconn log.Printf("[INFO] Deleting IAM Server Certificate: %s", d.Id()) @@ -160,12 +195,12 @@ 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") { + if awsErr.Code() == iam.ErrCodeDeleteConflictException && strings.Contains(awsErr.Message(), "currently in use by arn") { currentlyInUseBy(awsErr.Message(), meta.(*AWSClient).elbconn) log.Printf("[WARN] Conflict deleting server certificate: %s, retrying", awsErr.Message()) return resource.RetryableError(err) } - if awsErr.Code() == "NoSuchEntity" { + if awsErr.Code() == iam.ErrCodeNoSuchEntityException { return nil } } diff --git a/aws/resource_aws_iam_server_certificate_test.go b/aws/resource_aws_iam_server_certificate_test.go index d27cd8c3c07..96fb08d4be6 100644 --- a/aws/resource_aws_iam_server_certificate_test.go +++ b/aws/resource_aws_iam_server_certificate_test.go @@ -56,7 +56,7 @@ func testSweepIamServerCertificates(region string) error { func TestAccAWSIAMServerCertificate_basic(t *testing.T) { var cert iam.ServerCertificate - resourceName := "aws_iam_server_certificate.test_cert" + resourceName := "aws_iam_server_certificate.test" rName := acctest.RandomWithPrefix("tf-acc-test") key := tlsRsaPrivateKeyPem(2048) @@ -71,25 +71,31 @@ func TestAccAWSIAMServerCertificate_basic(t *testing.T) { Config: testAccIAMServerCertConfig(rName, key, certificate), Check: resource.ComposeTestCheckFunc( testAccCheckCertExists(resourceName, &cert), - testAccCheckAWSServerCertAttributes(&cert, &certificate), + testAccCheckResourceAttrGlobalARN(resourceName, "arn", "iam", fmt.Sprintf("server-certificate/%s", rName)), + testAccCheckResourceAttrRfc3339(resourceName, "expiration"), + testAccCheckResourceAttrRfc3339(resourceName, "upload_date"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "path", "/"), + resource.TestCheckResourceAttr(resourceName, "certificate_body", strings.TrimSpace(certificate)), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateId: rName, - ImportStateVerifyIgnore: []string{ - "private_key"}, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateId: rName, + ImportStateVerifyIgnore: []string{"private_key"}, }, }, }) } -func TestAccAWSIAMServerCertificate_name_prefix(t *testing.T) { +func TestAccAWSIAMServerCertificate_tags(t *testing.T) { var cert iam.ServerCertificate - resourceName := "aws_iam_server_certificate.test_cert" + resourceName := "aws_iam_server_certificate.test" + rName := acctest.RandomWithPrefix("tf-acc-test") key := tlsRsaPrivateKeyPem(2048) certificate := tlsRsaX509SelfSignedCertificatePem(key, "example.com") @@ -100,36 +106,70 @@ func TestAccAWSIAMServerCertificate_name_prefix(t *testing.T) { CheckDestroy: testAccCheckIAMServerCertificateDestroy, Steps: []resource.TestStep{ { - Config: testAccIAMServerCertConfig_random(key, certificate), + Config: testAccIAMServerCertConfigTags1(rName, key, certificate, "key1", "value1"), Check: resource.ComposeTestCheckFunc( testAccCheckCertExists(resourceName, &cert), - testAccCheckAWSServerCertAttributes(&cert, &certificate), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateId: rName, + ImportStateVerifyIgnore: []string{"private_key"}, + }, + { + Config: testAccIAMServerCertConfigTags2(rName, key, certificate, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCertExists(resourceName, &cert), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccIAMServerCertConfigTags1(rName, key, certificate, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCertExists(resourceName, &cert), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), }, }, }) } -func TestAccAWSIAMServerCertificate_disappears(t *testing.T) { +func TestAccAWSIAMServerCertificate_name_prefix(t *testing.T) { var cert iam.ServerCertificate - resourceName := "aws_iam_server_certificate.test_cert" + + resourceName := "aws_iam_server_certificate.test" key := tlsRsaPrivateKeyPem(2048) certificate := tlsRsaX509SelfSignedCertificatePem(key, "example.com") - testDestroyCert := func(*terraform.State) error { - // reach out and DELETE the Cert - conn := testAccProvider.Meta().(*AWSClient).iamconn - _, err := conn.DeleteServerCertificate(&iam.DeleteServerCertificateInput{ - ServerCertificateName: cert.ServerCertificateMetadata.ServerCertificateName, - }) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIAMServerCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIAMServerCertConfig_random(key, certificate), + Check: resource.ComposeTestCheckFunc( + testAccCheckCertExists(resourceName, &cert), + ), + }, + }, + }) +} - if err != nil { - return fmt.Errorf("Error destroying cert in test: %s", err) - } +func TestAccAWSIAMServerCertificate_disappears(t *testing.T) { + var cert iam.ServerCertificate + resourceName := "aws_iam_server_certificate.test" - return nil - } + key := tlsRsaPrivateKeyPem(2048) + certificate := tlsRsaX509SelfSignedCertificatePem(key, "example.com") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -140,7 +180,7 @@ func TestAccAWSIAMServerCertificate_disappears(t *testing.T) { Config: testAccIAMServerCertConfig_random(key, certificate), Check: resource.ComposeTestCheckFunc( testAccCheckCertExists(resourceName, &cert), - testDestroyCert, + testAccCheckResourceDisappears(testAccProvider, resourceAwsIAMServerCertificate(), resourceName), ), ExpectNonEmptyPlan: true, }, @@ -154,7 +194,7 @@ func TestAccAWSIAMServerCertificate_file(t *testing.T) { rInt := acctest.RandInt() unixFile := "test-fixtures/iam-ssl-unix-line-endings.pem" winFile := "test-fixtures/iam-ssl-windows-line-endings.pem.winfile" - resourceName := "aws_iam_server_certificate.test_cert" + resourceName := "aws_iam_server_certificate.test" resourceId := fmt.Sprintf("terraform-test-cert-%d", rInt) resource.ParallelTest(t, resource.TestCase{ @@ -169,12 +209,11 @@ func TestAccAWSIAMServerCertificate_file(t *testing.T) { ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateId: resourceId, - ImportStateVerifyIgnore: []string{ - "private_key"}, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateId: resourceId, + ImportStateVerifyIgnore: []string{"private_key"}, }, { Config: testAccIAMServerCertConfig_file(rInt, winFile), @@ -189,7 +228,7 @@ func TestAccAWSIAMServerCertificate_file(t *testing.T) { func TestAccAWSIAMServerCertificate_Path(t *testing.T) { var cert iam.ServerCertificate - resourceName := "aws_iam_server_certificate.test_cert" + resourceName := "aws_iam_server_certificate.test" rName := acctest.RandomWithPrefix("tf-acc-test") key := tlsRsaPrivateKeyPem(2048) @@ -204,17 +243,15 @@ func TestAccAWSIAMServerCertificate_Path(t *testing.T) { Config: testAccIAMServerCertConfig_path(rName, "/test/", key, certificate), Check: resource.ComposeTestCheckFunc( testAccCheckCertExists(resourceName, &cert), - testAccCheckAWSServerCertAttributes(&cert, &certificate), resource.TestCheckResourceAttr(resourceName, "path", "/test/"), ), }, { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateId: rName, - ImportStateVerifyIgnore: []string{ - "private_key"}, + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateId: rName, + ImportStateVerifyIgnore: []string{"private_key"}, }, }, }) @@ -246,19 +283,6 @@ func testAccCheckCertExists(n string, cert *iam.ServerCertificate) resource.Test } } -func testAccCheckAWSServerCertAttributes(cert *iam.ServerCertificate, certBody *string) resource.TestCheckFunc { - return func(s *terraform.State) error { - if !strings.Contains(*cert.ServerCertificateMetadata.ServerCertificateName, "tf-acc-test") { - return fmt.Errorf("Bad Server Cert Name: %s", *cert.ServerCertificateMetadata.ServerCertificateName) - } - - if *cert.CertificateBody != strings.TrimSpace(*certBody) { - return fmt.Errorf("Bad Server Cert body\n\t expected: %s\n\tgot: %s\n", *certBody, *cert.CertificateBody) - } - return nil - } -} - func testAccCheckIAMServerCertificateDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).iamconn @@ -287,7 +311,7 @@ func testAccCheckIAMServerCertificateDestroy(s *terraform.State) error { func testAccIAMServerCertConfig(rName, key, certificate string) string { return fmt.Sprintf(` -resource "aws_iam_server_certificate" "test_cert" { +resource "aws_iam_server_certificate" "test" { name = "%[1]s" certificate_body = "%[2]s" private_key = "%[3]s" @@ -297,7 +321,7 @@ resource "aws_iam_server_certificate" "test_cert" { func testAccIAMServerCertConfig_random(key, certificate string) string { return fmt.Sprintf(` -resource "aws_iam_server_certificate" "test_cert" { +resource "aws_iam_server_certificate" "test" { name_prefix = "tf-acc-test" certificate_body = "%[1]s" private_key = "%[2]s" @@ -307,7 +331,7 @@ resource "aws_iam_server_certificate" "test_cert" { func testAccIAMServerCertConfig_path(rName, path, key, certificate string) string { return fmt.Sprintf(` -resource "aws_iam_server_certificate" "test_cert" { +resource "aws_iam_server_certificate" "test" { name = "%[1]s" path = "%[2]s" certificate_body = "%[3]s" @@ -319,7 +343,7 @@ resource "aws_iam_server_certificate" "test_cert" { // iam-ssl-unix-line-endings func testAccIAMServerCertConfig_file(rInt int, fName string) string { return fmt.Sprintf(` -resource "aws_iam_server_certificate" "test_cert" { +resource "aws_iam_server_certificate" "test" { name = "terraform-test-cert-%d" certificate_body = file("%s") @@ -343,3 +367,32 @@ EOF } `, rInt, fName) } + +func testAccIAMServerCertConfigTags1(rName, key, certificate, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_iam_server_certificate" "test" { + name = "%[1]s" + certificate_body = "%[2]s" + private_key = "%[3]s" + + tags = { + %[4]q = %[5]q + } +} +`, rName, tlsPemEscapeNewlines(certificate), tlsPemEscapeNewlines(key), tagKey1, tagValue1) +} + +func testAccIAMServerCertConfigTags2(rName, key, certificate, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_iam_server_certificate" "test" { + name = "%[1]s" + certificate_body = "%[2]s" + private_key = "%[3]s" + + tags = { + %[4]q = %[5]q + %[6]q = %[7]q + } +} +`, rName, tlsPemEscapeNewlines(certificate), tlsPemEscapeNewlines(key), tagKey1, tagValue1, tagKey2, tagValue2) +} diff --git a/website/docs/r/iam_server_certificate.html.markdown b/website/docs/r/iam_server_certificate.html.markdown index e6ed655fcfa..5557e999210 100644 --- a/website/docs/r/iam_server_certificate.html.markdown +++ b/website/docs/r/iam_server_certificate.html.markdown @@ -117,6 +117,7 @@ In addition to all arguments above, the following attributes are exported: * `id` - The unique Server Certificate name * `name` - The name of the Server Certificate * `arn` - The Amazon Resource Name (ARN) specifying the server certificate. +* `tags` - Key-value mapping of tags for the server certificate. ## Import From 3f6f12b2dff15a389f2cf643950cb91ec8061bd7 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Sat, 6 Mar 2021 09:54:20 +0200 Subject: [PATCH 2/8] fix update tags --- aws/resource_aws_iam_server_certificate.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_iam_server_certificate.go b/aws/resource_aws_iam_server_certificate.go index dd1df13ede0..ef979904e3c 100644 --- a/aws/resource_aws_iam_server_certificate.go +++ b/aws/resource_aws_iam_server_certificate.go @@ -177,8 +177,8 @@ func resourceAwsIAMServerCertificateUpdate(d *schema.ResourceData, meta interfac if d.HasChange("tags") { o, n := d.GetChange("tags") - if err := keyvaluetags.IamServerCertificateUpdateTags(conn, d.Id(), o, n); err != nil { - return fmt.Errorf("error updating tags for IAM Server Certificate (%s): %w", d.Id(), err) + if err := keyvaluetags.IamServerCertificateUpdateTags(conn, d.Get("name").(string), o, n); err != nil { + return fmt.Errorf("error updating tags for IAM Server Certificate (%s): %w", d.Get("name").(string), err) } } From 0b8be00c37d087fa25c8c95e25fddf26aecd015d Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Sat, 6 Mar 2021 10:00:42 +0200 Subject: [PATCH 3/8] changelog --- .changelog/17967.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/17967.txt diff --git a/.changelog/17967.txt b/.changelog/17967.txt new file mode 100644 index 00000000000..6211bc97134 --- /dev/null +++ b/.changelog/17967.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_iam_server_certificate: Add tagging support +``` From 3c5e1bce9e9e51ce470b1f313fd7a47b6b817d80 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Sat, 6 Mar 2021 10:02:06 +0200 Subject: [PATCH 4/8] changelog --- .changelog/17967.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.changelog/17967.txt b/.changelog/17967.txt index 6211bc97134..ff8a2683876 100644 --- a/.changelog/17967.txt +++ b/.changelog/17967.txt @@ -1,3 +1,7 @@ ```release-note:enhancement resource/aws_iam_server_certificate: Add tagging support ``` + +```release-note:enhancement +resource/aws_iam_server_certificate: Add `expiration` and `upload_date` attributes +``` From 195e806f7f7bf1950b6109cec3ba30600cdbbe39 Mon Sep 17 00:00:00 2001 From: drfaust92 Date: Sun, 7 Mar 2021 10:06:15 +0200 Subject: [PATCH 5/8] add docs --- website/docs/r/iam_server_certificate.html.markdown | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/docs/r/iam_server_certificate.html.markdown b/website/docs/r/iam_server_certificate.html.markdown index 5557e999210..15bb31e7f24 100644 --- a/website/docs/r/iam_server_certificate.html.markdown +++ b/website/docs/r/iam_server_certificate.html.markdown @@ -118,7 +118,8 @@ In addition to all arguments above, the following attributes are exported: * `name` - The name of the Server Certificate * `arn` - The Amazon Resource Name (ARN) specifying the server certificate. * `tags` - Key-value mapping of tags for the server certificate. - +* `expiration` - The date on which the certificate is set to expire. +* `upload_date` - The date when the server certificate was uploaded. ## Import IAM Server Certificates can be imported using the `name`, e.g. From d7fad54a908a956e87ef6f1281af301575900531 Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Sun, 7 Mar 2021 10:16:41 +0200 Subject: [PATCH 6/8] Update iam_server_certificate.html.markdown --- website/docs/r/iam_server_certificate.html.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/website/docs/r/iam_server_certificate.html.markdown b/website/docs/r/iam_server_certificate.html.markdown index 15bb31e7f24..040f27e0d6c 100644 --- a/website/docs/r/iam_server_certificate.html.markdown +++ b/website/docs/r/iam_server_certificate.html.markdown @@ -120,6 +120,7 @@ In addition to all arguments above, the following attributes are exported: * `tags` - Key-value mapping of tags for the server certificate. * `expiration` - The date on which the certificate is set to expire. * `upload_date` - The date when the server certificate was uploaded. +* ## Import IAM Server Certificates can be imported using the `name`, e.g. From 3fb2f9ef131cd2ad21bdd7b74abebccf26704d52 Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Sun, 7 Mar 2021 10:16:55 +0200 Subject: [PATCH 7/8] Update iam_server_certificate.html.markdown --- website/docs/r/iam_server_certificate.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/iam_server_certificate.html.markdown b/website/docs/r/iam_server_certificate.html.markdown index 040f27e0d6c..2b08f4c3d5d 100644 --- a/website/docs/r/iam_server_certificate.html.markdown +++ b/website/docs/r/iam_server_certificate.html.markdown @@ -120,7 +120,7 @@ In addition to all arguments above, the following attributes are exported: * `tags` - Key-value mapping of tags for the server certificate. * `expiration` - The date on which the certificate is set to expire. * `upload_date` - The date when the server certificate was uploaded. -* + ## Import IAM Server Certificates can be imported using the `name`, e.g. From 2cb9e61ef777f3543143f5b34b2b1ff62aef0fc6 Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Thu, 25 Mar 2021 19:36:43 +0200 Subject: [PATCH 8/8] Update aws/resource_aws_iam_server_certificate.go Co-authored-by: Brian Flad --- aws/resource_aws_iam_server_certificate.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_iam_server_certificate.go b/aws/resource_aws_iam_server_certificate.go index ef979904e3c..3c95305659f 100644 --- a/aws/resource_aws_iam_server_certificate.go +++ b/aws/resource_aws_iam_server_certificate.go @@ -161,8 +161,17 @@ func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{ d.Set("certificate_chain", cert.CertificateChain) d.Set("path", metadata.Path) d.Set("arn", metadata.Arn) - d.Set("expiration", aws.TimeValue(metadata.Expiration).Format(time.RFC3339)) - d.Set("upload_date", aws.TimeValue(metadata.UploadDate).Format(time.RFC3339)) + if metadata.Expiration != nil { + d.Set("expiration", aws.TimeValue(metadata.Expiration).Format(time.RFC3339)) + } else { + d.Set("expiration", nil) + } + + if metadata.UploadDate != nil { + d.Set("upload_date", aws.TimeValue(metadata.UploadDate).Format(time.RFC3339)) + } else { + d.Set("upload_date", nil) + } if err := d.Set("tags", keyvaluetags.IamKeyValueTags(cert.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %w", err)