Menu

Expand
Rate this page:

Use Terraform and Twilio Serverless

Terraform is a infrastructure as code (IaC) tool that makes it easier to provision the infrastructure resources for your application. In this guide we will look at how and why you might want to leverage Terraform with your Twilio Functions and Assets project.

Prerequisites

You'll need the latest Terraform CLI installed on your system.

Additionally, make sure you have either have the following environment variables defined on your system:

  • TWILIO_ACCOUNT_SID with the Account SID of the project you want to deploy to
  • TWILIO_API_KEY with a valid API Key
  • TWILIO_API_SECRET with a valid secret for your API Key

Make sure you also have the latest version of the Serverless Toolkit installed. In this tutorial we'll be using the Twilio CLI plugin. Install the latest version of the Serverless Toolkit by running:

twilio plugins:remove @twilio-labs/plugin-serverless
twilio plugins:install @twilio-labs/plugin-serverless@latest

You'll also need an existing Twilio Serverless project created with the Serverless Toolkit. If you don't have one you can follow the Getting Started guide.

A brief Terraform introduction

Before we start with the work, there's a couple of things you need to understand about Terraform.

1. Provisioning not deployment

Terraform is primarily used to provision various resources but not for deploying applications. By default when you run twilio serverless:deploy or twilio-run deploy the Serverless Toolkit will handle both provisioning the respective Serverless Service and Environment and afterwards deploy your code to them.

Provisioning in this context is creating a Serverless Service/Environment resource but could also be any other Service you'd be creating using the CLI, API, or the Console. This can even be purchasing a new phone number. Deploying involves taking the respective code for your project and uploading it to those provisioned resources.

With Terraform we are splitting provisioning and deployment into distinct steps. Splitting these two steps has a couple of benefits:

  1. Separation of concerns. With Terraform you can provide a variety of Twilio and non-Twilio resources (more about this later). Grouping all resource provisioning together makes it easier to identify what resources are required for a project.
  2. Predictable and reproducable. Especially if your project involves several Twilio resources having these steps separately means we can rely on the correct resources to be created and can even share it with colleagues working on the same project (see the next section on state).

2. Maintaining state

An important aspect of Terraform is the fact that it maintains state of your resources. It does so by either creating a .tfstate file on your system or by storing it in a backend of your choice. The Terraform state contains information such as the SIDs of the Twilio resources you might have created through Terraform. By sharing this Terraform state with your colleagues by using a shared backend (you generally don't want to check-in a .tfstate file in your project) you can make sure you are all deploying to the right project.

3. Providers

Terraform providers are essentially integrations that can be used to teach Terraform how to create certain resources. We've released a Twilio provider for Terraform that we'll be using as part of this project. If you find any issues with it, don't hesitate to create a GitHub issue on the project.

In the Terraform Registry you can find a wide variety of providers for other platforms.

4. Common Terraform commands

There are a few common Terraform commands that will likely use when working with Terraform.

terraform init is used to set up your project. You'll need to run this for example if you clone your project or if you start using new providers. terraform fmt will make sure your Terraform file is formatted appropriately. terraform validate verifies that your file is correct including using the right resources available through the provider. terraform plan will compute the plan on how Terraform can move from the current state to the new state described in your Terraform file. terraform apply will handle the actual provisioning. It also runs terraform plan under the hood if you didn't run it before.

Write your Terraform script

Start by creating a main.tf file at the root of your project.

All the following code has to be added to this main.tf file in the order mentioned below. At the end of the section you can also find the full file for easy copy & paste.

Use the Twilio provider for Terraform

To create the Twilio resources we'll be using the Twilio provider. In order to make sure you are using the latest version, head over to the Terraform Registry page. Click the "Use Provider" button and copy the content into your main.tf file.

The result should look like this with possibly a different version.

terraform {
  required_providers {
    twilio = {
      source  = "twilio/twilio"
      version = "0.7.0"
    }
  }
}

provider "twilio" {
  # Configuration options
}

Define which resources to create

From here we can define which resources we want to create with Terraform. You can find a list of all available Twilio resources on GitHub. In our case we'll create a twilio_serverless_services_v1 and a twilio_serverless_services_environments_v1 as both are required for our Serverless deployment.

Add the following lines to your main.tf file:

resource "twilio_serverless_services_v1" "service" {
  friendly_name       = "Terraform Example Service"
  unique_name         = "terraform-demo"
  include_credentials = true
}

resource "twilio_serverless_services_environments_v1" "environment" {
  service_sid   = twilio_serverless_services_v1.service.sid
  unique_name   = "stage-environment"
  domain_suffix = "stage"
}

The first resource we create is a Serverless Service with the name terraform-demo and friendly name Terraform Example Service. The second resource we create is a Serverless Environment with the domain suffix stage and name stage-environment. For this resource we are passing in the SID of the previously created Service.

This is one of the strengths of us using Terraform for the provisioning as we can immediately define the relationship between the resources.

Declare your output

We'll have to tell the Serverless Toolkit to deploy the code to the Service and Environment we provisioned with Terraform. To do this we have to output the SIDs for the Service and Environment from Terraform.

Add the following code to your main.tf to output the relevant SIDs:

output "serverlessService" {
  value     = twilio_serverless_services_v1.service.sid
  sensitive = true
}

output "serverlessEnvironment" {
  value     = twilio_serverless_services_environments_v1.environment.sid
  sensitive = true
}

This completes our main.tf Terraform file that should look in total like this:

terraform {
  required_providers {
    twilio = {
      source  = "twilio/twilio"
      version = "0.7.0"
    }
  }
}

provider "twilio" {
  # Configuration options
}

resource "twilio_serverless_services_v1" "service" {
  friendly_name       = "Terraform Example Service"
  unique_name         = "terraform-demo"
  include_credentials = true
}

resource "twilio_serverless_services_environments_v1" "environment" {
  service_sid   = twilio_serverless_services_v1.service.sid
  unique_name   = "stage-environment"
  domain_suffix = "stage"
}

output "serverlessService" {
  value     = twilio_serverless_services_v1.service.sid
  sensitive = true
}

output "serverlessEnvironment" {
  value     = twilio_serverless_services_environments_v1.environment.sid
  sensitive = true
}

Run your Terraform script

Now that we have our completed Terraform file it's time to provision our resources.

First, if you have not done so yet, initialize your Terraform project by running:

terraform init

Next ensure that your main.tf is valid by running:

terraform fmt
terraform validate

If you want to get a preview of what will be provisioned run:

terraform plan

Now it's time to provision the resources by running:

terraform apply

Once you confirmed the provisioning with yes all the resources will be created using the credentials in your environment variables.

You should also see the new service that was created in your Twilio Console.

Deploy your code

Now that the resources have been provisioned we can deploy our code. For this we first have to retrieve the relevant SIDs from Terraform. We can use terraform output for this.

We'll store them in temporary variables using:

SERVERLESS_SID=$(terraform output -raw serverlessService)
ENVIRONMENT_SID=$(terraform output -raw serverlessEnvironment)

With this we can trigger the deployment by passing in the relevant SIDs using --service-sid and --environment:

twilio serverless:deploy \
    --service-sid "$SERVERLESS_SID" \
    --environment "$ENVIRONMENT_SID" \
    --username $TWILIO_API_KEY
    --password $TWILIO_API_SECRET

This will kick of the same deployment that you are used to but it will explicitly deploy to the Service and Environment you have passed in.

Create more resources with Terraform

As mentioned before we can use Terraform to provision a variety of Twilio resources. For example you can use it to provision a Verify service by adding:

resource "twilio_verify_services_v2" "service" {
  friendly_name = "Verify Demo"
}

output "verifyServiceSid" {
  value     = twilio_verify_services_v2.service.sid
  sensitive = true
}

If you want to pass the Service SID to your Twilio Functions deployment you can do this using the Serverless Toolkit by running:

VERIFY_SERVICE_SID=$(terraform output -raw verifyServiceSid)
twilio serverless:env:set --key VERIFY_SERVICE_SID --value "$VERIFY_SERVICE_SID"

Check out more examples on the Twilio Terraform Provider GitHub.

Use a Continuous Delivery system

With all of this set up we can actually move this into a Continuous Integration / Continuous Delivery (CI/CD) system. How exactly you use Terraform depends on your the system you are using. Make sure to consult the Terraform docs for more information. You will also have to use some backend to store your Terraform state. To learn more on how to use the Serverless Toolkit from CI/CD environments check out our dedicated guide for it.

Rate this page:

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Stack Overflow Collective or browsing the Twilio tag on Stack Overflow.

Loading Code Sample...
        
        
        

        Thank you for your feedback!

        Please select the reason(s) for your feedback. The additional information you provide helps us improve our documentation:

        Sending your feedback...
        🎉 Thank you for your feedback!
        Something went wrong. Please try again.

        Thanks for your feedback!

        thanks-feedback-gif