Skip to content

Introduction to Terraform on Rumble Cloud

Overview

This tutorial provides a brief overview of Terraform and an example tutorial on how to use Terraform on Rumble Cloud to configure and launch a two-server setup.

About Terraform

What is Terraform?

Terraform is an open-source Infrastructure as Code (IaC) tool developed by HashiCorp, designed to enable users to define and provision data center infrastructure using a high-level configuration language. Terraform enables developers and operations teams to codify their infrastructure requirements into declarative configuration files, which can then be versioned, shared, and reused. You can use Terraform to manage a wide array of service providers, including cloud platforms such as Rumble Cloud, as well as other services like GitHub, Kubernetes, and various SaaS offerings.

How does Terraform work?

Terraform uses a human-readable language known as HashiCorp Configuration Language (HCL). You can use HCL to define their infrastructure in terms of resources, modules, and dependencies. This declarative approach means that users specify the desired state of their infrastructure, and Terraform takes on the responsibility of figuring out how to achieve that state. It does so by creating an execution plan that outlines the changes it will make to reach the desired configuration, which you can review and approve before any changes are applied.

What file format do Terraform configuration files use?

In a typical Terraform workflow, the configuration is usually split into multiple .tf files to organize the code better and to separate concerns. Here’s a list of the typical .tf files you might find in a Terraform project, along with their purposes:

  • main.tf: This file is often the main entry point of your Terraform configuration. It can include resource definitions, provider configurations, and module calls.
  • variables.tf: This file defines all the input variables for your configuration. Variables can make your Terraform configuration more flexible and reusable.
  • outputs.tf: This file defines the outputs of your Terraform configuration. Outputs can be used to provide information after the infrastructure is created, such as instance IP addresses or resource IDs.
  • provider.tf: This file is specifically used to configure the provider or providers that Terraform will use. It can be useful to keep this separate for clarity.
  • data.tf: This file is used to define data sources. Data sources allow you to fetch information from outside Terraform or from existing resources.
  • terraform.tfvars: This file contains the values for the input variables defined in variables.tf. This allows you to set and change variable values without modifying the configuration files.
  • backend.tf: This file is used to configure the backend for storing the Terraform state. This is often used when working with remote backends such as Rumble Cloud S3 object storage.
  • locals.tf: This file is used to define local values, which are temporary variables that can simplify the configuration and avoid repetition.
  • modules.tf: This file is used to include and configure reusable modules. Modules encapsulate groups of resources and can be shared and versioned.
  • ec2.tf, vpc.tf, etc.: These are additional files named after specific resources or components. This practice helps organize the configuration by separating different parts of the infrastructure into different files.

What are Terraform blocks?

In a Terraform configuration file, blocks are the building units that define various aspects of the infrastructure. Each block serves a specific purpose, such as declaring providers, defining resources, specifying data sources, setting variable values, and more.

What are some of Terraforms key features and benefits?

One of Terraform's key features is its state management system. Terraform maintains a state file that acts as a single source of truth for your infrastructure, keeping track of the current state of your resources. This state file is crucial for planning and executing changes, as it enables Terraform to determine what needs to be created, updated, or destroyed to achieve the desired state. By leveraging this state file, Terraform can efficiently manage complex infrastructure environments and ensure consistency across deployments.

Another benefit of Terraform is its extensibility through modules and provider plugins. Modules are reusable configurations that can encapsulate common infrastructure patterns, making it easy to share and standardize infrastructure definitions across teams and projects. Provider plugins enable Terraform to interact with a wide range of APIs and services, allowing it to manage resources across various cloud providers and third-party services seamlessly.

How do I use Terraform with Rumble Cloud?

  1. Install Terraform on your local machine. For more information, see Terraform documentation.
  2. Create a Terraform provider configuration file to configure your Rumble Cloud OpenStack setup.
  3. Create additional resource files to specify your cloud resources, such as images, security groups, network components, etc.
  4. Initialize Terraform.
    • Navigate to the directory containing your Terraform configuration files and run the terraform init command. This command initializes the directory, downloads the necessary provider plugins, and prepares the backend.
    • Run the following command: terraform init.
  5. Optionally run the plan command. This command creates an execution plan, showing what actions Terraform will take to achieve the desired state defined in your configuration files.
    • Run the following command: terraform plan.
  6. To apply the planned changes and create the resources in your Rumble Cloud project, run the terraform apply command. You will be prompted to confirm before Terraform makes any changes.
    • Run the following command: terraform apply.
  7. You can use the plan and apply commands to iterate and make changes to your Terraform configuration.
  8. You can use the destroy command to tear down all cloud resources managed and executed by your Terraform configuration.
    • Run the following command: terraform destroy to destroy all resources defined in your configuration files.

You can use the Rumble Cloud application credential file to generate credentials that can be used in your Terraform workflow. Please see the Terraform provider example below for more information.

See also:

Set up a Terraform provider

A Terraform provider is a plugin that enables Terraform to interact with various external APIs and services. Providers manage and provision resources across a wide range of platforms and services, from cloud infrastructure and software-as-a-service (SaaS) applications to configuration management tools and monitoring systems.

Here are the key aspects of a Terraform provider:

  • Providers define the types of resources they can manage and the corresponding actions (create, read, update, delete) that can be performed on these resources.
  • Providers require configuration details to authenticate and interact with the target service.
  • Providers help maintain the state of resources they manage by interacting with the Terraform state file.
  • Providers are modular, meaning they can be added, removed, or updated independently of the core Terraform tool.
  • HashiCorp maintains official providers for popular services and the Terraform community contributes to a growing ecosystem of third-party providers.

Pre-requisites

  • Familiarity with Terraform
  • Terraform is installed locally
  • Familiarity with using cloud providers and tools
  • Familiarity with using Rumble Cloud application credentials
  • Familiarity with the Rumble Cloud console and OpenStack CLI
  • Familiarity with configuration files and their usage

See also:

Example provider configuration

The HCL file (named main.tf) sets up the Terraform environment to interact with an OpenStack cloud infrastructure using specified credentials. It doesn't define any resources to be managed yet; it only sets up the provider configuration necessary for Terraform to communicate with the OpenStack API.

Terraform
# Specifying the OpenStack provider

terraform {
  required_providers {
    openstack = {
      source = "terraform-provider-openstack/openstack"
      version = "2.0.0"
    }
  }
}

provider "openstack" {
  auth_url                      = "https://keystone.rumble.cloud/"
  application_credential_id     = "00000EXAMPLE000000000000"
  application_credential_secret = "EXAMPLESECRETKEY"
}

The HCL configuration contains two blocks:

  • Provider specification: defines that the OpenStack provider will be used, sourcing it from the Terraform registry and specifying the version 2.0.0.
  • Authentication configuration: configures the necessary authentication details (auth URL, credential ID, and secret) required to connect to the OpenStack environment specified by the auth_url.

You'll be able to access your credentials by generating a application credential file using the Rumble Cloud console.

The terraform block specifies that the Terraform configuration requires the OpenStack provider:

  • source = "terraform-provider-openstack/openstack" indicates the source of the provider plugin.
  • version = "2.0.0" specifies the version of the OpenStack provider to use.

The provider block configures the OpenStack provider with the necessary authentication details:

  • auth_url = "https://keystone.rumble.cloud/" specifies the authentication URL for the OpenStack Keystone service.
  • application_credential_id = "00000EXAMPLE000000000000" provides the application credential ID used for authentication.
  • application_credential_secret = "EXAMPLESECRETKEY" provides the secret key associated with the application credential.

In this example, instead of defining the block for specific credentials, you can use environment variables. (For help with setting up application credentials, please see the article,Generate app credentials.)

Environment variables:

  • OS_AUTH_URL which replaces the auth_url value in the provider config.
  • OS_APPLICATION_CREDENTIAL_ID which replaces the application_credential_id value in the provider config.
  • OS_APPLICATION_CREDENTIAL_SECRET which replaces the application_credential_secret value in the provider config.

Notes about using environment variables:

  • The environment variables are the last effort to be loaded; if a specific credential is in the provider configuration, the environment variables will be ignored.
  • Special care should be taken to not use user_name, user_id, tenant_id, tenant_name, password, etc.
  • For advanced users, a token can be used, using the token field or the OS_AUTH_TOKEN environment variable. While this authentication method works without issue, it is not documented by Rumble, and you should refer to the official documentation for the OpenStack Terraform Provider.

Using explicitly defined credentials is also an option and is as easy as putting those credentials into the provider configuration block. However, it can also be ran without those explicit configurations using environment variables like this:

Bash
export OS_AUTH_URL="https://keystone.rumble.cloud/"
export OS_APPLICATION_CREDENTIAL_ID="00000EXAMPLE000000000000"
export OS_APPLICATION_CREDENTIAL_SECRET="EXAMPLESECRETKEY"

terraform init
terraform apply

Using the environment variable method, allows you to omit all configuration and use an empty provider block like this:

Text Only
provider "openstack" {}

Configure resources

Cloud resources are also defined in Terraform configuration files. In this example, you'll create config files to specify resources for:

  • data: specified in the data.tf configuration file
  • database: : specified in the database.tf configuration file
  • variables: specified in the variables.tf configuration file
  • webserver: specified in the webserver.tf configuration file

These files are used in combination with the main.tf file you previous defined.

Data resource configuration

The data.tf configuration is used to query the OpenStack environment for the most recent image with the name "Ubuntu-22.04". This data source can then be used in other parts of the Terraform configuration to reference the image. For example, you might use the resulting image ID to create instances based on this image.

Terraform
data "openstack_images_image_v2" "ubuntu" {
  name        = "Ubuntu-22.04"
  most_recent = true
}

Here's a breakdown of what the file does:

  • Data source: The data block is used to define a data source. A data source in Terraform allows you to query information that is defined outside of Terraform's management, such as existing infrastructure resources. In this case, the data source is querying for an OpenStack image.
  • Resource type: "openstack_images_image_v2" specifies that the data source is for an OpenStack image (version 2 of the API).
  • Name: The name given to this data source instance is "ubuntu".
  • Attributes:
  • name = "Ubuntu-22.04": This specifies the name of the image you are looking for. Terraform will search for images with the name "Ubuntu-22.04".
  • most_recent = true: This indicates that if there are multiple images with the name "Ubuntu-22.04", Terraform should select the most recent one.

To use this data source in creating an OpenStack compute instance, you would refer to the data.openstack_images_image_v2.ubuntu resource. This approach ensures that your instance is always created using the latest version of the specified Ubuntu image.

Database resource configuration

The database.tf file defines a Terraform configuration to create an OpenStack compute instance specifically configured to serve as a database server.

Terraform
resource "openstack_compute_instance_v2" "database" {
  name            = "database"
  flavor_name     = "m2a.large"
  key_pair        = var.keypair
  security_groups = ["default"]

  block_device {
    uuid                  = data.openstack_images_image_v2.ubuntu.id
    source_type           = "image"
    volume_size           = 32
    boot_index            = 0
    destination_type      = "volume"
    delete_on_termination = true
  }

  block_device {
    source_type           = "blank"
    destination_type      = "volume"
    volume_size           = 32
    boot_index            = 1
    delete_on_termination = true
  }

  network {
    name = var.network_name
  }
}

Here's a breakdown of what the database.tf file does:

  • Provisions an OpenStack compute instance named "database".
  • Specifies the flavor as "m2a.large" to define the instance size.
  • Attaches an SSH key pair using a variable for secure access.
  • Assigns the default security group to the instance.
  • Creates a 32 GB boot volume from a specified Ubuntu image, which will be deleted upon instance termination.
  • Adds a second 32 GB blank volume, also set to delete upon instance termination.
  • Connects the instance to a specified network using a variable.

Details on the resource block

  • resource "openstack_compute_instance_v2" "database": This block defines an OpenStack compute instance resource named "database".
  • name = "database": Sets the name of the instance to "database".
  • flavor_name = "m2a.large": Specifies the flavor (instance size/type) to use, in this case, "m2a.large".
  • key_pair = var.keypair: Uses a variable var.keypair to set the key pair for SSH access.
  • security_groups = ["default"]: Assigns the default security group to the instance.

Details on the first block device block

  • uuid = data.openstack_images_image_v2.ubuntu.id: Sets the UUID of the image to use for the boot volume, referencing an existing data source for the image.
  • source_type = "image": Indicates that the source of the block device is an image.
  • volume_size = 32: Specifies that the boot volume size is 32 GB.
  • boot_index = 0: Indicates that this is the primary boot device.
  • destination_type = "volume": Sets the destination type to volume, meaning a volume will be created.
  • delete_on_termination = true: Specifies that the volume should be deleted when the instance is terminated.

Details on the second block device block

  • source_type = "blank": Indicates that the source of this block device is blank, meaning an empty volume will be created.
  • volume_size = 32: Specifies the size of the volume to be 32 GB.
  • boot_index = 1: Indicates that this is a secondary volume (not the boot volume).
  • delete_on_termination = true: Specifies that the volume should be deleted when the instance is terminated.

Details on the network configuration block

  • name = var.network_name: Uses a variable var.network_name to set the network in which the instance will be placed.

Variables resource configuration

The variables.tffile defines two input variables: keypair and network_name. These variables allow you to parameterize your Terraform configuration, making it more flexible and reusable.

Terraform
variable "keypair" {
  type        = string
  description = "The name of the keypair to use to launch the virtual machines."
}

variable "network_name" {
  type        = string
  description = "The name of the network to launch the virtual machines in."
  default     = "PublicEphemeral"
}

Here's a breakdown of what the variables.tf file does:

  • keypair: This variable allows you to specify the name of the SSH key pair that will be used to access the virtual machines. Since it has no default value, you must provide this value when applying the configuration.
  • network_name: This variable allows you to specify the network name where the virtual machines will be launched. If you don’t provide a value, it will default to "PublicEphemeral".

Details on keypair input variable:

  • type = string: This specifies that the keypair variable should be a string.
  • description: This provides a description of the variable, explaining that it should contain the name of the SSH key pair used to launch virtual machines. This key pair allows secure SSH access to the instances.

Details on network_name input variable:

  • type = string: This specifies that the network_name variable should be a string.
  • description: This provides a description of the variable, indicating that it should contain the name of the network where the virtual machines will be launched.
  • default = "PublicEphemeral": This sets a default value for the network_name variable. If no value is provided by the user, Terraform will use "PublicEphemeral" as the network name.

Webserver resource configuration

The webserver.tffile defines a Terraform configuration to create an OpenStack compute instance specifically configured as a web server.

Terraform
resource "openstack_compute_instance_v2" "webserver" {
  name            = "webserver"
  flavor_name     = "m2a.large"
  key_pair        = var.keypair
  security_groups = ["default"]

  block_device {
    uuid                  = data.openstack_images_image_v2.ubuntu.id
    source_type           = "image"
    volume_size           = 32
    boot_index            = 0
    destination_type      = "volume"
    delete_on_termination = true
  }

  network {
    name = var.network_name
  }
}

Here's a breakdown of what the webserver.tf file does:

  • Creates an OpenStack compute instance named "webserver".
  • Specifies the flavor "m2a.large" for the instance, which defines the compute resources allocated to the virtual machine.
  • Uses a key pair (provided through the var.keypair variable) to allow SSH access to the instance.
  • Attaches the default security group to control network access.
  • Creates a 32 GB boot volume from a specified Ubuntu image. The volume is deleted when the instance is terminated.
  • Connects the instance to a specified network, the name of which is provided through the var.network_name variable.

Details on the resource definition:

  • resource "openstack_compute_instance_v2" "webserver": This block defines a resource of type openstack_compute_instance_v2, which is used to create a virtual machine instance on OpenStack. The resource is named "webserver".
  • name = "webserver": Specifies the name of the compute instance, which will be "webserver".
  • flavor_name = "m2a.large": Specifies the instance size or flavor, which in this case is "m2a.large". This determines the CPU, memory, and other hardware specifications for the instance.
  • key_pair = var.keypair: Specifies the SSH key pair to use for accessing the instance. The value is provided through a variable (var.keypair), which should be defined elsewhere in your Terraform configuration.
  • security_groups = ["default"]: Assigns the default security group to the instance, which controls network access rules (like allowing SSH, HTTP, etc.).

Details on block device configuration:

  • uuid = data.openstack_images_image_v2.ubuntu.id: Specifies the UUID of the image to use for the boot volume, referencing a data source that likely represents an Ubuntu image.
  • source_type = "image": Indicates that the source of this block device is an image.
  • volume_size = 32": Defines the size of the boot volume as 32 GB.
  • boot_index = 0": Specifies that this block device is the primary boot volume.
  • destination_type = "volume": Specifies that the image will be used to create a new volume.
  • delete_on_termination = true": Indicates that the volume should be deleted when the instance is terminated.

Details on network configuration

  • name = var.network_name: Specifies the network to which the instance will be connected. The network name is provided through a variable (var.network_name), which allows flexibility in specifying the network.