Skip to content

WIP: POC for terraform backend

Magdalena Frankiewicz requested to merge terraform-state-http-backend into master

What does this MR do?

DO NOT MERGE This MR is only a rough POC for terraform http backend.

What we can observe here is that terraform http backend only works with basic http authentication. It does not work with passing a Personal Access Token as a query string parameter in the address option of terraform http backend, as that query string parameter is stripped away.

To see it happening

  1. checkout the branch locally, run the migrations
  2. create a simple terraform project using the terraform http backend
terraform {
  backend "http" {
    address = "http://localhost:3333/api/v4/projects/[project_id]/terraform_states/[state_name]"
  }
}
  1. comment out before { authenticate! } in lib/api/project_terraform_states.rb to disable authentication
  2. run terraform init and terraform apply from your terraform project directory
  3. you can see that the backend is working correctly (you can curl the endpoint to see the state curl http://localhost:3333/api/v4/projects/[project_id]/terraform_states/[state_name] or you can check in the database)
  4. uncomment back in before { authenticate! } in lib/api/project_terraform_states.rb to enable authentication
  5. create an Personal Access Token and add it to your terraform project backend config
terraform {
  backend "http" {
    address = "http://localhost:3333/api/v4/projects/[project_id]/terraform_states/[state_name]?private_token=[my-personal-access-token]"
  }
}
  1. run terraform init again
  2. you will see an authentication error

If you inspect the Rails logs, you will see that the terraform http backend strips the query string parameters. The same request made with curl works fine:

curl http://localhost:3333/api/v4/projects/[project_id]/terraform_states/[state_name]?private_token=[my-personal-access-token]

Http basic authentication would work with terraform backend, but it is not implemented on GitLab as an authentication method, as far as I can see.

UPDATE

The problem was solved thanks to @mattkasa knowing about the nuget helpers. The API endpoint is able to find the personal access token from http basic authentication. To see it working:

  1. checkout the branch locally, run the migrations
  2. create a simple terraform project using the terraform http backend
terraform {
  backend "http" {
    address = "http://localhost:3333/api/v4/projects/[project_id]/terraform_states/[state_name]"
    username = "something"
    password = [your-personal-access-token]
  }
}
  1. run terraform init from your terraform project directory

Important: It seems the username has to be passed and cannot be an empty string, although is't not really being used.

UPDATE (LOCKING/UNLOCKING ADDED)

To see it working:

  1. checkout the branch locally, run the migrations (I edited migration for terraform_states table, if you had it before, you should rollback and migrate again)
  2. create a simple terraform project using the terraform http backend
terraform {
  backend "http" {
    address = "http://localhost:3333/api/v4/projects/[project_id]/terraform_states/[state_name]"
    username = "something"
    password = [your-personal-access-token]
    lock_address = "http://localhost:3333/api/v4/projects/[project_id]/terraform_states/[state_name]/lock"
    unlock_address = "http://localhost:3333/api/v4/projects/[project_id]/terraform_states/[state_name]/lock"
    lock_method = "POST"
    unlock_method = "DELETE"
  }
}
  1. run terraform init from your terraform project directory
Edited by 🤖 GitLab Bot 🤖

Merge request reports