- 11 Dec 2024
- 20 Minutes to read
- Print
- PDF
Qwilt Terraform Provider User Guide
- Updated on 11 Dec 2024
- 20 Minutes to read
- Print
- PDF
Introduction
The Qwilt Terraform Provider allows you to manage your site configurations using a declarative configuration language. You can store, manage, and version your configuration data in the source control system of your choice.
The Qwilt Terraform Provider interacts with the Qwilt Sites API and the Qwilt Certificate Manager API.
Once you implement a site within a Terraform configuration, it is strongly recommended to manage the site exclusively through Terraform. Any updates made outside of Terraform, such as within the UI or API, must be manually applied in the Terraform configuration so that they are not overwritten during future terraform apply operations.
Both the Terraform state and configuration can contain sensitive information, such as private keys, and should be protected. HashiCorp recommends storing the Terraform state remotely and using the Terraform Remote State feature to avoid the risk of exposing sensitive information.
Install the Qwilt Provider
To get started using the Terraform Provider:
Verify that Terraform is installed.
Define the Qwilt Provider in the Terraform configuration.
terraform { required_providers { qwilt = { source = "Qwilt/qwilt" } } }
Create the provider configuration. Configure the authentication details.
provider "qwilt" { }
Initialize the provider using
terraform init
.
Authentication
The Qwilt Terraform Provider supports two authentication methods:
- API key-based authentication - The preferred method.
- When the api_key parameter is set, the key is passed in the header of each API call to authenticate the request.
- Learn how to generate an API key
- Login with username and password
- When the user name and password parameters are set, any Terraform command (apply, refresh, plan, etc.) triggers the Qwilt Login API to generate the required cqloud access token.
- Support for this method may be deprecated in the future.
Set the Authentication Parameters
You can set the authentication parameters inside the Terraform provider configuration, or as environment variables. We recommend setting env variables.
Supported Parameters:
Env Variable | TF Provider Variable | Example Value |
---|---|---|
QCDN_API_KEY | api_key | "eyJhbGciOiJSUzI1NiIsIn..." |
QCDN_USERNAME | username | "me@mycompany.com" |
QCDN_PASSWORD | password | "mypwd123456" |
As Env Variables
If the QCDN_API_KEY env variable is defined, the QCDN_USERNAME and QCDN_PASSWORD env variables are ignored.
An example of how to set the QCDN_API_KEY env variable:
export QCDN_API_KEY="eyJhbGciOiJSUzI1NiIsIn..."
When the authentication parameters are set by the environment variables, the provider config looks like this:
provider "qwilt" { }
Inside the Provider Config
If you set the authentication parameters in the Terraform provider configuration, you can define either the api_key or the username and password.
Quick Start
Explore the ReadMe files and examples in our playground on GitHub.
The sample configuration files under Playground demonstrate how to use the Qwilt Terraform provider. They can be used as starter files for provisioning and managing resources via the Terraform CLI. They are designed for customization-- replace placeholder values with your own specific configuration details. Replace the example certificate and key values with your own.
Also see the Qwilt Provider documentation on the Terraform registry for details about each of the resources. You can use the resource examples as templates for getting started.
Create or Import a Site
You have full flexibility when it comes to building your Media Delivery site in Terraform. You can either create the site directly within Terraform, or you can build it with the Media Delivery user interface or the Sites API and then import it into Terraform. For existing site configurations that are not yet managed by Terraform, importing them is necessary to bring them under Terraform's control.
Create a New Site
To create a site from within Terraform, create the following resources:
- qwilt_cdn_site - Define the site name.
- qwilt_cdn_site_configuration - Set the site configuration parameters that define exactly how the CDN will process client requests and deliver content.
- qwilt_cdn_site_activation - Specify the activation parameters for the site.
Each resource is assigned an ID upon which the subsequent resource depends.
You can add all the resources to the configuration file and run the apply command, or you can apply the resources individually.
If you choose to apply the resources individually, you must do so in the specified order because of the dependencies between them.
If your site uses HTTPS, you can create a qwilt_cdn_certificate or qwilt_cdn_certificate_template resource. Note that you can create these resources at any time. Also note that a site can use any relevant certificate or template on the CDN, even if it’s not managed in Terraform.
Learn about Certificate Management.
Step by Step Procedure
To configure a Media Delivery site with the Terraform Provider:
Build the Terraform configuration file.
For example:
resource "qwilt_cdn_site" "example" { site_name = "Terraform Basic Example Site" }
Define the site configuration resource.
For example:
resource "qwilt_cdn_site_configuration" "example" { site_id = qwilt_cdn_site.example.site_id host_index = <<-EOT { "hosts": [ { "host": "tf.example.com", "host-metadata": { "metadata": [ { "generic-metadata-type": "MI.SourceMetadataExtended", "generic-metadata-value": { "sources": [ { "protocol": "https/1.1", "endpoints": [ "origin-host.example.com" ] } ] } } ], "paths": [] } } ] } EOT change_description = "Basic example demonstrating the Terraform plugin" }
You could also save the JSON format as a stand-alone file and reference it from the host_index field, like this:
resource "qwilt_cdn_site_configuration" "example" { site_id = qwilt_cdn_site.example.site_id host_index = file("./siteconfig1.json") }
If your site uses HTTPS, then you need to set up your site to use certificates. Learn about Certificate Management
With Terraform, you can manually manage certificates using a certificate resource or let Qwilt manage the certificate lifecycle automatically with a certificate template resource.
The example demonstrates how to manually configure the certificate resource with a certificate, certificate chain, and private key. The certificate, certificate chain, and private key are loaded from their respective files using the filebase64 function.
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" }
Define the 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_id = qwilt_cdn_certificate.example.cert_id }
Including a certificate_id in the site activation resource links a certificate to the site. When you apply the configuration, the certificate is published together with the site.
Likewise, if you are working with a certificate template, you would add the certificate_template to the site activation resource to link the latest certificate generated from the template to the site.
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 }
Note that the certificate and certificate template resources are mutually exclusive.
If you choose to manage certificates with the Certificate Management UI or API instead of inside Terraform you can link directly to the relevant cert_id or cert_template_id.
For example:
certificate_id = "<certificate id>"
or
certificate_template_id = "<certificateTemplateId>"
Initialize the working directory if you have not already done so.
- In the CLI, navigate to the directory containing the configuration file/s.
- Run
terraform init
Review the configuration. For example, with
terraform plan
.Run
terraform apply
.
If the terraform configuration file includes all the resources, this is what happens:- The site is created and assigned a siteId.
- The site configuration is added to the site and assigned a revisionId.
- The certificate is uploaded to the Qwilt CDN and assigned a certId.
- The site is published and assigned a publishId; the certificate is associated with the site and published.
Note that it is also possible to define and apply one resource at a time, in the specified order. (The certificate and certificate template resources are not subject to this order. A new certificate or certificate template can be created at any time. An existing certificate or certificate template can be linked to the site at any time.)
Optionally, use the data sources to check the status of the publish operation or to retrieve any of the certificate, certificate template, site, revision, or publish IDs, and to retrieve the siteDnsCnameDelegationTarget value you'll use to route the website traffic to the CDN site.
Example Configuration
In this example, the host index and the certificate attributes are defined in external files and referenced within the resource configuration.
The purpose of the output blocks at the end of the configuration is to display information about the site and the site configuration in the CLI after running terraform apply
.
terraform {
required_providers {
qwilt = {
source = "Qwilt/qwilt"
}
}
}
provider "qwilt" {
}
resource "qwilt_cdn_site" "example" {
site_name = "Terraform Basic Example Site"
}
resource "qwilt_cdn_site_configuration" "example" {
site_id = qwilt_cdn_site.example.site_id
host_index = file("./examplesitebasic.json")
change_description = "Basic example demonstrating the Terraform plugin"
}
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
}
output "examplesite" {
value = qwilt_cdn_site.example
}
output "examplesiteconfig" {
value = qwilt_cdn_site_configuration.example
}
Import an Existing Site
You may import an existing site into Terraform by importing the following resources one at a time, in this order:
- qwilt_cdn_site - Imports the site.
- qwilt_cdn_site_configuration - Imports the site configuration.
- qwilt_cdn_site_activation - Imports a publishing operation.
The order is crucial because each resource is assigned an ID upon which the subsequent resource depends.
Additionally, you can import a certificate or certificate_template resource at any time. These resources are not mandatory. A new certificate or template can be created at any time. An existing certificate or template can be linked to the site at any time, regardless of whether it is managed in Terraform.
See the Qwilt Provider documentation on the Terraform registry for details about importing each of the resources. You can use the resource examples as templates for getting started.
Step by Step Procedure
To import an existing Media Delivery site into Terraform:
Create a Terraform configuration file (e.g., main.tf) with a basic structure for the configuration that you want to build.
For example:
terraform { required_providers { qwilt = { source = "Qwilt/qwilt" } } } provider "qwilt" { } resource "qwilt_cdn_site" "example" { } resource "qwilt_cdn_site_configuration" "example" { } resource "qwilt_cdn_certificate" "example" { } resource "qwilt_cdn_site_activation" "example" { } output "examplesite" { value = qwilt_cdn_site.example } output "examplesiteconfig" { value = qwilt_cdn_site_configuration.example }
Optionally, add an output host_index block to the Terraform configuration, so that later you can extract the host_index value from the qwilt_cdn_site_configuration resource.
Use the qwilt_cdn_sites data source or the QC Services UI to find the site_id of the site you wish to bring under Terraform control.
Initialize the working directory if you have not already done so.
- In the CLI, navigate to the directory containing the configuration file/s.
- Run
terraform init
Import the resources into the Terraform state, one at a time:
Optionally, import the site certificate or import the relevant certificate template.
Importing the site certificate or certificate template is optional. If you choose to import, and the site certificate was generated using a certificate template, import the template instead of the certificate.
Note that it is not mandatory to import a certificate or template; they can be added directly to the site_activation resource without being imported into Terraform.
Import the Site
Importing the site creates the site as a named resource in Terraform.
To import a site:
Run the following command:
terraform import qwilt_cdn_site.example <siteId>
Use the output command to display the imported state for the resource.
Note the site_name value and add it to the qwilt_cdn_site resource in the Terraform configuration file.
For example:resource "qwilt_cdn_site" "example" { site_name = "Terraform Example Site" }
Optionally, rename the site. We recommend adding the string "Terraform" to the site name, so that someone working in the UI will recognize it as a site that is managed in Terraform and shouldn't be modified with the UI.
Import a Site Configuration
The site configuration defines exactly how the CDN processes client requests and delivers content. Importing a site configuration creates the site configuration as a named resource in Terraform.
To import a site configuration:
Run the following command:
terraform import qwilt_cdn_site_configuration.example <siteId>
- By default, the active site configuration version is imported.
- If there is no active site configuration, the most recently published site configuration version is imported.
- If there is no published version, then the most recently saved version is imported.
Alternatively, you can specify the configuration version.
To import a specified site configuration version, run the following command:
terraform import qwilt_cdn_site_configuration.example <siteId>:<revisionId>
Use the output command to display the imported state for the resource.
Add the site_id value to the qwilt_cdn_site_configuration resource in the Terraform configuration file. When setting the site_id value, we recommend using a reference to achieve implicit dependency.
For example:resource "qwilt_cdn_site_configuration" "example" { site_id = qwilt_cdn_site.example.site_id }
Add the host_index (the site configuration JSON, found in the state file following import) to the qwilt_cdn_site_configuration resource in the Terraform configuration.
You can copy the JSON format in the suggested format to the host_index field in the configuration file like this:
resource "qwilt_cdn_site_configuration" "example" { site_id = qwilt_cdn_site.example.site_id host_index = <<-EOT { "hosts": [ { "host": "www.example.com", "host-metadata": { "metadata": [ { "generic-metadata-type": "MI.SourceMetadataExtended", "generic-metadata-value": { "sources": [ { "protocol": "https/1.1", "endpoints": [ "www.example-origin-host1.com" ] } ] } } ], "paths": [] } } ] } EOT }
Alternatively, you can save the JSON format as a stand-alone file in the suggested format and reference it from the host_index field, like this:
resource "qwilt_cdn_site_configuration" "example" { site_id = qwilt_cdn_site.example.site_id host_index = file("./siteconfig1.json") }
Add the change_description found in the state file to the qwilt_cdn_site_configuration resource in the Terraform configuration file.
resource "qwilt_cdn_site" "example" { site_id = qwilt_cdn_site.example.site_id host_index = file("./siteconfig1.json") change_description = "Example change description." }
Run
terraform plan
to verify that the local site configuration JSON (the host_index in the config file or referenced by the config file) is identical to the site configuration JSON in production (in the state file). Update the host_index as needed and runterraform plan
again. Repeat until the configurations are identical.
Import a Certificate (Optional)
If your site has an associated certificate and you want to manage the certificate in Terraform, you can import it. However, importing is optional. You can link the certificate to your site using the qwilt_cdn_site_activation resource, whether or not it is managed in Terraform.
Learn how to import a certificate.
Import a Certificate Template (Optional)
If your site has an associated certificate that was generated from a certificate template, and you want to manage the certificate in Terraform, you can import it. However, importing is optional. You can link the template to your site using the qwilt_cdn_site_activation resource, whether or not it is managed in Terraform.
Learn how to import a certificate template.
Import a Publishing Operation
You can import the most recent publishing operation relevant to the site, or a specified publishing operation.
To import a publishing operation:
Run the following command:
terraform import qwilt_cdn_site_activation.example <site_id>
- By default, this imports the active publishing operation.
- If there is no active publishing operation, then the most recent publishing operation is imported.
Alternatively, run this command to import a specified publishing operation:
terraform import qwilt_cdn_site_activation.example <site_id>:<publish_id>
Use the output command to display the imported state for the resource.
Add the site_id and revision_id to the qwilt_cdn_site_activation resource in the Terraform configuration. If the site has an associated certificate, also add the certificate_id.
When setting the values, we recommend using a reference to achieve implicit dependencies between resources. Note that if you plan to reference a certificate or certificate template in this way, the certificate/certificate template must first be imported into Terraform.
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_id = qwilt_cdn_certificate.example.cert_id }
Site Configuration JSON
The site configuration JSON defines how the CDN processes client requests and delivers content. It is set by the qwilt_cdn_site_configuration resource.
If you are creating a new site, you can build the configuration JSON manually, or you can use the Media Delivery user interface to configure a site and then copy the automatically generated JSON format.
Formatting the JSON for the Terraform provider.
When the configuration JSON is prepared, you can either copy it directly into the host_index attribute or save it as a stand-alone file and reference it from the host_index attribute.
Likewise, after importing an existing site configuration, you can either copy the JSON format from the Terraform state into the host_index attribute or save it as a standalone file and reference it from the host_index attribute.
Example 1: Configuration JSON as an External File
In this example, the configuration JSON is defined in an external file that is referenced by the host_index attribute.
resource "qwilt_cdn_site_configuration" "example" {
site_id = qwilt_cdn_site.example.site_id
host_index = file("./sitebasic.json")
change_description = "Example configuration JSON."
}
Example 2: Configuration JSON embedded in the host_index
In this example, the configuration JSON is embedded in the Terraform configuration, in the host_index attribute.
resource "qwilt_cdn_site_configuration" "example" {
site_id = qwilt_cdn_site.example.site_id
host_index = <<-EOT
{
"hosts": [
{
"host": "tf.example.com",
"host-metadata": {
"metadata": [
{
"generic-metadata-type": "MI.SourceMetadataExtended",
"generic-metadata-value": {
"sources": [
{
"protocol": "https/1.1",
"endpoints": [
"origin-host.example.com"
]
}
]
}
}
],
"paths": []
}
}
]
}
EOT
change_description = "Example configuration JSON."
}
Note: Include the "EOT" tag when copying the JSON format directly into the Terraform configuration. If you save the JSON in a separate file and reference it with the host_index, the "EOT" tag is not needed. (The change_description is always required.)
Suggested Formatting
To make it easier to spot changes in the state or when running the apply
command, we recommend formatting the JSON on multiple lines as shown above, rather than in a single line for the entire host index. This will enable identifying updates line by line.
After importing a site configuration into Terraform and adding the Host Index to the Terraform configuration, use terraform plan
to identify any differences. Adjust the JSON format in Terraform as needed. It is recommended that the formatting in production and in Terraform matches exactly, because Terraform recognizes even slight differences as updates.
To get your site configuration JSON in the suggested format, you can use a jq command like this one to format it and save it as a JSON file:
$ cat unformattedconfig.json | jq --tab >exampleconfig.json
Tips for Managing the Site Configuration JSON
Exporting the host_index
to a JSON file and then referencing it in the Terraform configuration can make it easier to manage your site configuration JSON. The idea is to keep the JSON format in a separate, easily editable file, which can be updated and referenced by the Terraform configuration as needed.
Before you import the qwilt_cdn_site_configuration resource, add an output block to the Terraform configuration to enable extracting the host_index value from the qwilt_cdn_site_configuration resource.
For example:
output "examplesitehostindex" { value = qwilt_cdn_site_configuration.example.host_index }
After importing the qwilt_cdn_site_configuration resource, use the terraform output command with the -raw flag to save the raw value of the host_index to a file.
For example:
$ terraform output -raw examplesitehostindex > exampleconfig.json
The -raw flag removes any extra formatting. In this example, the JSON format is saved to a file called exampleconfig.json.
In the Terraform configuration, set the host_index to reference the JSON File, like this:
resource "qwilt_cdn_site_configuration" "examplesiteconfig" { change_description = "Example configuration JSON." host_index = file("./exampleconfig.json") site_id = qwilt_cdn_site.examplesite.site_id }
Run
terraform apply
to apply the updates and verify that the host_index JSON is correctly referenced without any changes.
Site Management
In this section, we provide the basic information about managing a site once it is in Terraform.
Publish
You can publish or unpublish a site to either a production or staging environment.
Note there are two distinct, similarly named resources used for publishing:
- qwilt_cdn_site_activation - Used to publish/unpublish to production.
- qwilt_cdn_site_activation_staging - Used to publish/unpublish to staging.
A site cannot be published while another publishing operation is in progress. Wait for the one publishing operation to complete before launching a new one.
Publish a Site
After you publish a site, the CDN can begin using the configuration to process client requests. To direct traffic from your website to the CDN site, update your domain's DNS settings with the CNAME of the site. If the site was already published, the new configuration replaces the old one.
To publish a site to production:
- In the Terraform configuration, in the qwilt_cdn_site_activation resource, set the site_id and revision_id attributes.
- Optionally, set the certificate_id or certificate_template_id attribute.
- Run
terraform apply
.
You'll get a quick confirmation of the publish response, even though the publishing operation itself is not 100% complete. If you try to publish another update before the last publishing operation is completed, you'll get an error.
Publish to Staging
The Publish to Staging feature provides a way to validate an updated site configuration before publishing it to production. Learn more.
A distinct site activation resource, qwilt_cdn_site_activation_staging is specifically used for publishing to staging.
To publish a site to the staging environment:
In the Terraform configuration, in the qwilt_cdn_site_activation_staging resource, set the site_id and revision_id attributes.
Optionally, set the certificate_id or certificate_template_id attribute.
Run
terraform apply
.
You'll get a quick confirmation of the publish response, even though the publishing operation itself is not 100% complete. If you try to publish another update before the last publishing operation is completed, you'll get an error.
Unpublish a Site
You can unpublish a site from production or staging.
To unpublish a site from production:
- Remove the qwilt_cdn_site_activation resource from the Terraform configuration.
- Run
terraform apply
.
To unpublish a site from staging:
- Remove the qwilt_cdn_site_activation_staging resource from the Terraform configuration.
- Run
terraform apply
.
Update a Site Configuration
Update a site configuration by modifying the host_index (the JSON format).
To update a site configuration:
- Update the host_index attribute of the qwilt_cdn_site_configuration resource, or the referenced stand-alone file.
- Run
terraform apply
.
Delete a Site
To delete a site, you unpublish it by removing the site activation resource, and then the site configuration resource, and then the site resource. These steps must be performed one at a time, and in order.
To delete a site:
- Verify that the site is not published on a either a staging or production environment.
If needed unpublish the site. - Wait until the unpublish is complete.
- Remove the relevant qwilt_cdn_site_configuration resource from the Terraform configuration.
- Run
terraform apply
to delete the configuration version from the backend. - Remove the qwilt_cdn_site resource from the Terraform configuration.
- Run
terraform apply
to delete the site from the backend.
Rename a Site
To rename a site:
- In the Terraform configuration, update the site_name attribute of the qwilt_cdn_site resource.
- Run
terraform apply
.
Certificate Management
See Certificate Management in Terraform.
Supported Data Sources
Use the data sources to retrieve the details of the site in production.
qwilt_cdn_certificates - Retrieves details about the certificates uploaded to the CDN by users in your organization.
Learn more about the qwilt_cdn_certificates data source.qwilt_cdn_certificate_templates - Retrieves details about the certificate templates uploaded to the CDN by users in your organization.
Learn more about the qwilt_cdn_certificate_templates data source.qwilt_cdn_sites - Retrieves details about all sites, site configurations, and publishing operations. You can retrieve a subset of data by using filters to specify a siteId, revisionId, or publishId.
Learn more about the qwilt_cdn_sites data source.qwilt_cdn_origin_allow_list - Retrieves a comprehensive list of the IP addresses that Qwilt CDN may use to request content from your origin. The list includes the IPs from all of the networks where Qwilt CDN is present. Because of Qwilt's unique routing strategy, any of the IPs from any of the ISP networks may potentially send a request to your origin.
Learn more about the qwilt_cdn_origin_allow_list data source.
Experiment with the data source example on our GitHub playground to learn how to query different resources within your configuration.
Limitations
- General - It is important to note that once you implement a Terraform workflow for a particular site, you should continue working exclusively with the Terraform method for that site. The
terraform apply
command overwrites any updates made with the UI or API. So, unless you also made the same updates in Terraform the updates will disappear when you runterraform apply
. - Publish - A publishing operation may take up to 20 minutes. You cannot apply a new publishing operation until the previous one is complete. If you try to do so, you'll get the "Cannot Publish configuration while site is publishing" error. You can use the qwilt_cdn_sites data source to check the status of the most recent publishing operation.
- Purge - Purge is unsupported.