Skip to main content
Version: 1.0.0

Operating Your Terraform Blueprints with Zeet

Terraform is a powerful declarative engine for your cloud infrastructure. With great power comes great responsibility: why not let Zeet take some of that responsiblity off your plate?

Requirements for Terraform Modules (!)

ATTENTION: GCP Provider and GCS Backend Support is currently under development

Zeet can operate your terraform modules, but there's a few restrictions to keep in mind:

  • Modules can only use a single cloud provider, either AWS or GCP
    • this means you can use 1 AWS account or 1 GCP account within a module
    • the module must only rely on the "default" provider
  • Only the AWS S3 Bucket and GCP GCS Bucket state backends are supported

Deploying Your Terraform Module via GraphQL

The first step to deploying your Terraform module is to declare your module as a Zeet Blueprint:

Define Your Blueprint

First, issue a createBlueprint mutation request.

createBlueprint(input: 
{
userID: "uuid-abc-123",
slug: "my-blueprint",
displayName: "My Team's Great Blueprint",
published: true,
type: TERRAFORM,
configuration: {
terraform: {
githubSource: "github.com/example-co/example-repo",
}
},
variables: [
{name: "my_string_input", type: STRING, required: true},
{name: "optional_boolean", type: BOOLEAN, required: false}
]
}
) {...}

This mutation requires the following parameters:

  • userID: your team's user ID
  • slug: a short url-safe string used to programmatically reference your blueprint
  • displayName: a human-readable name for your blueprint (can include spaces and special characters)
  • published: whether the blueprint should be visible to your team members
  • type: the type of blueprint you are defining, in this case, it should be TERRAFORM
  • configuration: the type-specific configuration for your blueprint (see below)
  • variables: the variables accepted by each instance of the blueprint (see below)

Configuration

For a Terraform module, we'll need to declare the source of the module. Zeet supports two sources:

  • githubSource: a module defined in github, see the Terraform Docs
    • if it's in a private github repository, you can include a gitIntegration that will supply authentication for the repository.
  • registrySource: a module served by a Terraform Registry
    • registrySource supports the additional moduleVersionConstraint argument: see the Terraform Docs

Variables

Terraform modules support Input Variables and Zeet helps you manage those variables.

When defining your Blueprint, you will declare a variable for each Terraform Input Variable you wish to accept (Terraform variables with defaults don't need to be declared in Zeet, you can omit them in this step if you wish):

  • The Zeet Variable name must exactly match the Terraform Input Variable name
  • The type must match Terraform Input Variable type
    • use the JSON type in Zeet for Terraform maps and arrays
  • The required parameter for each variable should match the expected behavior in Terraform: if the Terraform Input Variable has a default, you can mark it optional in Zeet (or omit it from this mutation entirely).

Create Your Project

Now that you've defined the Blueprint in Zeet, you and your teammates can instantiate any number of Projects using the module.

createProjectV3(input: {
blueprintID: $blueprintID,
projectName: "api-server",
environmentName: "production",
name: "terraform-module-deployment-abc",
variables: [
{
variableSpecID: "variable-uuid-1",
value: "my-variable-value"
}
],
terraformConfiguration: {
stateBackend: {
s3Bucket: {
awsAccountID: "uuid-account-xyz",
region: "us-region-1",
bucketName: "example-co-terraform-state-bucket"
}
}
}
}
) {id, name, blueprintID}

For the createProjectV3 mutation, you'll need to supply:

  • The blueprintID (as returned by the createBlueprint call)
  • A projectName or projectID (now called groups), and environmentName or environmentID (now called sub-groups): to organize your Project into a group and sub-group
  • A name, to identify your Project
  • The values for each variable
    • You'll need to specify at least the required variables (as defined by the Blueprint)
  • The terraformConfiguration for this module instance:
    • For a Terraform module, this will be the Terraform state backend, i.e. an S3 bucket name and region, and the AWS Account to own the bucket (connected via Zeet)
      • Zeet will create the bucket (S3 or GCS) if it does not already exist

Plan and Apply your Terraform Module

Once your Project exists, you can now manage its lifecycle completely via Zeet. We do this using the Terraform Blueprint Driver.

Terraform Plan

To invoke the Blueprint Driver, we use the executeBlueprintDriverAction mutation:

executeBlueprintDriverAction(input: {
projectID: "uuid-resource-123",
action: PLAN,
driver: TERRAFORM,
parameters: {
cloudProvider: {
awsAccountID: "aws-provider-zeet-uuid",
region: "us-region-9"
}
}
}) {
__typename
... on BlueprintDriverActionResult {
execution {
id,
jobRun {
id,
},
}
}
}
  • Include the projectID (from the previous step)
  • We will use the PLAN action
  • Using the TERRAFORM driver
  • And in the parameters, we specify the cloud provider to inject into our module:

The PLAN action will return a "job" instance, which is executing your Terraform Plan asynchronously, and you can follow the progress of that job accordingly.

Terraform Apply

Once you've generated a Terraform Plan, you can then Apply that plan, again using the executeBlueprintDriverAction mutation:

executeBlueprintDriverAction(input: {
projectID: "uuid-resource-123",
action: APPLY,
driver: TERRAFORM,
parameters: {
planID: "actionResult-execution-id-from-previous-step"
}
}) {
... on BlueprintDriverActionResult {
execution {
id
jobRun {
id
}
}
}
}
  • Again specify the projectID
  • Use the APPLY action
  • Again using the TERRAFORM driver
  • The parameters for the APPLY action only requires the planID
    • The planID is the execution id from the previous step: BlueprintDriverActionResult.execution.id

This will run terraform apply using the exact plan that was generated by the previous step.