Deploying Linode Marketplace StackScripts with Terraform
Recently, I needed to deploy a 3 node Redis Cluster from Linode’s Marketplace.
Quick glance at Linode’s Terraform provider shows that we can deploy instances using StackScripts, but in order to do that, we need to specify the StackScript ID. If we are deploying from our own StackScript, it’s easy, you just reference it like this and you’re good to go.
resource "linode_stackscript" "foo" {
label = "foo"
description = "Installs a Package"
script = <<EOF
#!/bin/bash
# <UDF name="package" label="System Package to Install" example="nginx" default="">
apt-get -q update && apt-get -q -y install $PACKAGE
EOF
images = ["linode/ubuntu18.04", "linode/ubuntu16.04lts"]
rev_note = "initial version"
}
resource "linode_instance" "foo" {
image = "linode/ubuntu18.04"
label = "foo"
region = "us-east"
type = "g6-nanode-1"
authorized_keys = ["..."]
root_pass = "..."
stackscript_id = linode_stackscript.foo.id
stackscript_data = {
"package" = "nginx"
}
}
“Problem” comes when we want to deploy a product from the marketplace, in order to do that we need to collect a few things first.
- ID of the StackScript you want to deploy
- List of supported OS images
- Check which variables we need to provide to the StackScript.
Step 1 – Fetching the StackScript ID. In this case, I’ll do it using linode-cli, but you’re free to use any other method
linode-cli stackscripts list --label "Redis Sentinel Cluster One-Click"
Output of this command looks like this
From here, we need to write down the ID of the script, and check the list of supported images. In this case, I’ll deploy a stackscript with the ID 1132204 which is owned by Linode.
Next step is to check which variables we need to provide to the StackScript. We can easily see that by running the following Powershell command:
$stackscripts = ((wget https://cloud.linode.com/api/v4/linode/stackscripts?page_size=500).Content | convertfrom-json)
$stackscripts.data | where {$_.id -like "1132204"} | select -expand user_defined_fields
name label
---- -----
token_password Your Linode API token
sudo_username The limited sudo user to be created in the cluster
sslheader SSL Information
country_name Details for self-signed SSL certificates: Country or Region
state_or_province_name State or Province
locality_name Locality
organization_name Organization
email_address Email Address
ca_common_name CA Common Name
common_name Common Name
clusterheader Cluster Settings
add_ssh_keys Add Account SSH Keys to All Nodes?
cluster_size Redis cluster size
And finally put all of those variables into our Terraform code, which in end looks something like this:
resource "linode_instance" "redis" {
image = "linode/ubuntu22.04"
label = "RedisCluster"
group = "Redis"
tags = [ "stage:dev" ]
region = "eu-central"
type = "g6-standard-1"
authorized_users = [ "yourUsername" ]
root_pass = "SuperRandomPassW0rd.123!"
stackscript_id = 1132204
stackscript_data = {
"token_password" = "yourLinodeToken"
"sudo_username" = "myuser"
"sslheader" = "Yes" #Default YES
"country_name" = "NL" #Two letter country code
"state_or_province_name" = "South Holland"
"locality_name" = "Rotterdam"
"organization_name" = "Org Name"
"email_address" = "yourEmail@here.com"
"ca_common_name" = "Redis CA"
"clusterheader" = "Yes"
"add_ssh_keys" = "no" #yes or no
"cluster_size" = "3" #3 or 5
}
}
Notice we are required to provide our Linode token in order to deploy this cluster; this can be the same token you’re using for your existing Terraform code, so you can simple reference a environment variable in your code and off you go 😀
Cheers, Alex.