Deploying your infrastructure with Scalr and GitHub Actions
By
Brendan Thompson
In this post we will discuss how to deploy your infrastructure with Terraform using Scalr and GitHub Actions. Scalr will be used as the backend for our Terraform state and GitHub Actions will act as the orchestrator to execute our Terraform runs.
If you're new to Scalr or would like to learn more I would recommend reading the Introduction and Getting Started pages as they provide an good level of detail to get you started with Scalr. For this post it assumes that you have a Scalr Organization and Environment setup and ready to go!
Setting up Scalr
First off we need to setup a few things within Scalr; Service Account, Token, and Workspace. With these three things we will be able to connect up to GitHub and start running some Terraform.
1. From the Scalr Environment dashboard we are going to be clicking on Create workspace.
2. Give the workspace a Name that makes sense for your situation, and ensure you select CLI as the Source as we will be using GitHub Actions as our orchestrator rather than Scalr itself. Finally click on Create workspace.
3. The next step is going to be setting up a Service Account for GitHub to authenticate with. Click on Account.
4. Next click on IAM.
5. From the IAM page click on Service accounts.
6. Click on New service account.
7. Give the service account a meaningful Name, and then click on Grant access.
8. For this Service Account to work correctly for us we are going to need to provide it with access to three different areas within Scalr. Firstly under Roles we need to give access to account-min-access which provides the service account the ability to perform minimal operation on the account, ensure the Grant on is set to Account. Then click Assign.
Next we need to provide access to the environment; select environment-min-access from the the Roles dropdown, Environment from Grant on and finally select your environment name from the Environment dropdown. In our example that is Non-production. Finally click on Assign.
The final access we are going to be providing is to the workspace that we created, under Roles select admin, for Grant on select Workspace, Environment select your environment (e.g. Non-production), then select the workspace from the Workspace dropdown, finally click Assign.
9. Now that the access is all setup for the Service Account we need to generate a token for use. Click the Generate token button.
10. Give the Token a Description that is meaningful should you require and click Copy and Save.
Now we have all of our pieces put together we will add them into GitHub in the next section!
Setting up Github
For our GitHub setup we are simply going to be adding in the Token we just generated within Scalr, this will allow GitHub Actions to perform state storage operations on our workspace.
1. From your repository root click on Settings.
2. Click the disclosure on the Secrets and variables menu item.
3. Click Actions.
4. Click on New repository secret.
For the Name field we need to set that as SCALR_TOKEN, the Secret should be set to whatever Token value you copied from Scalr, finally click Add secret.
Terraform & GitHub Actions Code
Our environment is now completely setup and ready to accept our Terraform code as well as the definition of our GitHub Actions workflow. Firstly lets take a quick look at the Terraform code example, it is just going to be provisioning a scratch resource and outputting its value for us. Let's break up the code a little bit.
Firstly we need to ensure that our version of Terraform is set to less than v1.6, in this instance we will use v1.5.6.
terraform {
required_version = "1.5.6"
# ...
}
Next we need to instruct Terraform to use Scalr as our backend, this has three properties that are required to be set:
hostname: the Scalr URL to your Organization.
organization: the Environment ID from your Scalr Organisation.
name: the name of the Workspace that the code is going to be deployed into.
From the Scalr Workspace dashboard page you can get the Workspace configuration by click on Remote backend configuration.
This will show the follow modal with the details that can be copied and pasted into your editor:
The final element required within our terraform block is the required_providers, this instructs Terraform where to download the provider from and what version constraints to be applied if defined.
With all of that in place now when we define the following it will store its state into the remote backend we defined earlier.
resource "scratch_string" "this" {
in = "Hello, GitHub Actions"
}
output "github_actions_string" {
value = scratch_string.this.in
}
As I said, a very simple Terraform root module definition, we are merely going to be printing a message to the output.
Next we will step into the GitHub Actions (GHA) workflow file, this file MUST exist within the .github/workflows directory in your repository.
This defines us a very basic GHA workflow wherein any push to the main branch triggers an execution of the workflow. Firstly we checkout the Terraform code from the repository using actions/checkout@v2 then we setup the Scalr environment on the runner with the Scalr/scalr-action@v1 action, this is where we provide the Scalr Organisation and Token as well as optionally a Terraform version. If the Terraform version is not provided then Scalr will attempt to work it out for itself.
The next steps should look fairly familiar:
terraform init: initialises our code, pulls providers and modules as well as setting up connectivity to the backend.
terraform plan: plan our version of the code against what exists in production.
terraform apply: applies any changes to the environment.
All the echo steps are doing is providing useful information back to us. You can read more about the action on the Scalr Github Action page.
The GitHub Actions Run
Now that everything is setup and linked together when we push a change into GitHub a run is triggered. From the Repository root after a change has been pushed you can click on the little orange dot next to the commit.
This brings up a small modal, click on Details.
From here you can see a full summary of what is going on:
Once the Job has finished you can go back to Scalr to see what's happened:
Closing Out
So today we have looked at how easy it is to setup a GitHub repository hosting Terraform code with Scalr as the backend state storage facility using GitHub Actions as the orchestrator. If you're just starting out with Terraform in your organization and are looking for a free, highly-available and solid state storage solution then this is one of the most solid ways to go. As you will soon learn the more you delve into Terraform state is both a blessing and a curse, having it stored somewhere that is extremely solid is absolutely critically important!!
Note: While this blog references Terraform, everything mentioned in here also applies to OpenTofu. New to OpenTofu? It is a fork of Terraform 1.5.7 as a result of the license change from MPL to BUSL by HashiCorp. OpenTofu is an open-source alternative to Terraform that is governed by the Linux Foundation. All features available in Terraform 1.5.7 or earlier are also available in OpenTofu. Find out the history of OpenTofu here.