Skip to content

Commit

Permalink
Merge pull request #23126 from tmarlok88/f-iot-cert-use-existing
Browse files Browse the repository at this point in the history
Ability to register existing IoT certificate
  • Loading branch information
ewbankkit authored Mar 15, 2022
2 parents 242b03b + a69623e commit 92d3a20
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .changelog/23126.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_iot_certificate: Add `ca_pem` argument, enabling the use of existing IoT certificates
```
39 changes: 39 additions & 0 deletions internal/service/iot/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,15 @@ func ResourceCertificate() *schema.Resource {
},
"certificate_pem": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Sensitive: true,
},
"ca_pem": {
Type: schema.TypeString,
Optional: true,
Sensitive: true,
},
"public_key": {
Type: schema.TypeString,
Computed: true,
Expand All @@ -52,6 +58,14 @@ func ResourceCertificate() *schema.Resource {
func resourceCertificateCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).IoTConn

_, okcert := d.GetOk("certificate_pem")
_, okCA := d.GetOk("ca_pem")

cert_status := "INACTIVE"
if d.Get("active").(bool) {
cert_status = "ACTIVE"
}

if _, ok := d.GetOk("csr"); ok {
log.Printf("[DEBUG] Creating certificate from CSR")
out, err := conn.CreateCertificateFromCsr(&iot.CreateCertificateFromCsrInput{
Expand All @@ -63,6 +77,31 @@ func resourceCertificateCreate(d *schema.ResourceData, meta interface{}) error {
}
log.Printf("[DEBUG] Created certificate from CSR")

d.SetId(aws.StringValue(out.CertificateId))
} else if okcert && okCA {
log.Printf("[DEBUG] Registering certificate with CA")
out, err := conn.RegisterCertificate(&iot.RegisterCertificateInput{
CaCertificatePem: aws.String(d.Get("ca_pem").(string)),
CertificatePem: aws.String(d.Get("certificate_pem").(string)),
Status: aws.String(cert_status),
})
if err != nil {
return fmt.Errorf("error registering certificate with CA: %v", err)
}
log.Printf("[DEBUG] Certificate with CA registered")

d.SetId(aws.StringValue(out.CertificateId))
} else if okcert {
log.Printf("[DEBUG] Registering certificate without CA")
out, err := conn.RegisterCertificateWithoutCA(&iot.RegisterCertificateWithoutCAInput{
CertificatePem: aws.String(d.Get("certificate_pem").(string)),
Status: aws.String(cert_status),
})
if err != nil {
return fmt.Errorf("error registering certificate without CA: %v", err)
}
log.Printf("[DEBUG] Certificate without CA registered")

d.SetId(aws.StringValue(out.CertificateId))
} else {
log.Printf("[DEBUG] Creating keys and certificate")
Expand Down
32 changes: 32 additions & 0 deletions internal/service/iot/certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,31 @@ func TestAccIoTCertificate_Keys_certificate(t *testing.T) {
})
}

func TestAccIoTCertificate_Keys_existing_certificate(t *testing.T) {
key := acctest.TLSRSAPrivateKeyPEM(2048)
certificate := acctest.TLSRSAX509SelfSignedCertificatePEM(key, "testcert")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, iot.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckCertificateDestroy_basic,
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(testAccCertificate_existing_certificate, acctest.TLSPEMEscapeNewlines(certificate)),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("aws_iot_certificate.foo_cert", "arn"),
resource.TestCheckNoResourceAttr("aws_iot_certificate.foo_cert", "csr"),
resource.TestCheckResourceAttrSet("aws_iot_certificate.foo_cert", "certificate_pem"),
resource.TestCheckNoResourceAttr("aws_iot_certificate.foo_cert", "public_key"),
resource.TestCheckNoResourceAttr("aws_iot_certificate.foo_cert", "private_key"),
resource.TestCheckResourceAttr("aws_iot_certificate.foo_cert", "active", "true"),
),
},
},
})
}

func testAccCheckCertificateDestroy_basic(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).IoTConn

Expand Down Expand Up @@ -103,3 +128,10 @@ resource "aws_iot_certificate" "foo_cert" {
active = true
}
`

var testAccCertificate_existing_certificate = `
resource "aws_iot_certificate" "foo_cert" {
active = true
certificate_pem = "%[1]s"
}
`
21 changes: 19 additions & 2 deletions website/docs/r/iot_certificate.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ resource "aws_iot_certificate" "cert" {
}
```

### From existing certificate without a CA

```terraform
resource "aws_iot_certificate" "cert" {
certificate_pem = file("/my/cert.pem")
active = true
}
```


## Argument Reference

* `active` - (Required) Boolean flag to indicate if the certificate should be active
Expand All @@ -37,6 +47,13 @@ resource "aws_iot_certificate" "cert" {
for more information on generating a certificate from a certificate signing request (CSR).
If none is specified both the certificate and keys will be generated, review [CreateKeysAndCertificate](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateKeysAndCertificate.html)
for more information on generating keys and a certificate.
* `certificate_pem` - (Optional) The certificate to be registered. If `ca_pem` is unspecified, review
[RegisterCertificateWithoutCA](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterCertificateWithoutCA.html).
If `ca_pem` is specified, review
[RegisterCertificate](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterCertificate.html)
for more information on registering a certificate.
* `ca_pem` - (Optional) The CA certificate for the certificate to be registered. If this is set, the CA needs to be registered with AWS IoT beforehand.


## Attributes Reference

Expand All @@ -45,6 +62,6 @@ In addition to all arguments above, the following attributes are exported:
* `id` - The internal ID assigned to this certificate.
* `arn` - The ARN of the created certificate.
* `certificate_pem` - The certificate data, in PEM format.
* `public_key` - When no CSR is provided, the public key.
* `private_key` - When no CSR is provided, the private key.
* `public_key` - When neither CSR nor certificate is provided, the public key.
* `private_key` - When neither CSR nor certificate is provided, the private key.

0 comments on commit 92d3a20

Please sign in to comment.