DEV Community

Vincent
Vincent

Posted on

IoT certificates for AWS with Terraform

Today I am trying to simplify the deployment of small projects with little amount of things on AWS. Having worked with AWS in the console to create the certificates, I realized it's an easy way to have that working but using IaC would be a breeze compared to that.

Create certificate requests with Terraform

Using certificates with terraform is pretty simple:

resource "tls_private_key" "signed_1" {
  algorithm = "RSA"
  rsa_bits  = 2048
}

resource "tls_cert_request" "signed_1" {
  private_key_pem = tls_private_key.signed_1.private_key_pem

  subject {
    organization = "iot.rpi.com"
    common_name = "thing1.iot.rpi.com"
  }
}
Enter fullscreen mode Exit fullscreen mode

Get a certificate from AWS IoT

Using the aws_iot_certificate we can get a certificate from the Certificate Signing Request (CSR) generated just before.

resource "aws_iot_certificate" "iot_certificate" {
  active = true
  csr = tls_cert_request.signed_1.cert_request_pem
}
Enter fullscreen mode Exit fullscreen mode

Output the certificates to use them

Then for our IoT thing, we will need the private key used to create our CSR, the certificate itself and the CA used to sign the certificate.

We can output them and define them as sensitive, they will be available in the terraform.tfstate file.

# Get a CA used to sign the certificate
data "tls_certificate" "aws_root_ca" {
  url = "https://www.amazontrust.com/repository/AmazonRootCA1.pem"
}

output "thing_cert_pem" {
  value = aws_iot_certificate.iot_certificate.certificate_pem
  sensitive = true
}

output "thing_key_pem" {
  value = tls_private_key.signed_1.private_key_pem
  sensitive = true
}

output "aws_root_ca_pem" {
  sensitive = true
  value = data.tls_certificate.aws_root_ca.content
}
Enter fullscreen mode Exit fullscreen mode

The result resides in the state file, that we can parse to get the values:

#!/bin/sh

mkdir -r certs

TERRAFORM_STATE_FILE=terraform.tfstate
CERT=$(jq ".outputs.thing_cert_pem.value" < ${TERRAFORM_STATE_FILE} | tr -d '"' )
KEY=$(jq ".outputs.thing_key_pem.value" < ${TERRAFORM_STATE_FILE}| tr -d '"')

# shellcheck disable=SC2039
echo "$CERT"> certs/thing1.crt.pem
# shellcheck disable=SC2039
echo "$KEY" > certs/thing1.key.pem
wget -O certs/AmazonRootCA1.pem "https://www.amazontrust.com/repository/AmazonRootCA1.pem"
Enter fullscreen mode Exit fullscreen mode

The PEM files will then be available in the certs folder and you just have to use them !


If you want to help me, buy me a coffe: Buy Me A Coffee

Thank you for reading

Top comments (0)