Serializing and deploying space level resources
Octopus is conceptually split into two types of resources:
- Space level resources such as environments, feeds, accounts, lifecycles, certificates, workers, worker pools, and variable sets
- Project level resources such as the projects themselves, the project deployment process, runbooks, project variables, and project triggers
Space level resources are shared by projects and do not tend to change as frequently as projects.
Managed, or downstream, spaces (i.e. spaces with centrally managed resources) are implemented by deploying space and project level resources as separate processes:
- Space level resources are deployed first to support one or more projects
- Project level resources are deployed second referencing the space level resources
Space level resources are best managed with the Octopus Terraform provider.
Config-as-code only supports persisting a subset of project settings in a Git repository, and can not be used to define space level resources.
Space level resources can be defined in a Terraform module in two ways:
- Write the module by hand
- Serialize an existing space to a Terraform module with octoterra
Writing by hand
You can write a Terraform module that manages Octopus space level resources by hand if you wish to do so. The Terraform provider source code contains a suite of tests that can be used as examples for creating your own Terraform module.
Serializing with octoterra
The second approach is to create a management, or upstream, space using the Octopus UI and then export the space to a Terraform module with octoterra. This allows you to rely on the UI for convenience and validation and then serialize the space to a Terraform module.
You are free to edit the Terraform module created by octoterra as you see fit once it is exported.
Octopus includes a number of steps to help you serialize a space with octoterra and apply the module to a new space.
The steps documented below are best run on the Hosted Ubuntu
worker pools for Octopus Cloud customers.
Exporting space level resources
The following process serializes a space to a Terraform module:
- Create a project with a runbook called
__ 1. Serialize Space
. Runbooks with the prefix__
(two underscores and a space) are automatically excluded when exporting projects, so this is a pattern we use to indicate runbooks that are involved in serializing Octopus resources but are not to be included in the exported module. - Add the
Octopus - Serialize Space to Terraform
step from the community step template library.- Set the
Terraform Backend
field to the backend configured in the exported module. The step defaults tos3
, which uses an S3 bucket to store Terraform state. However, any backend provider can be defined here. - Set the
Octopus Server URL
field to the URL of the Octopus server to export a space from. The default value of#{Octopus.Web.ServerUri}
references the URL of the current Octopus instance. - Set the
Octopus API Key
field to the API key used when accessing the instance defined in theOctopus Server URL
field. - Set the
Octopus Space ID
field to the ID of the space to be exported. The default value of#{Octopus.Space.Id}
references the current space. - Set the
Octopus Upload Space ID
field to the ID of another space to upload the resulting Terraform module zip file to the built-in feed of that space. Leave this field blank to upload the zip file to the built-in feed of the current space. - Set the
Ignored Variables Sets
field to a comma separated list of variable sets to exclude from the Terraform module. Typically, this field is used when the values of the previous fields were sourced from a variable set that should not be exported. - Set the
Ignored Tenants
field to a comma separated list of tenants to exclude from the Terraform module. Typically, this is used to exclude tenants that are used to run this export step but do not make sense to reimport in a new space. - Tick the
Ignore All Targets
to exclude all targets from the exported Terraform module. Targets are typically space specific and should not be shared between spaces. - Tick the
Default Secrets to Dummy Values
to set all secret values, such as account and feed passwords, to dummy values. This setting allows you to apply the resulting Terraform module without specifying any secret values, after which you can manually update the values in the new space as needed. If this value is not ticked, the resulting Terraform module exposes Terraform variables for every Octopus secret, and you must supply the secret values when applying the Terraform module. - Set the
Ignore Tenants with Tag
field to a tag, in the formattag-set/tag-name
, which when applied to a tenant results in the tenant being excluded from the export. This is similar to theIgnored Tenants
field, but allows you to ignore tenants based on their tags rather than by name.
- Set the
Executing the runbook will:
- Export space level resources (i.e. everything but projects) to a Terraform module
- Zip the resulting Terraform module files into a package named after the current space
- Upload the zip file to the built-in feed of the current space, or the space defined in the
Octopus Upload Space ID
field
The package has two directories:
space_creation
, which contains a Terraform module to create a new spacespace_population
, which contains a Terraform module to populate a space with the exported resources.
Many of the exported resources expose values, like resource names, as Terraform variables with default values. You can override these variables when applying the module to customize the resources, or leave the Terraform variables with their default value to recreate the resources with their original names.
Importing space level resources
The following process creates and populates a space with the Terraform module exported using the process documented in the previous section:
- Create a project with a runbook called
__ 2. Deploy Space
. Runbooks with the prefix__
(two underscores and a space) are automatically excluded when exporting projects, so this is a pattern we use to indicate runbooks that are involved in serializing Octopus resources but are not to be included in the exported module. - Add one of the steps called
Octopus - Create Octoterra Space
from the community step template library. Each step indicates the Terraform backend it supports. For example, theOctopus - Create Octoterra Space (S3 Backend)
step configures a S3 Terraform backend.- Configure the step to run on a worker with a recent version of Terraform installed, or use the
octopuslabs/terraform-workertools
container image. - Set the
Octopus Space Name
field to the name of the new space. The default value of#{Octopus.Deployment.Tenant.Name}
assumes the step is run against a tenant, and the name of the tenant is the name of the new space. - Set the
Octopus Space Managers
field to a comma separated list of team IDs to assign as space managers. Built-in teams likeOctopus Administrator
have named IDs liketeams-administrators
. Custom teams have IDs likeTeams-15
. - Set the
Terraform Workspace
field to a workspace that tracks the new space. The default value of#{OctoterraApply.Octopus.Space.NewName | Replace "[^A-Za-z0-9]" "_"}
creates a workspace name based on the space name with all non-alphanumeric characters replaced with an underscore. Leave the default value unless you have a specific reason to change it. - Select the package created by the export process in the previous section in the
Terraform Module Package
field. The package name is the same as the exported space name, with all non-alphanumeric characters replaced with an underscore. - Set the
Octopus Server URL
field to the URL of the Octopus server to create the new space in. The default value of#{Octopus.Web.ServerUri}
references the URL of the current Octopus instance. - Set the
Octopus API Key
field to the API key used when accessing the instance defined in theOctopus Server URL
field. - Set the
Terraform Additional Apply Params
field to a list of additional arguments to pass to theterraform apply
command. This field is typically used to define the value of any Terraform variables. However, there are no variables that need to be defined when creating a space, so leave this field blank unless you have a specific reason to pass an argument to Terraform. - Set the
Terraform Additional Init Params
field to a list of additional arguments to pass to theterraform init
command. Leave this field blank unless you have a specific reason to pass an argument to Terraform. - Each
Octopus - Create Octoterra Space
step exposes values relating to their specific Terraform backend that must be configured. For example, theOctopus - Create Octoterra Space (S3 Backend)
step exposes fields to configure the S3 bucket, key, and region where the Terraform state is saved. Other steps have similar fields.
- Configure the step to run on a worker with a recent version of Terraform installed, or use the
- Add one of the steps called
Octopus - Populate Octoterra Space
from the community step template library. Each step indicates the Terraform backend it supports. For example, theOctopus - Populate Octoterra Space (S3 Backend)
step configures a S3 Terraform backend.- Configure the step to run on a worker with a recent version of Terraform installed, or use the
octopuslabs/terraform-workertools
container image. - Set the
Terraform Workspace
field to a workspace that tracks the new space. The default value of#{OctoterraApply.Octopus.SpaceID}
creates a workspace name based on the ID of the space that is being populated. Leave the default value unless you have a specific reason to change it. - Select the package created by the export process in the previous section in the
Terraform Module Package
field. The package name is the same as the exported space name, with all non-alphanumeric characters replaced with an underscore. - Set the
Octopus Server URL
field to the URL of the Octopus server to create the new space in. The default value of#{Octopus.Web.ServerUri}
references the URL of the current Octopus instance. - Set the
Octopus API Key
field to the API key used when accessing the instance defined in theOctopus Server URL
field. - Set the
Octopus Space ID
field to the ID of the space created by the previous step. The ID is an output variable that can be access with an octostache template like#{Octopus.Action[Octopus - Create Octoterra Space (S3 Backend)].Output.TerraformValueOutputs[octopus_space_id]}
. Note that the name of the previous step may need to be changed fromOctopus - Create Octoterra Space (S3 Backend)
if your step has a different name. - Set the
Terraform Additional Apply Params
field to a list of additional arguments to pass to theterraform apply
command. This field is typically used to define the value of secrets such as account or feed passwords e.g.-var=account_aws_account=TheAwsSecretKey
. - Set the
Terraform Additional Init Params
field to a list of additional arguments to pass to theterraform init
command. Leave this field blank unless you have a specific reason to pass an argument to Terraform. - Each
Octopus - Populate Octoterra Space
step exposes values relating to their specific Terraform backend that must be configured. For example, theOctopus - Populate Octoterra Space (S3 Backend)
step exposes fields to configure the S3 bucket, key, and region where the Terraform state is saved. Other steps have similar fields.
- Configure the step to run on a worker with a recent version of Terraform installed, or use the
Executing the runbook will create a new space and populate it with the space level resources defined in the Terraform module zip file created in the previous section.
Typically, downstream spaces are represented by tenants in the upstream space. For example, the space called Acme
is represented by a tenant wth the same name. Configuring the __ 2. Deploy Space
runbook to run against a tenant allows you to manage the creation and updates of downstream spaces with a typical tenant based deployment process. This is why the Octopus - Create Octoterra Space
step defaults the Octopus Space Name
field to the name of the current tenant.
If you ticked the Default Secrets to Dummy Values
option when exporting a space, all resources with secret values like accounts, feeds, certificates, variables sets, and git credentials will have dummy values set for the passwords or secret values. You must manually update these values after the new space has been created to allow deployments and runbooks to work correctly.
Updating space level resources
The runbooks __ 1. Serialize Space
and __ 2. Deploy Space
can be run as needed to serialize any changes to the upstream space and deploy the changes to downstream spaces. The Terraform module zip file pushed to the built-in feed is versioned with a unique value each time, so you can also revert changes by redeploying an older package. In this way you can use Octopus to deploy Octopus spaces using the same processes you use Octopus to deploy applications.
Help us continuously improve
Please let us know if you have any feedback about this page.
Page updated on Thursday, November 30, 2023