Skip to content

Commit

Permalink
bt: Terraform checks have extra env vars exported and can run from pa…
Browse files Browse the repository at this point in the history
…rallel stack components

Checks can also save output to a file.
  • Loading branch information
DavidGamba committed Sep 17, 2024
1 parent ae9f763 commit f6ad98a
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 65 deletions.
7 changes: 7 additions & 0 deletions bt/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ terraform_profile: {
}
----

See the link:./config/schema.cue[schema] for extra details.

== Usage Basics

. (optional) Run `bt terraform init` to initialize your config.
Expand Down Expand Up @@ -207,6 +209,9 @@ Pre apply check commands get the following Env vars exported:

* `CONFIG_ROOT`: The dir of the config file.
* `TERRAFORM_JSON_PLAN`: The path to the rendered json plan.
* `TERRAFORM_TXT_PLAN`: The path to the rendered txt plan.
* `TF_WORKSPACE`: The current workspace or "default".
* `BT_COMPONENT`: The current component name if running in stack mode or the basename of the current directory.

If pre-apply checks are enabled in the config file, they can be disabled for the current run using the `--no-checks` option.

Expand Down Expand Up @@ -367,6 +372,8 @@ stack: "prod-us-west-2": {
}
----

See the link:./stack/config/schema.cue[stack schema] for extra details.

=== Usage

==== Config
Expand Down
36 changes: 36 additions & 0 deletions bt/changelog.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
= bt

== v0.8.0: New features

* Terraform checks have extra ENV vars exported and can run from parallel stack components.

* Checks can save output to a file.

== v0.7.0: New features

* Add terraform graph wrapper.

* Add option to run terraform providers lock after init.

* Set default parallelism.

* Enable passing variables from stack definition to component.

* Allow running stack from anywhere under the stacks config file.

== v0.6.0: New features

* Introduce stacks and components workflows.

* Ensure plan and apply output files are dir relative.

* Add dry-run flag.

* Add unit tests.

* expand CONFIG_ROOT on init backend config.

* Use default profile for data dir when none selected.

* Ensure quiet controls logging output.

* Remove error on config file not found.

== v0.5.0: New features

* Better cache invalidation.
Expand Down
7 changes: 4 additions & 3 deletions bt/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ type TerraformProfile struct {
}

type Command struct {
Name string
Command []string
Files []string
Name string
Command []string
Files []string
OutputFile string `json:"output_file,omitempty"`
}

func (t TerraformProfile) String() string {
Expand Down
1 change: 1 addition & 0 deletions bt/config/schema.cue
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ terraform_profile: [ID=_]: #TerraformProfile & {id: ID}
name: string
command: [...string]
files: [...string]
output_file?: string
}
28 changes: 14 additions & 14 deletions bt/go.mod
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
module github.com/DavidGamba/dgtools/bt

go 1.22
go 1.23

require (
github.com/DavidGamba/dgtools/buildutils v0.4.0
github.com/DavidGamba/dgtools/cueutils v0.0.0-20240619042954-1fe1b59646dd
github.com/DavidGamba/dgtools/fsmodtime v0.2.0
github.com/DavidGamba/dgtools/buildutils v0.6.0
github.com/DavidGamba/dgtools/cueutils v0.0.0-20240905043238-7cc0ae242d0a
github.com/DavidGamba/dgtools/fsmodtime v0.3.0
github.com/DavidGamba/dgtools/run v0.9.0
github.com/DavidGamba/go-getoptions v0.30.0
github.com/hashicorp/terraform-config-inspect v0.0.0-20240607080351-271db412dbcb
github.com/hashicorp/terraform-config-inspect v0.0.0-20240801114854-6714b46f5fe4
github.com/mattn/go-isatty v0.0.20
)

require (
cuelang.org/go v0.9.1 // indirect
cuelang.org/go v0.10.0 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/hcl/v2 v2.20.1 // indirect
github.com/hashicorp/hcl/v2 v2.22.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/zclconf/go-cty v1.14.4 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/tools v0.22.0 // indirect
github.com/zclconf/go-cty v1.15.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/tools v0.25.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
74 changes: 38 additions & 36 deletions bt/go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2 h1:BnG6pr9TTr6CYlrJznYUDj6V7xldD1W+1iXPum0wT/w=
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2/go.mod h1:pK23AUVXuNzzTpfMCA06sxZGeVQ/75FdVtW249de9Uo=
cuelang.org/go v0.9.1 h1:SkNkBFMcGpDjjYbbEthAogVP86VA48vRt/KvZ2Xb5OU=
cuelang.org/go v0.9.1/go.mod h1:qpAYsLOf7gTM1YdEg6cxh553uZ4q9ZDWlPbtZr9q1Wk=
github.com/DavidGamba/dgtools/buildutils v0.4.0 h1:9qg5/FJaEKwYYiaRh2fVKgJCPcT2U0u4hTTjQvR4VE0=
github.com/DavidGamba/dgtools/buildutils v0.4.0/go.mod h1:gEikilH0xsJVMydPErNv4mlUPhJGFT5k6v5Ss+Fn+d4=
github.com/DavidGamba/dgtools/cueutils v0.0.0-20240619042954-1fe1b59646dd h1:i212q0x+Ylz9HWo7ov+OgMresTFElJ4R4e2fpB62+VY=
github.com/DavidGamba/dgtools/cueutils v0.0.0-20240619042954-1fe1b59646dd/go.mod h1:M4IQmZFf1qZ9MBMnicn3QlYgjDEmsUMNYrOtu8JKFVY=
github.com/DavidGamba/dgtools/fsmodtime v0.2.0 h1:2GnxhUIsaNzCj1LLrxhKA3wWv9z0KKrY68tIVcXo/QY=
github.com/DavidGamba/dgtools/fsmodtime v0.2.0/go.mod h1:ruwqMvW2pWDbSQlAupP7F0QaojfbuXPyUOUKR4Ev3pQ=
cuelabs.dev/go/oci/ociregistry v0.0.0-20240807094312-a32ad29eed79 h1:EceZITBGET3qHneD5xowSTY/YHbNybvMWGh62K2fG/M=
cuelabs.dev/go/oci/ociregistry v0.0.0-20240807094312-a32ad29eed79/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg=
cuelang.org/go v0.10.0 h1:Y1Pu4wwga5HkXfLFK1sWAYaSWIBdcsr5Cb5AWj2pOuE=
cuelang.org/go v0.10.0/go.mod h1:HzlaqqqInHNiqE6slTP6+UtxT9hN6DAzgJgdbNxXvX8=
github.com/DavidGamba/dgtools/buildutils v0.6.0 h1:sbiwJPAdbXF+Gc8L9C+BldaaMRje/qf5BfVYyp0qBMk=
github.com/DavidGamba/dgtools/buildutils v0.6.0/go.mod h1:j7DC6tKOOoMy4s6ICP220y2jgRlIGpzLH2wXZo2WF7g=
github.com/DavidGamba/dgtools/cueutils v0.0.0-20240905043238-7cc0ae242d0a h1:RzlXYTgnqOfbnt4H8slYzFo4B8Ag86lyjZOq58CuNUM=
github.com/DavidGamba/dgtools/cueutils v0.0.0-20240905043238-7cc0ae242d0a/go.mod h1:M4IQmZFf1qZ9MBMnicn3QlYgjDEmsUMNYrOtu8JKFVY=
github.com/DavidGamba/dgtools/fsmodtime v0.3.0 h1:unnbwD+JSadgcqlBI2v524dWcX6dxqD44TSAP5V7sA8=
github.com/DavidGamba/dgtools/fsmodtime v0.3.0/go.mod h1:ruwqMvW2pWDbSQlAupP7F0QaojfbuXPyUOUKR4Ev3pQ=
github.com/DavidGamba/dgtools/run v0.9.0 h1:Hg0v4ExUMd6Vzf9x9Bqr2yxreZtZpqlcAi8tI86QtIM=
github.com/DavidGamba/dgtools/run v0.9.0/go.mod h1:GVGYL0p5hdBaQ9uIAslXh1g1TTfr0igMSDVTwhhy9q4=
github.com/DavidGamba/go-getoptions v0.30.0 h1:8x69Fc8k/mEWVE0GknpwQ3uGj56MXOUp17egPxCEAG4=
Expand All @@ -20,8 +20,8 @@ github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEa
github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emicklei/proto v1.10.0 h1:pDGyFRVV5RvV+nkBK9iy3q67FBy9Xa7vwrOTE+g5aGw=
github.com/emicklei/proto v1.10.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY=
github.com/emicklei/proto v1.13.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
Expand All @@ -32,10 +32,10 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc=
github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4=
github.com/hashicorp/terraform-config-inspect v0.0.0-20240607080351-271db412dbcb h1:6gCfY5aQdQgRr0G5VDjnV5ENpd+hTamWaZfVz+lJ724=
github.com/hashicorp/terraform-config-inspect v0.0.0-20240607080351-271db412dbcb/go.mod h1:Gz/z9Hbn+4KSp8A2FBtNszfLSdT2Tn/uAKGuVqqWmDI=
github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M=
github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
github.com/hashicorp/terraform-config-inspect v0.0.0-20240801114854-6714b46f5fe4 h1:RwY5HBgtBZ997UtKJAO2Rx+94ETyevwWEVXWx1SL5YY=
github.com/hashicorp/terraform-config-inspect v0.0.0-20240801114854-6714b46f5fe4/go.mod h1:Gz/z9Hbn+4KSp8A2FBtNszfLSdT2Tn/uAKGuVqqWmDI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
Expand All @@ -50,29 +50,31 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 h1:sadMIsgmHpEOGbUs6VtHBXRR1OHevnj7hLx9ZcdNGW4=
github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8=
github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI=
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21 h1:igWZJluD8KtEtAgRyF4x6lqcxDry1ULztksMJh2mnQE=
github.com/rogpeppe/go-internal v1.12.1-0.20240709150035-ccf4b4329d21/go.mod h1:RMRJLmBOqWacUkmJHRMiPKh1S1m3PA7Zh4W80/kWPpg=
github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ=
github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
74 changes: 64 additions & 10 deletions bt/terraform/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func checksRun(ctx context.Context, opt *getoptions.GetOpt, args []string) error
}

cfg := config.ConfigFromContext(ctx)
component := ComponentFromContext(ctx)
dir := DirFromContext(ctx)
LogConfig(cfg, profile)

Expand All @@ -49,6 +50,11 @@ func checksRun(ctx context.Context, opt *getoptions.GetOpt, args []string) error
if err != nil {
return fmt.Errorf("failed to get current dir: %w", err)
}
if component == "." {
component = filepath.Base(cwd)
}
component = strings.Split(component, ":")[0]
Logger.Printf("component: %s\n", component)

ws, err = getWorkspace(cfg, profile, ws, varFiles)
if err != nil {
Expand All @@ -65,12 +71,23 @@ func checksRun(ctx context.Context, opt *getoptions.GetOpt, args []string) error
checkFile = fmt.Sprintf(".tf.check-%s", ws)
}
jsonPlan := planFile + ".json"
os.Setenv("TERRAFORM_JSON_PLAN", jsonPlan)
os.Setenv("CONFIG_ROOT", cfg.ConfigRoot)
txtPlan := planFile + ".txt"
wsEnv := ws
if ws == "" {
wsEnv = "default"
}

env := map[string]string{
"TERRAFORM_JSON_PLAN": jsonPlan,
"TERRAFORM_TXT_PLAN": txtPlan,
"CONFIG_ROOT": cfg.ConfigRoot,
"TF_WORKSPACE": wsEnv,
"BT_COMPONENT": component,
}

cmdFiles := []string{}
for _, cmd := range cfg.TFProfile[cfg.Profile(profile)].PreApplyChecks.Commands {
exp, err := fsmodtime.ExpandEnv(cmd.Files)
exp, err := fsmodtime.ExpandEnv(cmd.Files, env)
if err != nil {
return fmt.Errorf("failed to expand: %w", err)
}
Expand Down Expand Up @@ -114,31 +131,68 @@ func checksRun(ctx context.Context, opt *getoptions.GetOpt, args []string) error
Logger.Printf("missing target: %v\n", checkFile)
}

cmd := []string{cfg.TFProfile[cfg.Profile(profile)].BinaryName, "show", "-json", planFile}
dataDir := fmt.Sprintf("TF_DATA_DIR=%s", getDataDir(cfg.Config.DefaultTerraformProfile, cfg.Profile(profile)))
Logger.Printf("export %s\n", dataDir)
cmd := []string{cfg.TFProfile[cfg.Profile(profile)].BinaryName, "show", "-json", planFile}
ri := run.CMDCtx(ctx, cmd...).Stdin().Log().Env(dataDir).Dir(dir).DryRun(dryRun)
out, err := ri.STDOutOutput()
if err != nil {
return fmt.Errorf("failed to get plan json output: %w", err)
}

err = os.WriteFile(jsonPlan, out, 0600)
err = os.WriteFile(filepath.Join(dir, jsonPlan), out, 0600)
if err != nil {
return fmt.Errorf("failed to write json plan: %w", err)
}
Logger.Printf("plan json written to: %s\n", jsonPlan)

cmd = []string{cfg.TFProfile[cfg.Profile(profile)].BinaryName, "show", planFile}
ri = run.CMDCtx(ctx, cmd...).Stdin().Log().Env(dataDir).Dir(dir).DryRun(dryRun)
out, err = ri.STDOutOutput()
if err != nil {
return fmt.Errorf("failed to get plan json output: %w", err)
}

err = os.WriteFile(filepath.Join(dir, txtPlan), out, 0600)
if err != nil {
return fmt.Errorf("failed to write txt plan: %w", err)
}
Logger.Printf("plan txt written to: %s\n", txtPlan)

for _, cmd := range cfg.TFProfile[cfg.Profile(profile)].PreApplyChecks.Commands {
Logger.Printf("running check: %s\n", cmd.Name)
exp, err := fsmodtime.ExpandEnv(cmd.Command)
exp, err := fsmodtime.ExpandEnv(cmd.Command, env)
if err != nil {
return fmt.Errorf("failed to expand: %w", err)
}
ri := run.CMDCtx(ctx, exp...).Stdin().Log().Env(dataDir).Dir(dir).DryRun(dryRun)
err = ri.Run()
if err != nil {
return fmt.Errorf("failed to run: %w", err)
ri := run.CMDCtx(ctx, exp...).Stdin().Log().
Env(dataDir).
Env(fmt.Sprintf("TERRAFORM_JSON_PLAN=%s", jsonPlan)).
Env(fmt.Sprintf("TERRAFORM_TXT_PLAN=%s", txtPlan)).
Env(fmt.Sprintf("CONFIG_ROOT=%s", cfg.ConfigRoot)).
Env(fmt.Sprintf("TF_WORKSPACE=%s", wsEnv)).
Env(fmt.Sprintf("BT_COMPONENT=%s", component)).
Dir(dir).DryRun(dryRun)
if cmd.OutputFile == "" {
err = ri.Run()
if err != nil {
return fmt.Errorf("failed to run: %w", err)
}
} else {
f, err := fsmodtime.ExpandEnv([]string{cmd.OutputFile}, env)
if err != nil {
return fmt.Errorf("failed to expand: %w", err)
}
fh, err := os.Create(filepath.Join(dir, f[0]))
if err != nil {
return fmt.Errorf("failed to create cmd output file: %w", err)
}
defer fh.Close()
err = ri.Run(fh, os.Stderr)
if err != nil {
return fmt.Errorf("failed to run: %w", err)
}
Logger.Printf("Saving check output to file: %s\n", filepath.Join(dir, f[0]))
}
}

Expand Down
2 changes: 1 addition & 1 deletion bt/terraform/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func initRun(ctx context.Context, opt *getoptions.GetOpt, args []string) error {

for _, bvars := range cfg.TFProfile[cfg.Profile(profile)].Init.BackendConfig {
b := strings.ReplaceAll(bvars, "~", "$HOME")
bb, err := fsmodtime.ExpandEnv([]string{b})
bb, err := fsmodtime.ExpandEnv([]string{b}, nil)
if err != nil {
return fmt.Errorf("failed to expand: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion bt/terraform/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func getDefaultVarFiles(cfg *config.Config, profile string) ([]string, error) {
varFiles := []string{}
for _, vars := range cfg.TFProfile[cfg.Profile(profile)].Plan.VarFile {
v := strings.ReplaceAll(vars, "~", "$HOME")
vv, err := fsmodtime.ExpandEnv([]string{v})
vv, err := fsmodtime.ExpandEnv([]string{v}, nil)
if err != nil {
return varFiles, fmt.Errorf("failed to expand: %w", err)
}
Expand Down

0 comments on commit f6ad98a

Please sign in to comment.