Enable the Terraform Integration Stage in Armory Enterprise
Overview of Terraform Integration in Spinnaker
The examples on this page describe how to configure the Terraform Integration and an artifact provider to support either GitHub or BitBucket. Note that the Terraform Integration also requires a git/repo
artifact account. For information about how to use the stage, see Using the Terraform Integration.
Armory’s Terraform Integration integrates your infrastructure-as-code Terraform workflow into your SDLC. The integration interacts with a source repository you specify to deploy your infrastructure as part of a Spinnaker pipeline.
Supported Terraform versions
Armory ships several versions of Terraform as part of the Terraform Integration feature. The Terraform binaries are verified by checksum and with Hashicorp’s GPG key before being installed into an Armory release.
When creating a Terraform Integration stage, pipeline creators select a specific available version from a list of available versions:
Note that all Terraform stages within a Pipeline that affect state must use the same Terraform version.
Requirements
- Credentials (in the form of basic auth) for the Git repository where your Terraform scripts are stored. The Terraform Integration needs access to credentials to download directories that house your Terraform templates.
- Git Repo can be configured with any of the following:
- a Personal Access Token (potentially associated with a service account). For more information, see Generating a Github Personal Access Token (PAT).
- SSH protocol in the form of an SSH key or an SSH key file
- basic auth in the form of a user and password, or a user-password file
- Git Repo can be configured with any of the following:
- A source for Terraform Input Variable Files (
tfvar
) or a backend config. You must have a separate artifact provider that can pull yourtfvar
file(s). The Terraform Integration supports the following artifact providers fortfvar
files and backend configs:- GitHub
- BitBucket
- HTTP artifact
- Dedicated external Redis instance
- Armory requires configuring a dedicated external Redis instance for production usage of the Terraform Integration. This is to ensure that you do not encounter scaling or stability issues in production. For more information Redis.
Redis
The Terraform Integration uses Redis to store Terraform logs and plans.
Note: The Terraform Integration can only be configured to use a password with the default Redis user.
To set/override the Armory Enterprise Redis settings do the following:
Operator
In SpinnakerService
manifest:
apiVersion: spinnaker.armory.io/v1alpha2
kind: SpinnakerService
metadata:
name: spinnaker
spec:
spinnakerConfig:
profiles:
terraformer:
redis:
baseUrl: "redis://spin-redis:6379"
password: "password"
kubectl -n spinnaker apply -f spinnakerservice.yml
Halyard
Edit the ~/.hal/default/profiles/terraformer-local.yml
file and add the following:
redis:
baseUrl: "redis://spin-redis:6379"
password: "password"
Then run hal deploy apply
to deploy the changes.
Generating a GitHub Personal Access Token (PAT)
Skip this section if you are using BitBucket, which requires your username and password.
Before you start, you need a GitHub Personal Access Token (PAT). The Terraform Integration authenticates itself using the PAT to interact with your GitHub repositories. You must create and configure a PAT so that the Terraform Integration can pull a directory of Terraform Templates from GitHub. Additionally, the Spinnaker GitHub artifact provider require a PAT for tfvar
files.
Make sure the PAT you create meets the following requirements:
- The token uses a distinct name and has the repo scope.
- If your GitHub organization uses Single Sign-On (SSO), enable
the SSO option for the organizations that host the Terraform template(s) and Terraform
tfvar
files.
For more information about how to generate a GitHub PAT, see Creating a Personal Access Token for the Command Line.
Configure your artifact accounts
The Terraform Integration uses the following artifact accounts:
- Git Repo - To fetch the repo housing your main Terraform files.
- GitHub, BitBucket or HTTP - Optional. To fetch single files such as var-files or backend config files.
Configure the Git Repo artifact
Spinnaker uses the Git Repo Artifact Provider to download the repo containing your main Terraform templates
If you already have a Git Repo artifact account configured in Spinnaker, skip this section.
Operator
Edit the SpinnakerService
manifest to add the following:
apiVersion: spinnaker.armory.io/v1alpha2
kind: SpinnakerService
metadata:
name: spinnaker
spec:
spinnakerConfig:
profiles:
clouddriver:
artifacts:
gitRepo:
enabled: true
accounts:
- name: gitrepo
token: <Your GitHub PAT> # GitHub personal access token
Halyard
-
Enable Git Repo as an artifact provider:
hal config artifact gitrepo enable
-
Add the Git Repo account:
hal config artifact gitrepo account add gitrepo-for-terraform --token
The command prompts you for your Git Repo PAT.
For more configuration options, see Git Repo.
Configure the Terraform Integration for GitHub (optional)
These steps describe how to configure GitHub as an artifact provider for the Terraform Integration. For information about BitBucket, see Configuring the Terraform Integration with BitBucket.
Enabling and configuring the GitHub Artifact Provider
Spinnaker uses the Github Artifact Provider to download any referenced tfvar
files.
If you already have a GitHub artifact account configured in Spinnaker, skip this section.
Note
The following examples usegithub-for-terraform
as a unique identifier for the artifact account. Replace it with your own identifier.
Operator
Edit the SpinnakerService
manifest to add the following:
apiVersion: spinnaker.armory.io/v1alpha2
kind: SpinnakerService
metadata:
name: spinnaker
spec:
spinnakerConfig:
config:
artifacts:
github:
accounts:
- name: github-for-terraform
token: <Your GitHub PAT> # GitHub personal access token # PAT GitHub token. This field supports "encrypted" field references (https://docs.armory.io/spinnaker-install-admin-guides/secrets/)
enabled: true
Halyard
-
Enable GitHub as an artifact provider:
hal config artifact github enable
-
Add the GitHub account:
hal config artifact github account add github-for-terraform --token
The command prompts you for your GitHub PAT.
Configure the Terraform Integration for BitBucket (optional)
Enabling and configuring the BitBucket Artifact Provider
Spinnaker uses the BitBucket Artifact Provider to download any referenced tfvar
files, so it must be configured with the BitBucket token to pull these files.
If you already have a BitBucket artifact account configured in Spinnaker, skip this step.
Replace bitbucket-for-terraform
with any unique identifier to
identify the artifact account.
Operator
apiVersion: spinnaker.armory.io/v1alpha2
kind: SpinnakerService
metadata:
name: spinnaker
spec:
spinnakerConfig:
config:
artifacts:
bitbucket:
enabled: true
accounts:
- name: bitbucket-for-terraform
username: <Your Bitbucket username>
password: <Your Bitbucket password> # This field supports "encrypted" field references (https://docs.armory.io/spinnaker-install-admin-guides/secrets/)
Halyard
hal config artifact bitbucket enable
# This will prompt for the password
hal config artifact bitbucket account add bitbucket-for-terraform \
--username <USERNAME> \
--password
Enabling the Terraform Integration
Enable the Terraform Integration:
Operator
In SpinnakerService
manifest:
apiVersion: spinnaker.armory.io/v1alpha2
kind: SpinnakerService
metadata:
name: spinnaker
spec:
spinnakerConfig:
config:
armory:
terraform:
enabled: true
profiles:
deck:
# Enables the UI for the Terraform Integration stage
settings-local.js: |
window.spinnakerSettings.feature.terraform = true;
This example manifest also enables the Terraform Integration UI.
Halyard
hal armory terraform enable
Remote backends
Early Access
The information below is written for an Early Access feature. Contact us if you are interested in using this feature! Your feedback will help shape the development of this feature.Do not use Early Access features for production environments.
The Terraform Integration supports using remote backends provided by Terraform Cloud and Terraform Enterprise.
When using remote backends, keep the following in mind:
- The Terraform stage must use the same Terraform version that your Terraform Cloud/Enterprise workspace is configured to run.
- The minimum supported Terraform version is 0.12.0.
- In the Terraform Cloud/Enterprise UI, the type of
plan
action that the Terraform Integration performs is a “speculative plan.” For more information, see Speculative Plans. - You cannot save and apply a plan file.
Enable remote backend support
End users can use remote backends by configuring the Terraform Integration stage with the following parameters:
- A Terraform version that is 0.12.0 or later and matches the version that your Terraform Cloud/Enterprise runs.
- Reference a remote backend in your Terraform code.
To enable support, add the following config to your terraformer-local.yml
file in the .hal/default/profiles
directory:
terraform:
remoteBackendSupport: true
Enabling the Terraform Integration UI
If you previously used the Terraform Integration stage by editing the JSON representation of the stage, those stages are automatically converted to use the UI.
Manually enable the stage UI for Deck:
Operator
See the example manifest in Enabling the Terraform Integration.
Halyard
Edit ~/.hal/default/profiles/settings-local.js
and add the following:
window.spinnakerSettings.feature.terraform = true;
Completing the installation
After you finish your Terraform integration configuration, perform the following steps:
-
Apply the changes:
Operator
Assuming that Spinnaker lives in the namespace
spinnaker
and theSpinnakerService
manifest is namedspinnakerservice.yml
:kubectl -n spinnaker apply -f spinnakerservice.yml
Halyard
hal deploy apply
-
Confirm that the Terraform Integration service (Terraformer) is deployed with your Spinnaker deployment:
kubectl get pods -n <your-spinnaker-namespace>
In the command output, look for a line similar to the following:
spin-terraformer-d4334g795-sv4vz 2/2 Running 0 0d
Configure Terraform for your cloud provider
Since the Terraform Integration executes all Terraform commands against the terraform
binary, all methods of configuring authentication are supported for your desired cloud provider. This section describes how to accomplish this for various cloud providers.
You can also configure a profile that grants access to resources, like AWS.
Named Profiles
A Named Profile gives users the ability to reference certain kinds of external sources, such as a private remote repository, when creating pipelines. The supported credentials are described in Types of credentials.
Types of credentials
The Terraform integration supports multiple types of credentials for Named Profiles to handle the various use cases that you can use the Terraform integration for:
- AWS
- SSH
- Static
- Terraform remote backend
If you don’t see a credential that suits your use case, let us know!
For information about how to configure a Profile, see Configuring a profile.
AWS
Use the aws
credential type to provide authentication to AWS. There are two methods you can use to provide authentication - by defining a static key pair or a role that should be assumed before a Terraform action is executed.
For defining a static key pair, supply an accessKeyId
and a secretAccessKey
:
- name: devops # Unique name for the profile. Shows up in Deck.
variables:
- kind: aws # Type of credential
options:
accessKeyId: AKIAIOWQXTLW36DV7IEA
secretAccessKey: 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
For assuming a role instead of defining a static set of credentials, supply the ARN of the role to assume:
- name: devops # Unique name for the profile. Shows up in Deck.
variables:
- kind: aws # Type of credential
options:
assumeRole: arn:aws:iam::012345567:role/roleAssume
When assuming a role, if accessKeyId
and secretAccessKey
are supplied, the Terraform integration uses these credentials to assume the role. Otherwise, the environment gets used for authentication, such as a machine role or a shared credentials file.
SSH Key
Use the git-ssh
credential kind to provide authentication to private Git repositories used as modules within your Terraform actions. The supplied SSH key will be available to Terraform for the duration of your execution, allowing it to fetch any modules it needs:
- name: pixel-git # Unique name for the profile. Shows up in Deck.
variables:
- kind: git-ssh # Type of credential
options:
sshPrivateKey: encrypted:vault!e:<secret engine>!p:<path to secret>!k:<key>!b:<is base64 encoded?>
Static
Use the static
credential kind to provide any arbitrary key/value pair that isn’t supported by any of the other credential kinds. For example, if you want all users of the devops
profile to execute against the AWS_REGION=us-west-2
, use the following static
credential configuration.
- name: devops # Unique name for the profile. Shows up in Deck.
variables:
- kind: static # Type of credential
options:
name: AWS_REGION
value: us-west-2
Terraform remote backend
Use the tfc
credential kind to provide authentication to remote Terraform backends.
- name: milton-tfc # Unique name for the profile. Shows up in Deck.
variables:
- kind: tfc
options:
domain: app.terraform.io # or Terraform Enterprise URL
token: <authentication-token> # Replace with your token
Configuring a Named Profile
Configure profiles that users can select when creating a Terraform Integration stage:
-
In the
.hal/default/profiles
directory, create or editterraformer-local.yml
. -
Add the values for the profile(s) you want to add under the
profiles
section. The following example adds a profile namedpixel-git
for an SSH key secured in Vault.- name: pixel-git # Unique profile name displayed in Deck variables: - kind: git-ssh options: sshPrivateKey: encrypted:vault!e:<secret engine>!p:<path to secret>!k:<key>!b:<is base64 encoded?>
When a user creates or edits a Terraform Integration stage in Deck, they can select the profile
pixel-git
from a dropdown.Keep the following in mind when adding profiles:
-
You can add multiple profiles under the
profiles
section. -
Do not commit plain text secrets to
terraformer-local.yml
. Instead, use a secret store: Vault, an encrypted S3 bucket, or an encrypted GCS bucket. -
For SSH keys, one option parameter at a time is supported for each Profile. This means that you can use a private key file (
sshPrivateKeyFilePath
) or the key (sshPrivateKey
) as the option. To use the key file path, usesshPrivateKeyFilePath
for the option and provide the path to the key file. The path can also be encrypted using a secret store such as Vault. The followingoption
example usessshPrivateKeyFilePath
:options: sshPrivateKeyFilePath: encryptedFile:<secret_store>!e:...
For more information, see the documentation for your secret store.
-
-
Save the file.
-
Apply your changes:
hal deploy apply
Adding authz to Named Profiles
Armory recommends that you enable authorization for your Named Profiles to provide more granular control and give App Developers better guardrails. When you configure authz for Named Profiles, you need to explicitly grant permission to the role(s) you want to have access to the profile. Users who do not have permission to use a certain Named Profile do not see it as an option in Deck. And any stage with that uses a Named Profile that a user is not authorized for fails.
You can see a demo here: Named Profiles for the Terraform Integration.
Note
Before you start, make sure you enable Fiat. For more information about Fiat, see Fiat Overview and Authorization (RBAC).Halyard
To start, edit ~/.hal/default/profiles/terraformer-local.yml
and add the following config:
fiat:
enabled: true
baseUrL: ${services.fiat.baseUrl} # If you are using a custom URL for Fiat, replace with your Fiat URL.
Now, you can specify permissions for any profiles you have:
profiles:
...
...
...
permissions:
- <role that should have access>
- <role that should have access>
- ...
This is what a Named Profile for a team named dev-team
looks like for AWS credentials:
profiles:
- name: dev-team
variables:
- kind: aws
options:
assumeRole: my-role
permissions:
- dev
- ops
In the example, only users who belong to the dev
or ops
groups can use the credentials that correspond to this profile.
Don’t forget to run hal deploy apply
once you finish making changes!
Retries
The Terraformer service can retry connections if it fails to fetch artifacts from Clouddriver. Configure the retry behavior in your terraformer-local.yml
file by adding the following snippet:
# terraformer-local.yml
clouddriver:
retry:
enabled: true
minWait: 4s # must be a duration, such as 4s for 4 seconds
maxWait: 8s # must be a duration, such as 8s for 8 seconds
maxRetries: 5
The preceding example enables retries and sets the minimum wait between attempts to 4 seconds, the maximum wait between attempts to 8s, and the maximum number of retries to 5.
Logging and metrics
If the logging URL is not responsive, the Terraform Integration may not process deploys until the URL can be reached.
You can enable logging and metrics for Prometheus by adding the following configuration to the spec.spinnakerConfig.profiles.terraformer.logging.remote
block in your SpinnakerService
manifest (Operator) or the terraformer-local.yml
file (Halyard):
spec:
spinnakerConfig:
profiles:
terraformer:
logging:
remote:
enabled: true
endpoint: <TheLoggingEndPoint> # For example, https://debug.armory.io
version: 1.2.3
customerId: someCustomer123 # Your Armory Customer ID
metrics:
enabled: true
frequency: <Seconds> # Replace with an integer value for seconds based on how frequently you want metrics to be scraped
prometheus:
enabled: true
commonTags: # The following tags are examples. Use tags that are relevant for your environment
# env: dev
# nf_app: exampleApp
# nf_region: us-west-1
logging:
remote:
enabled: true
endpoint: <TheLoggingEndPoint> # For example, https://debug.armory.io
version: 1.2.3
customerId: someCustomer123 # Your Armory Customer ID
metrics:
enabled: true
frequency: <Seconds> # Replace with an integer value for seconds based on how frequently you want metrics to be scraped
prometheus:
enabled: true
commonTags: # The following tags are examples. Use tags that are relevant for your environment
# env: dev
# nf_app: exampleApp
# nf_region: us-west-1
Submit feedback
Let us know what you think at go.armory.io/ideas or feedback.armory.io. We’re constantly iterating on customer feedback to ensure that the features we build make your life easier!
Feedback
Was this page helpful?
Thank you for letting us know!
Sorry to hear that. Please tell us how we can improve.
Last modified July 19, 2021: (2d2e3e1)