Skip to content

Automatically create terraform module from yamls and push workspaces into Terraform Cloud

License

Notifications You must be signed in to change notification settings

dasmeta/terraform-tfe-cloud

Repository files navigation

Why

We needed way to run terraform modules using yaml files as it is much simpler.

How

We have decided to use terraform cloud to execute terraform code. We have decided that it is right to have workspace per module as we do not want giant module dependencies. We have created terraform module that can parse yaml files, create workspaces and make TFC to execute code / modules.

Current implementation si very basic:

  1. accepts module source/version, variables, dependencies and uses variables from other workspaces if allowed.

Caviats

Modules does generate terraform code from yamls and sets up workspaces but since the code is not yet in git repository first run will fail. After another apply is run from local and resulting code is comitted to git repo it will pick up code and executel.

How to use

  1. Create workspace in terrqform cloud
  2. Create folder and place yaml files in the folder
  3. Yaml files point to modules and provide variables like done in tests/basic/example-infra folder
  4. Supply variables to the module like done in basic tests
  5. Terraform apply will create workspaces and code (by default in _terraform folder).
  6. Commit the code and TFC will pick up and apply changes as requested.

ToDo

  1. Modify module to not create workspace immidiately but only when code is comitted (this might create issue with race condition, workspaces can be creared but TFC mighhave had already tried to execute code).
  2. There is an issue with some providers (more details in jira).
  3. Currently some generated code is escaped which is wrong.
  4. Get this repo be managed by terraform module manager terraform repo.

Providers

Name Version
local 2.4.0
tfe 0.47.0

Modules

Name Source Version
provider_custom_vars_default_merged cloudposse/config/yaml//modules/deepmerge 1.0.2

Resources

Name Type
local_file.this resource
tfe_project.project resource
tfe_workspace.this resource
tfe_workspace_variable_set.this resource

Inputs

Name Description Type Default Required
linked_workspaces The list of workspaces from where we can pull outputs and use in our module variables list(string) null no
module_providers The list of providers to add in providers.tf any [] no
module_source The module source string n/a yes
module_vars The module variables any {} no
module_version The module version string n/a yes
name module/repo-folder/workspace name and uniq identifier string n/a yes
output The module output any [] no
repo git/vcs repository configurations
object({
identifier = string # / format repo identifier
branch = optional(string, null) # will default to repo default branch if not set
ingress_submodules = optional(string, false) # whether to fetch submodules a]when cloning vcs
oauth_token_id = optional(string, null) # the auth token generated by resource tfe_oauth_client
tags_regex = optional(string, null) # regular expression used to trigger Workspace run for matching Git tags
})
null no
target_dir The directory where new module folder will be created, this will be terraform project repository root url string "./" no
terraform_backend Allows to set terraform backend configurations
object({
name = string
configs = optional(any, {})
})
{
"configs": null,
"name": null
}
no
terraform_version The required_version variable value for terraform{} block in versions.tf string ">= 1.3.0" no
variable_set_ids The list of variable set ids to attach to workspace list(string) null no
workspace Terraform cloud workspace configurations
object({
org = string
tags = optional(list(string), null)
description = optional(string, null)
directory = optional(string, "./") # this seems supposed to be the root directory of git repo
global_remote_state = optional(bool, true) # allow org workspaces access to this workspace state, TODO: there is a way to implement specific workspaces whitelisting using remote_state_consumer_ids, needs apply and testing
project = optional(string, null) # name of the project to be created and where the workspace should be created
project_id = optional(string, null) # ID of the project which already exists, if none of project and project_id is provided Default Project is used for storing workspaces
})
n/a yes

Outputs

Name Description
project_id The ID of terraform cloud project
test-data n/a
workspace_id The ID of created terraform cloud workspace

Requirements

Name Version
terraform >= 1.3.0
tfe ~> 0.40

Providers

Name Version
tfe ~> 0.40

Modules

Name Source Version
aws_credentials_variable_set ./modules/variable-set n/a
workspaces ./modules/workspace n/a

Resources

Name Type
tfe_oauth_client.this resource

Inputs

Name Description Type Default Required
auto_apply To have workspaces automatically apply after plan is done successfully. bool false no
aws Cloud Access (goes to shared variable set, should be adjusted) map(any)
{
"access_key_id": "",
"default_region": "",
"region": "",
"secret_access_key": "",
"security_token": "",
"session_token": ""
}
no
git_org The github org/owner name string n/a yes
git_provider The vsc(github, gitlab, ...) provider id string "gitlab" no
git_repo The github repo name without org prefix string n/a yes
git_token The vsc(github, gitlab, ...) personal access token. TFC oauth token can be created manually or externally and oken supplied via this variable. string n/a yes
org The terraform cloud org name string n/a yes
rootdir The directory on git repo where the workspaces creator main.tf file located string "./_terraform/" no
targetdir The directory where tf cloud workspace corresponding workspaces will be created string "./../_terraform/" no
token The terraform cloud token string n/a yes
yamldir The directory where yamls located string "." no

Outputs

No outputs.