Certificate Management in Terraform
  • 22 Dec 2024
  • 11 Minutes to read
  • PDF

Certificate Management in Terraform

  • PDF

Article summary

Certificate Management

Qwilt CDN supports two distinct workflows for certificate management:

  • Upload Certificate and Private key
    Upload a certificate, chain, and private key directly to the CDN, to make it available for linking to a site.

    Once a certificate is available on the CDN, it can be linked to a site, regardless of if it is managed in Terraform.

    To bring existing certificates under Terraform's management, you can import them. Importing a certificate creates a named resource in Terraform.

    New certificates created in Terraform are automatically uploaded to the CDN and available for management within Terraform.

  • Certificate Template (CSR workflow)
    Use the Certificate Template feature to generate a Certificate Signing Request (CSR) while keeping private keys secure with no need to share them.

    With the Certificate Template feature, you can choose to allow Qwilt to manage the CSR lifecycle using Let's Encrypt, or you can generate and download the CSR to manage the lifecycle yourself using any Certificate Authority (CA).

    Currently, the Qwilt Terraform Provider supports setting up a Qwilt-managed CSR workflow.

    To manage the CSR lifecycle yourself for a site managed in Terraform, use the Certificate Manager API or UI to set up a self-managed certificate template workflow. Then in Terraform, add the certificate template directly to the site_activation resource.

Upload Certificate and Private Key Workflow

This workflow requires uploading a certificate, chain, and private key directly to the CDN, to make it available for linking to a site.

Upload a Certificate

Use the Terraform qwilt_cdn_certificate resource to upload a new PEM certificate to the CDN. All the users in your organization will have access to the certificate.

Note that the same certificate cannot be uploaded more than once. (Each certificate has a unique thumbprint. If you must upload a certificate again for any reason, please delete the original one first.)

To upload a certificate:

  1. Add the qwilt_cdn_certificate resource to the Terraform configuration.
  2. Set the mandatory parameters.
  3. Run terraform apply. The new certificate is uploaded to the CDN.

Learn how to associate a certificate to a site.

Import an Existing Certificate

To use Terraform to manage existing certificates that are already uploaded to the CDN but not yet under Terraform's control, importing them is necessary.

To import a certificate:

  1. Run the following command:

      terraform import qwilt_cdn_certificate.example <certId>
    

    You can use the qwilt_cdn_certificates data source to retrieve the certId.

  2. Use the output command to display the imported state for the resource.

  3. Note the certificate and certificate_chain values and add them to the resource in the Terraform configuration.

    In this example, the certificate, certificate_chain, and private_key attributes are kept in separate files, and referenced from the qwilt_cdn_certificate resource in the Terraform configuration file.

    resource "qwilt_cdn_certificate" "example" {
      certificate       = filebase64("./domain.crt")
      certificate_chain = filebase64("./domain.crt")
      private_key       = filebase64("./domain.key")
      description       = "example description"
    }
    
  4. For security reasons, the private_key remains empty in the state. To avoid this being detected as a change every time you run terraform plan, add this block to the qwilt_cdn_certificate resource:

    lifecycle {
      ignore_changes = [
        private_key
      ]
    }
    

    Learn more about the qwilt_cdn_certificate resource.

Link a Certificate to a Site

To link a certificate to your site, the certificate must first be uploaded to the CDN and it must be available to your user. A certificate that meets those requirements can be linked to your site whether or not the certificate is managed by Terraform. Only one certificate can be linked to a site. If needed, first unlink an old certificate and then link the new one.

To link a certificate to a site:

  1. In the Terraform configuration, add the certificate_id attribute to the qwilt_cdn_site_activation resource.

    resource "qwilt_cdn_site_activation" "example" {
      site_id        = qwilt_cdn_site_configuration.example.site_id
      revision_id    = qwilt_cdn_site_configuration.example.revision_id
      certificate_id = "<certificate id>"
    }
    

    The above example illustrates how to link to an explicit certificate_id. You could also link to a named qwilt_cdn_certificate resource if the resource exists in Terraform: certificate_id = qwilt_cdn_certificate.example.cert_id

  2. Run terraform apply.

Tip:

For a published site, you'll want to unlink the old certificate and link the new one simultaneously. To do so, in the qwilt_cdn_site_activation resource, replace the old certificate_id attribute value with the new certificate id. When you run 'terraform apply,' the old certificate is unlinked and the new certificate is linked to the site.

Unlink a Certificate

To disassociate a certificate from a site, unlink it. Note that unlinking a certificate from a site does not delete it from the CDN.

To unlink a certificate from a site:

  1. In the Terraform configuration, remove the certificate_id attribute from the qwilt_cdn_site_activation resource.
  2. Run terraform apply.

Update (Replace) a Site Certificate

Certificate renewal is a common scenario often referred to as a certificate update. However, certificates are immutable, so updating a site certificate actually involves replacing the certificate linked to a site with a new one and then republishing the site. The new certificate is activated when the site is republished.

We'll use this example configuration to illustrate how to update (replace) a site certificate.

resource "qwilt_cdn_certificate" "example" {
  certificate       = filebase64("./tf.example.com.crt")
  certificate_chain = filebase64("./tf.example.com.crt")
  private_key       = filebase64("./tf.example.com.key")
  description       = "Certificate for the Terraform basic example configuration"
}

resource "qwilt_cdn_site_activation" "example" {
  site_id        = qwilt_cdn_site_configuration.example.site_id
  revision_id    = qwilt_cdn_site_configuration.example.revision_id
  certificate_id = qwilt_cdn_certificate.example.cert_id
}

Example 1: Upload, Replace, and Activate a Certificate with a Single Command Process
You can upload an updated certificate, link it to the relevant site(s), and activate it like this:

  1. Create a new named certificate resource (example-2024-12-04 in this example) in your TF configuration like this:

    resource "qwilt_cdn_certificate" "example-2024-12-04" {
      certificate       = filebase64("./tf.example.com.new.crt")
      certificate_chain = filebase64("./tf.example.com.new.crt")
      private_key       = filebase64("./tf.example.com.key")
      description       = "Certificate for the Terraform basic example configuration dated 12/04/2024"
    }
    
  2. Update existing site activations to use the new named certificate resource:

    resource "qwilt_cdn_site_activation" "example" {
      site_id        = qwilt_cdn_site_configuration.example.site_id
      revision_id    = qwilt_cdn_site_configuration.example.revision_id
      certificate_id = qwilt_cdn_certificate.example-2024-12-04.cert_id
    }
    
  3. Run terraform apply. The new certificate is uploaded to the CDN, and a new publishing operation is submitted. Republishing the site is what activates the new certificate.

Example 2: Manage Certificate Upload and Site Activation as Separate Workflows
Alternatively, if you prefer to manage certificate upload and site activation as separate workflows—for example, to test a new certificate in a staging environment before activating it in production, start by creating the certificate resource. Once the certificate is created, update the site activation(s) to link the new certificate.

  1. Create the new named certificate resource (e.g. example-2024-12-04).

    resource "qwilt_cdn_certificate" "example-2024-12-04" {
      certificate       = filebase64("./tf.example.com.new.crt")
      certificate_chain = filebase64("./tf.example.com.new.crt")
      private_key       = filebase64("./tf.example.com.key")
      description       = "Certificate for the Terraform basic example configuration dated 12/04/2024"
    }
    
  2. Run terraform apply.

  3. Configure the certificate_id attribute in all the relevant site activations.

        resource "qwilt_cdn_site_activation" "example" {
          site_id        = qwilt_cdn_site_configuration.example.site_id
          revision_id    = qwilt_cdn_site_configuration.example.revision_id
          certificate_id = qwilt_cdn_certificate.example-2024-12-04.cert_id
        }
        ```
        
    
  4. Run terraform apply.

Example 3: Use Explicit Certificate IDs for Site Activation
You can use explicit certificate IDs instead of referencing named resources, for example if the certificate is managed with the API or UI and not in Terraform. In this case, the Certificate must be uploaded to the CDN before you apply site activation.

Note that you can use the qwilt_cdn_certificates data source to retrieve the cert_Id.

  1. Upload the Certificate to the CDN in one of three ways:

  2. Configure the certificate_id attribute with the new cert_id in all the relevant site activations.

        resource "qwilt_cdn_site_activation" "example" {
          site_id        = qwilt_cdn_site_configuration.example.site_id
          revision_id    = qwilt_cdn_site_configuration.example.revision_id
          certificate_id = "<certificate id>"
        }
        ```
        
    
  3. Run terraform apply.

Once new site activations are applied for all sites and there are no more sites referencing the old certificate, you can delete it.

Delete a Certificate

A linked certificate cannot be deleted. A certificate that is not available to your user cannot be deleted.

To delete a certificate from the CDN:

  1. Make sure that it is not linked to a site.
  2. Remove the named qwilt_cdn_certificate resource from the Terraform configuration.
  3. Run terraform apply.


Alternatively, you can explicitly destroy a certificate like this, where "example" is the name of the specific qwilt_cdn_certificate resource that you want to delete.

$ terraform destroy -target=qwilt_cdn_certificate.example

CSR Workflow

Use the Certificate Template resource to generate a Certificate Signing Request (CSR) while keeping private keys secure with no need to share them.

Set up a Qwilt-Managed CSR Workflow

Setting up a Qwilt-managed CSR workflow, allows Qwilt to handle the entire certificate lifecycle, including issuance and renewal.

The required steps:

  1. Create a Qwilt-Managed Certificate Template.
  2. Configure a CNAME Record for Domain Verification.
  3. Link the template to a site and activate the certificate.

Create a Qwilt-Managed Certificate Template

Use the Terraform qwilt_cdn_certificate_template resource to upload a new certificate template to the CDN. All the users in your organization will have access to the template.

To create a new certificate template:

  1. Add the qwilt_cdn_certificate_template resource to the Terraform configuration.

  2. Set the mandatory parameters.

    • auto_managed_certificate_template: Set this to true to create a Qwilt-managed certificate template.

    • common_name: The fully qualified domain name for which the certificate is issued.

      resource "qwilt_cdn_certificate_template" "example" {
        common_name                       = "example.com"
        auto_managed_certificate_template = true
      }
      
  3. Set the other certificate details including the organization details. Note that currently SANs are not supported for Qwilt-managed templates. This is a temporary limitation.
    Example resource configuration:

     resource "qwilt_cdn_certificate_template" "example" {
         common_name                       = "*.example.com"
         auto_managed_certificate_template = true 
         country                           = "US"
         organization_name                 = "Example Organization"
         state                             = "California"
         locality                          = "Redwood City"
         
       }
    
  4. Run terraform apply to create the new certificate template, CSR, and private key.
    Note the ACME challenge values in the Terraform output, as you will need them to create the required CNAME record.
    acmeChallengeTF.png

Configure a CNAME Record for Domain Verification

Configure a CNAME record to allow Qwilt to verify domain ownership with the CA for certificate issuance and renewal. This step is performed outside of the Qwilt environment, and is your responsibility to manage.
- Specify the record name and value using the Qwilt provided values from the Terraform output.
- We recommend setting the TTL to a maximum of one day.

Track the Status of the CSR

Once the CNAME record is created, Qwilt automatically sends the CSR to the CA. It will take 30 - 60 minutes for the signed certificate to be issued by the CA and become available for use.

Currently, you can use the Certificate Manager API to check the progress of the request, as indicated by the signingState value of the Get or List CSR endpoint response. Learn More.

Note that in case the signingState indicates a CSR failure, you can try to fix the underlying issue and then use the Certificate Manager API to trigger a new signing request.

Link the Template to a Site and Activate the Certificate

Once the signed certificate is available for use, you can link the template to a site.

Link a template to a site so that the latest certificate generated from the template will automatically be associated with the site. Linking the template and publishing the site to activate the template-generated certificate are one-time setup steps. Subsequently, Qwilt handles the entire CSR workflow for certificate renewals.

To link the template to a site:

  1. In the Terraform configuration, add the certificate_template_id attribute to the qwilt_cdn_site_activation resource.

    For example:

     resource "qwilt_cdn_site_activation" "example" {
              site_id        = qwilt_cdn_site_configuration.example.site_id
              revision_id    = qwilt_cdn_site_configuration.example.revision_id
              certificate_template_id = qwilt_cdn_certificate_template.example.certificate_template_id
     }
    

    The above example illustrates how to link to the named qwilt_cdn_certificate_template resource. You could also link to an explicit certificate_template_id:

    certificate_template_id="<certificate_template_id>"
    



    Tip: You can use the qwilt_cdn_certificate_templates data source to retrieve the certificate_template_id.

  2. Run terraform apply to activate the certificate that was generated from the template. Note that site activation will fail until a signed certificate associated with the template is available.

From now on, Qwilt manages the entire CSR flow for renewals.

Import a Template

You can import an existing certificate template to bring it under Terraform's control. However, it is important to note that you can use the template in the site_activation without importing it.

To import a template:

  1. Run the following command:

    terraform import qwilt_cdn_certificate_template.example <certificate_template_id>
    

    Tip: You can use the qwilt_certificate_templates data source to retrieve the certificate_template_id.

  2. Use the output command to display the imported state for the resource.

  3. Note the auto_managed_certificate_template and common_name values and add them to the resource in the Terraform configuration.
    For example:

    resource "qwilt_cdn_certificate_template" "example" {
        common_name                       = "example.com"
        auto_managed_certificate_template = true
    }
    

    Learn more about the qwilt_cdn_certificate_template resource.

Link a Template to a Site

Linking a certificate template to a site applies only to Qwilt-managed certificate templates. This step should be completed as part of the overall Qwilt-Managed CSR workflow setup.

Unlink a Template

To disassociate a template from a site, remove it from the site activation resource. The next time you apply the site activation resource, both the link to the template and the link to the current certificate associated with the site are broken.

If the site is in production, to ensure continuous coverage, we recommend adding a new certificate template to the site activation resource before running terraform apply.

Unlinking a Qwilt-managed certificate template from a site does not delete the template from the CDN. Qwilt will continue to manage certificate renewals for the template. However the current certificate linked to the site will be removed, and any new certificates generated from the template will not be automatically linked to the site.

To unlink a template from a site:

  1. In the Terraform configuration, remove the certificate_template_id attribute from the qwilt_cdn_site_activation resource.

    Important: If the site is already in production, to ensure continuous coverage, add a new certificate template to the site activation resource before running terraform apply.

  2. Run terraform apply.

Delete a Template

When you delete a certificate template, all of the CSRs generated from it and the associated private keys are deleted. As a result, any certificate generated from the template and currently linked to a site will become invalid.

To delete a certificate template that is managed in Terraform:

  1. Ensure that no certificate generated from the template is currently linked to a site in production.
  2. Remove the named qwilt_cdn_certificate_template resource from the Terraform configuration.
  3. Run terraform apply.

Was this article helpful?

What's Next
Changing your password will log you out immediately. Use the new password to log back in.
First name must have atleast 2 characters. Numbers and special characters are not allowed.
Last name must have atleast 1 characters. Numbers and special characters are not allowed.
Enter a valid email
Enter a valid password
Your profile has been successfully updated.