Skip to content
This repository has been archived by the owner on Jul 17, 2023. It is now read-only.

Commit

Permalink
Merge pull request #59 from VJftw/terraform
Browse files Browse the repository at this point in the history
Terraform build_defs
  • Loading branch information
Tatskaari authored Mar 18, 2021
2 parents 841482e + 507df01 commit 675732a
Show file tree
Hide file tree
Showing 30 changed files with 1,011 additions and 1 deletion.
25 changes: 25 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Test
on: [push]
jobs:
terraform:
name: Test Terraform
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2

- name: Terraform lint
run: ./pleasew run sequential --include lint //terraform/...
env:
TF_CLEAN_OUTPUT: "true"

- name: Terraform plan
run: ./pleasew query alltargets //terraform/... | grep "_plan$" | ./pleasew run sequential -
env:
TF_CLEAN_OUTPUT: "true"

- name: Terraform apply
run: ./pleasew query alltargets //terraform/... | grep "_apply$" | ./pleasew run sequential -
env:
TF_CLI_ARGS_apply: "-auto-approve"
TF_CLEAN_OUTPUT: "true"
6 changes: 5 additions & 1 deletion .plzconfig
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[please]
version = >=14.6.0
version = >=15.15.0

[build]
path = /usr/local/bin:/usr/bin:/bin
Expand All @@ -23,6 +23,10 @@ default-docker-repo = repo.please.build
; yarn
yarn-workspace = //js/yarn_workspace_example:workspace
yarn-offline-mirror = js/yarn_workspace_example/third_party
; terraform
terraform-module-builder-src = //terraform/scripts:module_builder
terraform-runner-src = //terraform/scripts:runner
terraform-workspace-builder-src = //terraform/scripts:workspace_builder

[proto]
protoctool = //third_party/proto:protoc
Expand Down
5 changes: 5 additions & 0 deletions terraform/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export_file(
name = "terraform",
src = "terraform.build_defs",
visibility = ["PUBLIC"],
)
86 changes: 86 additions & 0 deletions terraform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
Terraform build rules
=====================

These build defs contain a set of rules for using Terraform configuration with plz.

This includes support for the following:
* `terraform_provider`: Terraform Providers
* `terraform_module`: Terraform Remote Modules
* `terraform_module`: Terraform Local Modules
* `terraform_toolchain`: Multiple versions of Terraform
* Terraform fmt/validate


## `terraform_toolchain`

This build rule allows you to specify a Terraform version to download and re-use in `terraform_root` rules. You can repeat this for multiple versions if you like, see `//third_party/terraform/BUILD` for examples.

## `terraform_provider`

This build rule allows you to specify a [Terraform provider](https://www.terraform.io/docs/providers/index.html) to re-use in your `terraform_root` rules. See `//third_party/terraform/provider/BUILD` for examples.

## `terraform_module`

This build rule allows you to specify a [Terraform module](https://www.terraform.io/docs/language/modules/index.html) to re-use in your `terraform_root` rules or as dependencies in other `terraform_module` rules. Terraform modules can be sourced remotely or exist locally on the filesystem.

See `//third_party/terraform/module/BUILD` for examples of remote Terraform modules.
See `//terraform/examples/<version>/my_module/BUILD` for examples of local terraform modules.

In your Terraform source code, you should refer to your modules by their canonical build label. e.g.:

```
module "remote_module" {
source = "//third_party/terraform/module:a_module"
}
module "my_module" {
source = "//terraform/examples/0.12/my_module:my_module"
}
```

## `terraform_root`

This build rule allows to specify a [Terraform root module](https://www.terraform.io/docs/language/modules/index.html#the-root-module) which is the root configuration where Terraform will be executed. In this build rule, you reference the `srcs` for the root module as well as optionally (but recommended) the providers and modules those `srcs` use. This is optional as we cannot disable the pulling of providers and modules in Terraform 0.13+, so we only pre-populate the Terraform cache. However, it is advisable to use these parameters to reduce network load so that providers and modules are only downloaded once.

We support substitution of the following please build environment variables into your source terraform files:
- `PKG`
- `PKG_DIR`
- `NAME`
- `ARCH`
- `OS`
This allows you to template Terraform code to keep your code DRY. for example: A terraform remote state configuration can that can be re-used in all `terraform_root`s:
```
terraform {
backend "s3" {
region = "eu-west-1"
bucket = "my-terraform-state"
key = "$PKG/$NAME.tfstate"
dynamodb_table = "my-terraform-state-lock"
encrypt = true
}
}
```
The above will result in a terraform state tree consistent with the structure of your repository.

This build rule generates the following subrules which perform the Terraform workflows:
* `_plan`
* `_apply`
* `_destroy`
* `_bin` for all other workflows e.g. `plz run //my_infrastructure_tf_bin -- init && plz run //my_infrastructure_tf_bin -- console`

For all of these workflows, we support passing in flags via please as expected, e.g.:
```
$ plz run //my_tf:my_tf_plan -- -lock=false
$ plz run //my_tf:my_tf_import -- resource_type.my_resource resource_id
```

We also add an environment variable `TF_CLEAN_OUTPUT` which strips noisy Terraform output on a best effort basis. This is incompatible with interactive commands, so we only advise setting this in automation.


It additionally adds linters under the `lint` label for:
* `terraform fmt -check`
* `terraform validate`

See `//terraform/examples/<version>/BUILD` for examples of `terraform_root`.

**NOTE**: This build rule utilises a [Terraform working directory](https://www.terraform.io/docs/cli/init/index.html) in `plz-out`, so whilst this is okay for demonstrations, you must use [Terraform Remote State](https://www.terraform.io/docs/language/state/remote.html) for your regular work. This can be added either simply through your `srcs` or through a `pre_binaries` binary.
14 changes: 14 additions & 0 deletions terraform/examples/0.11/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
subinclude("//terraform")

terraform_root(
name = "example",
srcs = ["main.tf", "data.tf"],
toolchain = "//third_party/terraform:terraform_0_11",
providers = [
"//third_party/terraform/provider:null",
],
modules = [
"//third_party/terraform/module:cloudposse_null_label_0_11",
"//terraform/examples/0.11/my_module:my_module",
]
)
1 change: 1 addition & 0 deletions terraform/examples/0.11/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
resource "null_resource" "empty" {}
27 changes: 27 additions & 0 deletions terraform/examples/0.11/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
provider "null" {
version = "~> 2.1"
}

resource "null_resource" "version" {
provisioner "local-exec" {
command = "terraform version"
}
}

module "label" {
source = "//third_party/terraform/module:cloudposse_null_label_0_11"
namespace = "eg"
stage = "prod"
name = "bastion"
attributes = ["public"]
delimiter = "-"

tags = {
"BusinessUnit" = "XYZ"
"Snapshot" = "true"
}
}

module "my_label" {
source = "//terraform/examples/0.11/my_module:my_module"
}
10 changes: 10 additions & 0 deletions terraform/examples/0.11/my_module/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
subinclude("//terraform")

terraform_module(
name = "my_module",
srcs = ["main.tf", "data.tf"],
deps = [
"//third_party/terraform/module:cloudposse_null_label_0_11",
],
visibility = ["//terraform/examples/0.11/..."],
)
1 change: 1 addition & 0 deletions terraform/examples/0.11/my_module/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
resource "null_resource" "empty" {}
19 changes: 19 additions & 0 deletions terraform/examples/0.11/my_module/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module "label" {
source = "//third_party/terraform/module:cloudposse_null_label_0_11"
namespace = "eg"
stage = "prod"
name = "bastion"
attributes = ["public"]
delimiter = "-"

tags = {
"BusinessUnit" = "XYZ"
"Snapshot" = "true"
}
}

resource "null_resource" "version" {
provisioner "local-exec" {
command = "terraform version"
}
}
14 changes: 14 additions & 0 deletions terraform/examples/0.12/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
subinclude("//terraform")

terraform_root(
name = "example",
srcs = ["main.tf"],
toolchain = "//third_party/terraform:terraform_0_12",
providers = [
"//third_party/terraform/provider:null",
],
modules = [
"//third_party/terraform/module:cloudposse_null_label_0_12",
"//terraform/examples/0.12/my_module:my_module",
]
)
27 changes: 27 additions & 0 deletions terraform/examples/0.12/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
provider "null" {
version = "~> 2.1"
}

resource "null_resource" "version" {
provisioner "local-exec" {
command = "terraform version"
}
}

module "label" {
source = "//third_party/terraform/module:cloudposse_null_label_0_12"
namespace = "eg"
stage = "prod"
name = "bastion"
attributes = ["public"]
delimiter = "-"

tags = {
"BusinessUnit" = "XYZ",
"Snapshot" = "true"
}
}

module "my_label" {
source = "//terraform/examples/0.12/my_module:my_module"
}
10 changes: 10 additions & 0 deletions terraform/examples/0.12/my_module/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
subinclude("//terraform")

terraform_module(
name = "my_module",
srcs = ["main.tf"],
deps = [
"//third_party/terraform/module:cloudposse_null_label_0_12",
],
visibility = ["//terraform/examples/0.12/..."],
)
19 changes: 19 additions & 0 deletions terraform/examples/0.12/my_module/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module "label" {
source = "//third_party/terraform/module:cloudposse_null_label_0_12"
namespace = "eg"
stage = "prod"
name = "bastion"
attributes = ["public"]
delimiter = "-"

tags = {
"BusinessUnit" = "XYZ",
"Snapshot" = "true"
}
}

resource "null_resource" "version" {
provisioner "local-exec" {
command = "terraform version"
}
}
14 changes: 14 additions & 0 deletions terraform/examples/0.13/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
subinclude("//terraform")

terraform_root(
name = "example",
srcs = ["main.tf"],
toolchain = "//third_party/terraform:terraform_0_13",
providers = [
"//third_party/terraform/provider:null",
],
modules = [
"//third_party/terraform/module:cloudposse_null_label_0_12",
"//terraform/examples/0.13/my_module:my_module",
]
)
27 changes: 27 additions & 0 deletions terraform/examples/0.13/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
provider "null" {
version = "~> 2.1"
}

resource "null_resource" "version" {
provisioner "local-exec" {
command = "terraform version"
}
}

module "label" {
source = "//third_party/terraform/module:cloudposse_null_label_0_12"
namespace = "eg"
stage = "prod"
name = "bastion"
attributes = ["public"]
delimiter = "-"

tags = {
"BusinessUnit" = "XYZ",
"Snapshot" = "true"
}
}

module "my_label" {
source = "//terraform/examples/0.13/my_module:my_module"
}
10 changes: 10 additions & 0 deletions terraform/examples/0.13/my_module/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
subinclude("//terraform")

terraform_module(
name = "my_module",
srcs = ["main.tf"],
deps = [
"//third_party/terraform/module:cloudposse_null_label_0_12",
],
visibility = ["//terraform/examples/0.13/..."],
)
19 changes: 19 additions & 0 deletions terraform/examples/0.13/my_module/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module "label" {
source = "//third_party/terraform/module:cloudposse_null_label_0_12"
namespace = "eg"
stage = "prod"
name = "bastion"
attributes = ["public"]
delimiter = "-"

tags = {
"BusinessUnit" = "XYZ",
"Snapshot" = "true"
}
}

resource "null_resource" "version" {
provisioner "local-exec" {
command = "terraform version"
}
}
14 changes: 14 additions & 0 deletions terraform/examples/0.14/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
subinclude("//terraform")

terraform_root(
name = "example",
srcs = ["main.tf"],
toolchain = "//third_party/terraform:terraform_0_14",
providers = [
"//third_party/terraform/provider:null",
],
modules = [
"//third_party/terraform/module:cloudposse_null_label_0_12",
"//terraform/examples/0.14/my_module:my_module",
]
)
Loading

0 comments on commit 675732a

Please sign in to comment.