Automating Harness with Terraform

Automating Harness with Terraform

Most DevOps teams use Terraform to automate the management of their infrastructure. It’s a highly extensible tool that can work with just about any platform that has an API. Whether it’s spinning up resources in the cloud or adding users to git repositories, Terraform is typically the tool of choice for automating the entire DevOps ecosystem.

Until now, onboarding new teams, applications, and pipelines in Harness required scripting using our GraphQL API’s or creating Yaml objects in a git repository. With the new Harness Terraform Provider you can now use the tool you already know and love (well maybe not that last part) to create everything you need in Harness.

NOTE: This article assumes you already know the basics of using Terraform. If you want you can skip ahead to this fully working demo

Prerequisites

There are two things you’ll need to get started:

  • API Key: You can create an api key by following these instructions. For this example it should have the role of Account Administrator.
  • Account Id: This can be found in the URL of the Harness UI. The format is https://app.harness.io/#/account/<ACCOUNT_ID>

Provider Setup

First thing you’ll need to do is setup the provider. You can either enter the API key and account id directly (not recommended) or they can be set using the HARNESS_API_KEY and HARNESS_ACCOUNT_ID environment variables (preferred).

terraform {
  required_providers {
    harness = {
      source  = "harness-io/harness"
      version = "~> 0.0.12"
    }
  }
}

provider "harness" {
  api_key = "<API_KEY>"
  account_id = "<ACCOUNT_ID>"
}

Creating resources

Most things in Harness require a git connector. Let’s see how we can create one.

variable "github_token" {}
variable "github_username" {}

data "harness_secret_manager" "default" {
  default = true
}

resource "harness_encrypted_text" "github_token" {
  name              = "github-token"
  value             = var.github_token
  secret_manager_id = data.harness_secret_manager.default.id

  usage_scope {
    application_filter_type = "ALL"
    environment_filter_type = "NON_PRODUCTION_ENVIRONMENTS"
  }

  usage_scope {
    application_filter_type = "ALL"
    environment_filter_type = "PRODUCTION_ENVIRONMENTS"
  }
}
resource "harness_git_connector" "demo" {
  name                 = "git-connector"
  url                  = "https://github.com/harness-io/terraform-demo"
  branch               = "main"
  username             = var.github_username
  password_secret_id   = harness_encrypted_text.github_token.id
  url_type             = "REPO"
  generate_webhook_url = true
}

You’ll notice here that we create some required variables github_token and github_username. Since these are sensitive values we will want to pass them in using the environment variables TF_VAR_github_token and TF_VAR_github_username.

Using config-as-code objects

Some Harness resources don’t yet have a native object in Terraform. For these scenarios we can fall back to using the config-as-code objects and provide the raw YAML. Here is an example of creating an artifact server.

resource "harness_yaml_config" "docker_registry" {
  path    = "Setup/Artifact Servers/docker-hub-public.yaml"
  content = <<EOF
harnessApiVersion: '1.0'
type: DOCKER
url: https://registry.hub.docker.com/v2/
usageRestrictions:
  appEnvRestrictions:
  - appFilter:
      filterType: ALL
    envFilter:
      filterTypes:
      - PROD
  - appFilter:
      filterType: ALL
    envFilter:
      filterTypes:
      - NON_PROD
EOF
}

What’s next?

Here’s a project that has a full working example that creates everything you need to deploy a Kubernetes application: harness-io/terraform-demo. The Terraform provider is not yet an officially supported project by Harness so be sure and reach out directly through our github repo or in our community slack channel.

2 Likes