Reference HashiCorp Terraform State Outputs

It is a popular use case to use Terraform and Serverless Framework in conjunction, where Terraform is used to provision shared infrastructure while Serverless Framework is used to provision app-specific infrastructure. For example, you might have some infrastructure like an RDS Database or an SQS Queue that is used by your Serverless Framework based service, as well as other apps/services at your company. In this case, the RDS Database and SQS Queue may be provisioned with Terraform, while your app provisions Lambda functions and event configurations using Serverless Framework.

In this case, it is helpful to access the Terraform State Outputs from within your serverless.yml file so at deployment time it can look up details about the shared infrastructure, like the RDS connection string, or SQS Queue ARN.

The Terraform Variable Resolver supports getting the Terraform State Outputs s3, remote,cloud, or http backend.

Getting Terraform Outputs from Remote Backends

Terraform supports using a remote backend to store the state of the infrastructure. The state can be stored in a number of support remote backends like AWS S3, Terraform HCP, or HTTP.

The Terraform output variable resolver in Serverless Framework V.4 only supports the S3, Remote, and HTTP backends, therefore one of these four options must be used.

In all the examples we'll assume a Terraform configuration that creates a DynamoDB table and outputs the ARN of the table in the users_table_arn output.

# Configures the Terraform backend to store state in an S3 bucket
terraform {
  # cloud {} - compatible with remote backend
  # backend "s3" { }
  # backend "remote" { }
  # backend "http" { }
}

# ...

output "users_table_arn" {
  description = "The ARN of the Users DynamoDB table"
  value       = aws_dynamodb_table.users_table.arn
}

To access this output in the serverless.yml file, you can use the ${terraform} variable resolver.

${terraform:outputs:users_table_arn}

Configuring the s3 Backend

To use this resolver, you must declare the resolver with type: terraform and backend: s3 under stages.<stage>.resolvers.<key> in the serverless.yml.

stages:
  default:
    resolvers:
      terraform:
        type: terraform
        backend: s3
        bucket: terraform-state
        key: users-table/terraform.tfstate

In the terraform resolver supports the following configuration if the backend is s3:

  • bucket - The name of the S3 bucket where the Terraform State Outputs are stored.
  • key - The key of the Terraform State Outputs file in the S3 bucket.
  • region - (optional) - The region of the S3 bucket where the Terraform State Outputs are stored. This is optional and if not provided the default region will be used.

The resolver uses the current AWS account credentials, the same ones being used for the deployment, so the S3 bucket containing the state must reside in that account. Support for pointing to a secondary AWS account is coming soon.

The bucket and key properties match the values in the terraform backend configuration in the Terraform configuration file.

Configuring the remote or cloud Backend

To use this resolver, you must declare the resolver with type: terraform and backend: remote under stages.<stage>.resolvers.<key> in the serverless.yml.

stages:
  default:
    resolvers:
      terraform:
        type: terraform
        backend: remote
        organization: my-org
        workspace: my-workspace

In the terraform resolver supports the following configuration if the backend is remote:

  • organization - (optional) The name of the Terraform Cloud organization where the Terraform State Outputs are stored.
  • workspace - (optional) The name of the Terraform Cloud workspace where the Terraform State Outputs are stored.
  • workspaceId - (optional) The ID of the Terraform Cloud workspace where the Terraform State Outputs are stored.
  • token - (optional) The Terraform Cloud API token to use to access the Terraform State Outputs. This is required if the Terraform Cloud workspace is private.
  • hostname - (optional) The hostname of the Terraform Cloud API. This is optional and if not provided the default hostname will be used.

While organization, workspace, and workspaceId are optional, you must provide either the organization & workspace, or the workspaceId.

If no token is provided then the resolver will try to get the token from the TF_CLOUD_TOKEN environment variable, or from the ~/.terraform.d/credentials.tfrc.json file.

Configuring the http Backend

To use this resolver, you must declare the resolver with type: terraform and backend: http under stages.<stage>.resolvers.<key> in the serverless.yml.

stages:
  default:
    resolvers:
      terraform:
        type: terraform
        backend: http

In the terraform resolver supports the following configuration if the backend is remote:

  • address - (optional) The HTTP address of the Terraform http backend where the Terraform State Outputs are stored.
  • username - (optional) The username to use to access the Terraform State Outputs.
  • password - (optional) The password to use to access the Terraform State Outputs.

While, address, username, and password are optional, you must provide an address either via the address configuration or the TF_HTTP_ADDRESS environment variable.

Resolvers in Serverless Framework V.4

The Terraform Variable Resolver is a new feature in Serverless Framework V.4. It is part of a new feature called Variable Resolvers that allows you to reference external data sources in your serverless.yml file. The Terraform Variable Resolver is one of the first resolvers available, with more resolvers planned for the future.

Since Variable Resolvers are a new concept in Serverless Framework V.4 it is worth mentioning that the variable reference, ${terraform:outputs} is based on the keys declared in the resolvers section of the serverless.yml

For example, we can change the terraform: key to infra: like this:

stages:
  default:
    resolvers:
      infra: # Previously this was "terraform"
        type: terraform

With this change, the variable reference must be updated from ${terraform:outputs:users_table_name} to ${infra:outputs:users_table_name}.

As you can see, the <key> in the stages.<stage>.resolvers.<key> path is used to reference the resolver in the variable reference, ${<key>:outputs:users_table_name}.

This also means you can have multiple resolvers in the serverless.yml file, each with a unique key and configuration, and reference them in the serverless.yml file using their unique keys.

Edit this page

Reference HashiCorp Terraform State Outputs

It is a popular use case to use Terraform and Serverless Framework in conjunction, where Terraform is used to provision shared infrastructure while Serverless Framework is used to provision app-specific infrastructure. For example, you might have some infrastructure like an RDS Database or an SQS Queue that is used by your Serverless Framework based service, as well as other apps/services at your company. In this case, the RDS Database and SQS Queue may be provisioned with Terraform, while your app provisions Lambda functions and event configurations using Serverless Framework.

In this case, it is helpful to access the Terraform State Outputs from within your serverless.yml file so at deployment time it can look up details about the shared infrastructure, like the RDS connection string, or SQS Queue ARN.

The Terraform Variable Resolver supports getting the Terraform State Outputs s3, remote,cloud, or http backend.

Getting Terraform Outputs from Remote Backends

Terraform supports using a remote backend to store the state of the infrastructure. The state can be stored in a number of support remote backends like AWS S3, Terraform HCP, or HTTP.

The Terraform output variable resolver in Serverless Framework V.4 only supports the S3, Remote, and HTTP backends, therefore one of these four options must be used.

In all the examples we'll assume a Terraform configuration that creates a DynamoDB table and outputs the ARN of the table in the users_table_arn output.

# Configures the Terraform backend to store state in an S3 bucket
terraform {
  # cloud {} - compatible with remote backend
  # backend "s3" { }
  # backend "remote" { }
  # backend "http" { }
}

# ...

output "users_table_arn" {
  description = "The ARN of the Users DynamoDB table"
  value       = aws_dynamodb_table.users_table.arn
}

To access this output in the serverless.yml file, you can use the ${terraform} variable resolver.

${terraform:outputs:users_table_arn}

Configuring the s3 Backend

To use this resolver, you must declare the resolver with type: terraform and backend: s3 under stages.<stage>.resolvers.<key> in the serverless.yml.

stages:
  default:
    resolvers:
      terraform:
        type: terraform
        backend: s3
        bucket: terraform-state
        key: users-table/terraform.tfstate

In the terraform resolver supports the following configuration if the backend is s3:

  • bucket - The name of the S3 bucket where the Terraform State Outputs are stored.
  • key - The key of the Terraform State Outputs file in the S3 bucket.
  • region - (optional) - The region of the S3 bucket where the Terraform State Outputs are stored. This is optional and if not provided the default region will be used.

The resolver uses the current AWS account credentials, the same ones being used for the deployment, so the S3 bucket containing the state must reside in that account. Support for pointing to a secondary AWS account is coming soon.

The bucket and key properties match the values in the terraform backend configuration in the Terraform configuration file.

Configuring the remote or cloud Backend

To use this resolver, you must declare the resolver with type: terraform and backend: remote under stages.<stage>.resolvers.<key> in the serverless.yml.

stages:
  default:
    resolvers:
      terraform:
        type: terraform
        backend: remote
        organization: my-org
        workspace: my-workspace

In the terraform resolver supports the following configuration if the backend is remote:

  • organization - (optional) The name of the Terraform Cloud organization where the Terraform State Outputs are stored.
  • workspace - (optional) The name of the Terraform Cloud workspace where the Terraform State Outputs are stored.
  • workspaceId - (optional) The ID of the Terraform Cloud workspace where the Terraform State Outputs are stored.
  • token - (optional) The Terraform Cloud API token to use to access the Terraform State Outputs. This is required if the Terraform Cloud workspace is private.
  • hostname - (optional) The hostname of the Terraform Cloud API. This is optional and if not provided the default hostname will be used.

While organization, workspace, and workspaceId are optional, you must provide either the organization & workspace, or the workspaceId.

If no token is provided then the resolver will try to get the token from the TF_CLOUD_TOKEN environment variable, or from the ~/.terraform.d/credentials.tfrc.json file.

Configuring the http Backend

To use this resolver, you must declare the resolver with type: terraform and backend: http under stages.<stage>.resolvers.<key> in the serverless.yml.

stages:
  default:
    resolvers:
      terraform:
        type: terraform
        backend: http

In the terraform resolver supports the following configuration if the backend is remote:

  • address - (optional) The HTTP address of the Terraform http backend where the Terraform State Outputs are stored.
  • username - (optional) The username to use to access the Terraform State Outputs.
  • password - (optional) The password to use to access the Terraform State Outputs.

While, address, username, and password are optional, you must provide an address either via the address configuration or the TF_HTTP_ADDRESS environment variable.

Resolvers in Serverless Framework V.4

The Terraform Variable Resolver is a new feature in Serverless Framework V.4. It is part of a new feature called Variable Resolvers that allows you to reference external data sources in your serverless.yml file. The Terraform Variable Resolver is one of the first resolvers available, with more resolvers planned for the future.

Since Variable Resolvers are a new concept in Serverless Framework V.4 it is worth mentioning that the variable reference, ${terraform:outputs} is based on the keys declared in the resolvers section of the serverless.yml

For example, we can change the terraform: key to infra: like this:

stages:
  default:
    resolvers:
      infra: # Previously this was "terraform"
        type: terraform

With this change, the variable reference must be updated from ${terraform:outputs:users_table_name} to ${infra:outputs:users_table_name}.

As you can see, the <key> in the stages.<stage>.resolvers.<key> path is used to reference the resolver in the variable reference, ${<key>:outputs:users_table_name}.

This also means you can have multiple resolvers in the serverless.yml file, each with a unique key and configuration, and reference them in the serverless.yml file using their unique keys.