Code Monkey home page Code Monkey logo

terraform-provider-env0's Introduction

env0 logo

Terraform Provider for env0

Go Report Card

Quick Start

terraform {
  required_providers {
    env0 = {
      source = "env0/env0"
    }
  }
}

provider "env0" {}

data "env0_project" "default_project" {
  name = "My First Project"
}

resource "env0_template" "example" {
  name        = "example"
  description = "Example template"
  repository  = "https://github.com/env0/templates"
  path        = "aws/hello-world"
}

resource "env0_configuration_variable" "in_a_template" {
  name        = "VARIABLE_NAME"
  value       = "some value"
  template_id = env0_template.tested1.id
}

Authentication

  1. Generate an api_key and api_secret from the Organization Settings page. See here.

  2. These can be provided by one of two methods:

    1. Set ENV0_API_KEY and ENV0_API_SECRET environment variables, and just declaring the provider with no parameters:
       provider "env0" {}
    1. Specify these fields as parameters to the provider:
    variable "env0_api_key" {}
    variable "env0_api_secret" {}
    
    provider "env0" {
      api_key = var.env0_api_key
      api_secret = var.env0_api_secret
    }

How to get VCS credentials for Creating a template or a VCS environment

To create an env0_template or a VCS env0_environment resources a user must provision the corresponding credentials:

  1. github_installation_id for Github
  2. bitbucket_client_key for Bitbucket
  3. gitlab_project_id + token_id for Gitlab
  4. token_id for Azure DevOps

To get those credentials in the provider you must first create a "master" environment via the env0 app, then just fetch the corresponding env0_environment data source and use the relevant credentials:

data "env0_environment" "master_environment" {
  id = "exampleId"
}

resource "env0_template" "example" {
  name        = "example AzureDevOps"
  description = "Example AzureDevOps template"
  repository  = "https://dev.azure.com/example-org/AWS/_git/example"
  path        = "hello-world"
  token_id    = data.env0_environment.master_environment.token_id
}

Development Setup

Supported Go Version: 1.21

Build

  • Use the ./build.sh script.
  • The output binary is called terraform-provider-env0

Run local version of the provider

  • Build - ./build.sh
  • Create the plugins folder - mkdir -p ~/.terraform.d/plugins/terraform.env0.com/local/env0/6.6.6/darwin_amd64 (for M1 processor, replace amd64 with arm64)
  • Copy the built binary - cp ./terraform-provider-env0 ~/.terraform.d/plugins/terraform.env0.com/local/env0/6.6.6/darwin_amd64 (Replace darwin with linux on Linux)
  • Require the local provider in your main.tf -
terraform {
  required_providers {
    env0 = {
      version = "6.6.6"
      source  = "terraform.env0.com/local/env0"
    }
  }
}

Installing pre-commit hooks

For consistent coding style, install pre-commit hooks.

go install golang.org/x/tools/...@latest
go install honnef.co/go/tools/cmd/staticcheck@latest
pre-commit install
pre-commit install --hook-type pre-push

Testing

Integration tests

  • The integration tests run against the real env0 API
  • Have ENV0_API_KEY and ENV0_API_SECRET environment variables defined.
  • Also set ENV0_API_ENDPOINT if you want to run against a non-prod environment.
  • Run go run tests/harness.go (from the project root folder) to run all the tests.
  • Use go run tests/harness.go 003_configuration_variable to run a specific test.

Each test perform the following steps:

  • terraform init
  • terraform apply -auto-approve -var second_run=0
  • terraform apply -auto-approve -var second_run=1
  • terraform outputs -json - and verifies expected outputs from expected_outputs.json
  • terraform destroy

The harness has two modes to help while developing: If an environment variable DESTROY_MODE exists and it's value is NO_DESTROY, the harness will avoid calling terraform destroy, allowing the developer to inspect the resources created, through the dashboard, for example. Afterwards, when cleanup is required, just set DESTROY_MODE to DESTROY_ONLY and only terraform destroy will run.

Integration Test Prerequisites

Unit Testing

How to run tests

Run from root directory:

go test -v ./...

Running a single provider test

export TEST_PATTERN="TestUnitConfigurationVariableResource/Create" && go test -v ./env0

How to use mocks

  1. Make sure GOPATH is in your PATH
go env GOPATH
echo $PATH
export PATH=$PATH:$(go env GOPATH)  # if not
  1. Install mockgen
go install go.uber.org/mock/[email protected]
  1. Make sure to add this line in files that include the interface you'd wish to mock:
//go:generate mockgen -destination=<file>_mock.go -package=<package> . <interface>
  1. Run from root directory:
go generate ./...

Documentation

  • Docs are generated using github.com/hashicorp/terraform-plugin-docs
  • Run ./generate-docs.sh to generate docs
  • Must be run manually before releasing a version
  • Please add an example to examples/<resources or data-sources>/env0_<name> dir and make sure it is added to the docs.

Release

To release a version to the Terraform Public Registry:

  1. Validate that all status checks are ✅ on main branch (specifically that docs generation is complete)
  2. Pull from remote first - git pull origin main
  3. Create and push a tag locally, in semver format - git tag v0.0.9 && git push origin --tags
  4. New release with binaries will be automatically generated by the GitHub action defined in .github/workflows/release.yml.
  5. The Registry will automatically pick up on the new version.

terraform-provider-env0's People

Contributors

4562448 avatar alonnoga avatar asafpeduel avatar avnerenv0 avatar away168 avatar bernot-dev avatar chpl avatar dependabot[bot] avatar eladmosh avatar eyalatzmon avatar gilifaroenv0 avatar heverfarber avatar idokrn avatar ivankovnatsky avatar liranfarage89 avatar omry-hay avatar razbensimon avatar rlrabinowitz avatar roni-frantchi avatar ronnyorot avatar sagilaufer1992 avatar sagydr avatar samuel-br avatar shlomimatichin avatar tomer-landesman avatar tomerheber avatar yaronya avatar yossi-kerner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-provider-env0's Issues

`data "env0_project"` should not take archived projects into account

  1. Manually create two projects in env0 called "TestProject"
  2. Archive one of those projects
  3. Create env0_project data in a TF file with name = "TestProject":
data "env0_project" "test_project" {
  name = "TestProject"
}
  1. terraform plan fails with "Found multiple Projects for name"

This data should completely ignore archived projects, as they are technically "destroyed"

Integration tests fail to run on Mac/OSX

Getting an error

Provider terraform-registry.env0.com/env0/env0 v6.6.6 does not have a package
available for your current platform, darwin_amd64.

this can be fixed by changing tests/harness.go in buildFakeTerraformRegistry making the registry_dir end with darwin_amd64 instead of linux_amd64, but we should have this resolved automatically.

Unit tests take a minute

On Mac :

ok  	github.com/env0/terraform-provider-env0/client/http	(cached)
=== RUN   TestUnitOrganizationData
--- PASS: TestUnitOrganizationData (16.59s)
=== RUN   TestUnitProjectData
--- PASS: TestUnitProjectData (16.04s)
=== RUN   TestProvider
--- PASS: TestProvider (0.00s)
=== RUN   TestMissingConfigurations
--- PASS: TestMissingConfigurations (0.00s)
=== RUN   TestUnitProjectResource
--- PASS: TestUnitProjectResource (27.87s)
PASS
ok  	github.com/env0/terraform-provider-env0/env0	61.365s

via GIPHY

Resync Terraform Registry after release build is complete

When we release there is a github action that builds all the binaries.
But the TF Registry will pickup on the release too soon and we get

Could not find all platform assets for this release yet (0.0.5) — 2 minutes ago

Then we need to manually re-sync it (from the registry UI)

We should add an API call in the release flow to do that when the binaries are ready.

Integration tests fail - getConfigurationVariable - interface conversion

Stack trace from the terraform-provider-env0 plugin:

panic: interface conversion: interface {} is string, not *client.ApiClient

goroutine 30 [running]:
github.com/env0/terraform-provider-env0/env0.getConfigurationVariable(0x18b2c8d, 0x6, 0x0, 0x0, 0x0, 0x0, 0xc000120b80, 0x12, 0x0, 0x0, ...)
	/Users/avnersorek/env0/terraform-provider-env0/env0/data_configuration_variable.go:147 +0x8f3
github.com/env0/terraform-provider-env0/env0.dataConfigurationVariableRead(0x19ae020, 0xc000300240, 0xc000338600, 0x1882cc0, 0xc000683d80, 0xc0006b4760, 0xc00048f950, 0x100ff98)
	/Users/avnersorek/env0/terraform-provider-env0/env0/data_configuration_variable.go:103 +0x2af

Documentation Generation should be automatic

There is a script to generate the docs (./generate-docs.sh) which does everything
But that needs to be run manually and the output committed and pushed.
We should have some kind of pipeline to do that automatically, probably as part of the release (in GitHub actions)

Template Project-IDs doesn't remove template assignments

  1. Apply this tf
resource "env0_project" "my_project" {
  name        = "Provider Project"
  description = "Project Created By Providerz"
}

resource "env0_template" "test_template" {
  name        = "Created by provider"
  description = "This is the best template."
  repository  = "https://github.com/env0/templates"
  path        = "aws/hello-world"
  revision = "master"
  project_ids = [ env0_project.my_project.id ]
}
  1. The template+project are created and assigned
  2. Change to project_ids = []
  3. Apply. The apply makes it look like the project_ids are really cleared.
  4. Go into the env0 UI - the template is still assigned to the project

Map existing templates to new projects

This will tie into the current bug #13 with creating projects, but we would like the capability to tie org templates to newly created projects.

I would propose some new type of resource called something like "env0_project_template_attachment" that leverages the https://api.env0.com/blueprints/id/projects API endpoint to tie templates to projects

The TF code could look like:

data "env0_template" "aws-s3" {
  name = "aws-s3"
}

resource "env0_project" "project" {
  name = "My Project"
}

resource "env0_project_template_attachment" "attach" {
  template_id = data.env0_template.s3.id
  project_id = env0_project.project.id
}

Project deletion should be with flag

Only if there are no environments in the project it should be archived.

If there are - you should get an error.
There should be a flag for "force_destroy" (like in aws_s3_bucket) , when it's true then we should archive the project even if it has environments in it.

Template Resource - removing "path" doesn't remove it

  1. Create a template resource with path = "shoes"
  2. Apply
  3. Remove the path and apply again
  4. The plan says - path = "shoes" -> null
  5. Nothing really changes

Expected behaviour would be to update path with an empty string when it's not defined

Add missing UTs

These following files are not covered by UTs:

  1. data_aws_credentials
  2. resource_aws_credentials
  3. resource_template_project_assignment

Project Description isn't written on Create

  1. Create new project, with description in TF, like -
resource "env0_project" "my_project" {
  name        = "Provider Project"
  description = "Project Created By Provider"
}
  1. apply
  2. The description isn't applied.

If you update, the description will be there, but not on create.

Add pre-commit hooks

We need some run this as pre-commit git hook on this repo

  1. go fmt (husky & prettier style)

Considering those too (maybe with a different hook? commit can be slow)
2. generate mocks
3. generate docs

Import should be implemented for all resource types

terraform import "env0_configuration_variable.test1" b94f954c-0b06-4fb4-8cb5-ed5161c99480
env0_configuration_variable.test1: Importing from ID "b94f954c-0b06-4fb4-8cb5-ed5161c99480"...

Error: Not implemented

:(

Applying a Template 2nd time detects drift

  1. Create a template in TF
  2. Apply
  3. Apply second time, without any change

Get -

Note: Objects have changed outside of Terraform

Terraform detected the following changes made outside of Terraform since the last "terraform apply":

  # env0_template.test_template has been changed
  ~ resource "env0_template" "test_template" {
      + github_installation_id = 0
        id                     = "0495debd-96de-4c82-a6fd-3d607d373d65"
        name                   = "Created by providerz"
      + project_ids            = []
      + retries_on_deploy      = 0
      + retries_on_destroy     = 0
        # (6 unchanged attributes hidden)
    }

Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the following plan may include actions to undo or respond to these changes.

I guess we need to fix the types better so that TF will understand those default values are not changes.

example TF for recreate

resource "env0_template" "test_template" {
  name        = "Created by providerz"
  description = "This is the best template."
  repository  = "https://github.com/env0/templates"
  path        = "aws/hello-world"
  revision = "master"
}

Integration tests rely on actual configuration variable

examples/003_configuration_variable/main.tf relies on the organization having

  • A configuration variable called AWS_DEFAULT_REGION in the organization scope.
  • A configuration variable called AWS_DEFAULT_REGION in the project scope, in the Default Organization Project project.

This should at least be documented but preferably fixed so the integration tests can run on a "clean" organization and not depend on prior manual setup, besides the API Key.

Can't create new env0_project + env0_template + env0_template_project_assignment (Terraform 1.0.0 Env0 Provider 0.0.9)

Terraform Version:

Terraform v1.0.0
on linux_amd64
+ provider registry.terraform.io/env0/env0 v0.0.9

Ubuntu version:

20.04.2

Hi, I'm start trying Env0 Terraform Provider and I'm getting an error when I try to run a Terraform Apply.

Here are the steps that I did:

  1. Create an Env0 API Key.

  2. Successfully tested the Credentials using curl:

curl \
  --silent \
  --header 'Accept: application/json' \
  --user ${ENV0_API_KEY?}:${ENV0_API_SECRET?} \
  "https://api.env0.com/blueprints?organizationId=${ENV0_ORGANIZATION?}" | jq
  1. Set Environment Variables for test:
ENV0_ORGANIZATION=de6d1bb0-f746-4974-ab74-1ff73d0e2445
ENV0_API_SECRET=api_secret_value_here
ENV0_API_KEY=api_key_value_here
  1. Create a Simple Env0 Project worked:
# main.tf
terraform {
  required_providers {
    env0 = {
      source = "env0/env0"
      version = "0.0.9"
    }
  }
}

provider "env0" {
}

resource "env0_project" "example" {
  name        = "example"
  description = "Example project"
}
  1. When I'm trying to create a new env0_template and an env0_template_project_assignment using this:
terraform {
  required_providers {
    env0 = {
      source = "env0/env0"
      version = "0.0.9"
    }
  }
}

provider "env0" {
}

resource "env0_project" "example" {
  name        = "example"
  description = "Example project"
}

resource "env0_template" "example" {
  name        = "mytemplate"
  description = "Example template"
  repository  = "https://github.com/env0/templates"
  path        = "aws/hello-world"
}

resource "env0_template_project_assignment" "assignment" {
  template_id = env0_template.example.id
  project_id  = env0_project.example.id
}

Plan:

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # env0_project.example will be created
  + resource "env0_project" "example" {
      + description = "Example project"
      + id          = (known after apply)
      + name        = "example"
    }

  # env0_template.example will be created
  + resource "env0_template" "example" {
      + description       = "Example template"
      + id                = (known after apply)
      + name              = "mytemplate"
      + path              = "aws/hello-world"
      + repository        = "https://github.com/env0/templates"
      + terraform_version = "0.15.1"
      + type              = "terraform"
    }

  # env0_template_project_assignment.assignment will be created
  + resource "env0_template_project_assignment" "assignment" {
      + id          = (known after apply)
      + project_id  = (known after apply)
      + template_id = (known after apply)
    }

Plan: 3 to add, 0 to change, 0 to destroy.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: .terraform.plan

To perform exactly these actions, run the following command to apply:
    terraform apply ".terraform.plan"

Error:

env0_project.example: Creating...
env0_template.example: Creating...
env0_project.example: Creation complete after 6s [id=a56c4001-e98d-4c66-9487-8724c4465073]
╷
│ Error: could not create template: 400 Bad Request: ["/body/retry/onDestroy must have required property times","/body/retry/onDestroy must be null","/body/retry/onDestroy must match a schema in \"anyOf\"","/body/retry/onDestroy must be null","/body/retry/onDestroy must match a schema in \"anyOf\"","/body/retry/onDeploy must have required property times","/body/retry/onDeploy must be null","/body/retry/onDeploy must match a schema in \"anyOf\"","/body/retry/onDeploy must be null","/body/retry/onDeploy must match a schema in \"anyOf\"","/body/retry must be null","/body/retry must match a schema in \"anyOf\""]
│ 
│   with env0_template.example,
│   on main.tf line 18, in resource "env0_template" "example":
│   18: resource "env0_template" "example" {
│ 
╵

Am I missing something?

Thanks.

Create unit tests

We currently have some integration tests which are great, but we also want unit tests that can be used more frequently during development see #2 for some reference

Provide instructions on how to actually use the provider

Under the current instructions I just get
The "source" attribute must be in the format "[hostname/][namespace/]name"

so

terraform {
  required_providers {
    env0 = {
      source = "terraform-registry.env0.com/"
    }
  }
}

doesn't really work.

We need to provide instructions on how to install and use the provider locally.
After that we can think of publishing it to a registry

Support github integrated templates

  1. Add optional github_installation_id attribute to template resource + data schemas.
  2. Send it on Create/Update operations.
  3. Attach to object on Read. (both resource/data)

Add acceptance tests

We currently use terraform's testing framework for our unit tests, but this framework is genuinely intended for E2E testing (aka Acceptance tests).
This should basically replaces our somewhat problematic harness tests we have today.

Removing a project's description does not work correctly

  1. Create an "env0_project" resource with a description, and terraform apply it
resource "env0_project" "example" {
	name = "example"
	description = "Remove this later"
}
  1. Remove that description line and re-run terraform apply
  2. The description is not really removed from the env0 project

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.