Virtual Event
Join us for the next HashiConf Digital October 12-15, 2020 Register for Free

Organize Configuration

Share Modules in the Private Module Registry

Terraform Cloud allows users to create and confidentially share infrastructure modules within an organization using the private module registry. In this guide, you will explore how to create and version modules for use in your organization. You will share and use a module in the private module registry that deploys an S3 backed webapp that you will be able to navigate to in your web browser.

To complete this guide, you will need:

»Create the repository

Fork the example repository for the webapp module.

Review the module configuration for the s3-webapp module. The repository looks similar to the directory structure below.

$ tree
.
└──learn-private-module-aws-s3-webapp
  ├── main.tf
  ├── outputs.tf
  └── variables.tf
  └── assets
      └── index.html

The variables.tf file will define your Terraform Cloud variables as inputs for the aws_bucket resource that Terraform will create. This module also contains the webapp assets as well as the aws_s3_bucket_object resource to upload your content to the S3 bucket resource.

Rename your forked repository to match the three-part naming format required for private-module-registry repositories, terraform-<PROVIDER>-<NAME>, where <NAME> can contain extra hypens. Go to the Settings tab of your forked repository. Under "Repository name" rename your repository to terraform-aws-s3-webapp.

GitHub repository settings with "rename repo" updated

»Tag a Release

Terraform Cloud modules should be semantically versioned, and pull their versioning information from repository release tags. To publish a module initially, at least one release tag must be present. Tags that don't look like version numbers are ignored. Version tags can optionally be prefixed with a v.

To tag a release, under your repository's Code tab, click on the tag icon, which says "0 releases."

GitHub create a new release tag

Click "Create a new release", and add 1.0.0 to the tag version field, and set the Release title to "First module release!".

GitHub releases versioning and publishing mechanism

Click "Publish release" to create the release.

Now that you have created and versioned your module, you need to add a VCS connection to your Terraform Cloud organization.

»Import the module

To create a Terraform module for your private module registry, navigate to the Modules header in Terraform Cloud. Choose "Add Module" from the upper right corner.

Modules header with an empty module list

Choose the GitHub(Custom) VCS provider you configured and find the name of the module repository terraform-aws-s3-webapp.

Choose the module from your VCS connection

Select the module and click the "Publish module" button.

Once you have added your module, notice the "Provision" portion. You will use these as the building blocks for your workspace configuration.

Successfully created module view

»Create a configuration that uses the module

Fork the root configuration repository. This repository will access the module you created and Terraform will use it to create infrastructure.

In a previous guide, you learned how to locally create a Terraform module, but now that your modules are stored in the cloud, your configuration will need to reflect the new location.

Your main.tf file in your root GitHub repository has the module reference to the private module you created in in Terraform Cloud. You will need to replace hashicorp-learn with your own organization name.

provider "aws" {
  region = var.region
}

module "s3-webapp" {
  source  = "app.terraform.io/hashicorp-learn/s3-webapp/aws"
  name   = var.name
  region = var.region
  prefix = var.prefix
  version = "1.0.0"
}

Modules from the private registry can be referenced using a registry source address of the form app.terraform.io/<ORGANIZATION-NAME>/terraform/<NAME>/<PROVIDER>.

In this repository, you have a variables.tf file and an outputs.tf file as well.

The variables.tf file defines the variables that are required inputs into your module. Although you will enter these manually in the Terraform Cloud web UI, it is still a good idea to have these in your root configuration so that other teammates understand the required inputs.

variable "region" {
  description = "This is the cloud hosting region where your webapp will be deployed."
}

variable "prefix" {
  description = "This is the environment your webapp will be prefixed with. dev, qa, or prod"
}

variable "name" {
  description = "Your name to attach to the webapp address"
}

Terraform Cloud uses the outputs.tf file to display your module outputs as you run them in the web UI.

output "website_endpoint" {
  value = module.s3-webapp.endpoint
}

»Create a workspace for the configuration

In Terraform Cloud, create a new workspace and choose your GitHub connection.

Terraform Cloud will display a list of your GitHub repositories. You may need to filter by name to find and choose the your root configuration repository, called learn-private-module-root.

Leave the workspace name and "Advanced options" unchanged, and click the purple "Create workspace" button to create the workspace.

Once your configuration is uploaded successfully, choose "Configure variables."

You will need to add the three Terraform variables prefix, region, and name. These variables correspond to the variables.tf file in your root module configuration and are necessary to create a unique S3 bucket name for your webapp. Add your AWS credentials as two environment variables, AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and mark them as sensitive.

New variables page, added variables

»Deploy the infrastructure

Test your deployment by queuing a plan in your Terraform Cloud UI.

Terraform Cloud UI in workspace to queue plan

The output in the Terraform Cloud UI plan is similar to the output from a Terraform CLI plan and will detail the resources each module will create. Confirm the plan.

Plan needs confirmation, confirm the plan in Terraform Cloud UI

The apply output generates the resources as they are defined in the modules. Navigate to the website_endpoint address in a browser to test your deployment.

»Destroy your deployment

In the Terraform Cloud UI for your workspace, open the "Settings" menu and choose "Destruction and Deletion". Enable destroy plans by checking the "Allow destroy plans" box here and save your settings. Now you can click the red "Queue destroy plan" button and run a destroy plan against the infrastructure you've created.

Destroy Infrastructure, radio button, destroy plan

When Terraform prompts you, enter the workspace name to verify that you want to allow this plan to run.

Enter workspace name to confirm destroy plan

You will need queue a destroy plan in the Terraform Cloud UI for your workspace, by clicking the "Queue destroy plan" button.

Plan for destroy

"Confirm & Apply" the destroy plan to clean up your deployment.

Apply destroy

»Next Steps

In this guide, you:

  1. Created and versioned a GitHub repository for use in the private module registry

  2. Imported a module into your organization's private module registry.

  3. Constructed a root module to consume modules from the private registry.

You can read more about the private module registry in the Terraform documentation

For sharing and using public modules, visit the Public Module Registry.