Provision Infrastructure


In this second part of the Kubestack tutorial you will:

  1. Setup authentication.
  2. Provision the remote state.
  3. Bootstrap your infrastructure.

To make it easier to provide all prerequisites like the cloud provider command line utilities, Terraform, Kustomize and more we provide a container image and use it for bootstrapping now and also CI/CD later.

# Build the bootstrap container
docker build -t kbst-infra-automation:bootstrap .
# Exec into the bootstrap container
docker run --rm -ti \
-v `pwd`:/infra \

Setup authentication

Follow the instructions to authenticate with your chosen cloud provider. If you chose more than one, follow the instructions for each of them.


Use your personal user to create the automation user.

  1. Login with your personal user.

    # Run aws configure and follow the instructions
    # Make sure to set a default region
    aws configure
  2. Create the automation user and attach the AWS managed AdministratorAccess policy to it.

    # Create the user
    aws iam create-user --user-name kubestack-automation
    # Attach the managed admin policy to the user
    aws iam attach-user-policy \
    --policy-arn arn:aws:iam::aws:policy/AdministratorAccess \
    --user-name kubestack-automation
  3. Replace your personal credentials.

    # Create keys for the user
    ACCESS_KEY_JSON=$(aws iam create-access-key --user-name kubestack-automation)
    # Set the access key
    aws configure set aws_access_key_id $(echo $ACCESS_KEY_JSON | jq -r .AccessKey.AccessKeyId)
    # Set the secret access key
    aws configure set aws_secret_access_key $(echo $ACCESS_KEY_JSON | jq -r .AccessKey.SecretAccessKey)

Provision the remote state

Terraform requires remote state to run in CI/CD. You are free to use any supported remote state storage. Below instructions use your cloud provider's object storage. If you're provisioning multi-cloud infrastructure, pick one of your providers to store the state.

Object storage bucket names have to be globally unique. The instructions below append the short git hash of our initial commit to achieve this.


Run the following commands to create a bucket in AWS S3 and change the file to configure Terraform to use the created bucket for remote state.

# Create bucket and configure remote state
BUCKET_NAME=terraform-state-kubestack-`git rev-parse --short HEAD`
REGION=`aws configure get region`
aws s3api create-bucket --bucket $BUCKET_NAME --region $REGION --create-bucket-configuration LocationConstraint=$REGION --acl private
aws s3api put-bucket-versioning --bucket $BUCKET_NAME --region $REGION --versioning-configuration Status=Enabled
aws s3api put-bucket-encryption --bucket $BUCKET_NAME --region $REGION --server-side-encryption-configuration '{
"Rules": [
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
cat > <<EOF
terraform {
backend "s3" {
bucket = "${BUCKET_NAME}"
region = "${REGION}"
key = "tfstate"

Bootstrap your infrastructure

With the remote state set up, initialize Terraform.

# Initialize Terraform
terraform init

Terraform workspaces

Then create Terraform workspaces to match your infrastructure environments. You have to create one workspace per infrastructure environment you scaffolded. The workspace name has to match the environment name.

By default, there are two environments named ops and apps. If you chose three environments, create ops, apps and apps-prod workspaces respectively.

# If you chose three environments, create apps-prod
terraform workspace new apps-prod
# Create apps and ops workspaces
terraform workspace new apps
terraform workspace new ops

Terraform apply

Now, with the workspaces created, let's go ahead and provision the cloud resources for all environments. Provision two or three environments, depending on your platform environments. If you changed the name of the workspaces, adapt them here accordingly.

# Bootstrap the ops environment
terraform workspace select ops
terraform apply --auto-approve
# Bootstrap the apps environment
terraform workspace select apps
terraform apply --auto-approve
# Bootstrap the apps-prod environment
terraform workspace select apps-prod
terraform apply --auto-approve

Commit changes

# Exit the bootstrap container
# Commit the configuration
git add .
git commit -m "Add remote state configuration"


You now have the GitOps repository in place. And also provisioned prerequisites like authentication credentials and the remote state. Finally, you also bootstrapped your ops, apps and optionally apps-prod infrastructure.

Continue with the third part of the tutorial to add the automation pipeline.