Repository: chanzuckerberg/fogg
Pull request #573 (2021-04-16 19:07:20)

feat[auth0]: adding auth0 provider to fogg
### Summary
This PR adds an Auth0 provider to the fogg configuration so that developers can configure Auth0 terraform using fogg.

### Test Plan
Created new golden files in : https://github.com/chanzuckerberg/fogg/blob/692206a991fc8a5c52334e3a66ace53deb04af33/apply/golden_file_test.go

### References
https://github.com/alexkappa/terraform-provider-auth0


codecov[bot]: # [Codecov](https://codecov.io/gh/chanzuckerberg/fogg/pull/573?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chanzuckerberg) Report
> :exclamation: No coverage uploaded for pull request base (`main@8049518`). [Click here to learn what that means](https://docs.codecov.io/docs/error-reference?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chanzuckerberg#section-missing-base-commit).
> The diff coverage is `n/a`.

> :exclamation: Current head db7f3d0 differs from pull request most recent head 0b4d842. Consider uploading reports for the commit 0b4d842 to get more accurate results
[![Impacted file tree graph](https://codecov.io/gh/chanzuckerberg/fogg/pull/573/graphs/tree.svg?width=650&height=150&src=pr&token=57DhtZ7g2A&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chanzuckerberg)](https://codecov.io/gh/chanzuckerberg/fogg/pull/573?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chanzuckerberg)

```diff
@@           Coverage Diff           @@
##             main     #573   +/-   ##
=======================================
  Coverage        ?   55.27%           
=======================================
  Files           ?       21           
  Lines           ?     2106           
  Branches        ?        0           
=======================================
  Hits            ?     1164           
  Misses          ?      783           
  Partials        ?      159           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/chanzuckerberg/fogg/pull/573?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chanzuckerberg).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chanzuckerberg)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/chanzuckerberg/fogg/pull/573?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chanzuckerberg). Last update [8049518...0b4d842](https://codecov.io/gh/chanzuckerberg/fogg/pull/573?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chanzuckerberg). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=chanzuckerberg).


Patch:
diff --git a/config/v2/config.go b/config/v2/config.go
index f43a79ab..0575ae8d 100644
--- a/config/v2/config.go
+++ b/config/v2/config.go
@@ -117,6 +117,7 @@ type Component struct {
 }
 
 type Providers struct {
+	Auth0      *Auth0Provider      `yaml:"auth0,omitempty"`
 	AWS        *AWSProvider        `yaml:"aws,omitempty"`
 	Bless      *BlessProvider      `yaml:"bless,omitempty"`
 	Databricks *DatabricksProvider `yaml:"databricks,omitempty"`
@@ -139,6 +140,12 @@ type CommonProvider struct {
 	Version *string `yaml:"version,omitempty"`
 }
 
+//Auth0Provider is the terraform provider for the Auth0 service.
+type Auth0Provider struct {
+	Version *string `yaml:"version,omitempty"`
+	Domain  *string `yaml:"domain,omitempty"`
+}
+
 // OktaProvider is an okta provider
 type OktaProvider struct {
 	// the okta provider is optional (above) but if supplied you must set an OrgName
@@ -394,6 +401,13 @@ func (c *Config) Generate(r *rand.Rand, size int) reflect.Value {
 		return map[string]string{}
 	}
 
+	randAuth0Provider := func(r *rand.Rand, s int) *Auth0Provider {
+		return &Auth0Provider{
+			Version: randStringPtr(r, s),
+			Domain:  randStringPtr(r, s),
+		}
+	}
+
 	randOktaProvider := func(r *rand.Rand, s int) *OktaProvider {
 		if r.Float32() < 0.5 {
 			return nil
@@ -519,6 +533,7 @@ func (c *Config) Generate(r *rand.Rand, size int) reflect.Value {
 			Owner:     randStringPtr(r, s),
 			Project:   randStringPtr(r, s),
 			Providers: &Providers{
+				Auth0:      randAuth0Provider(r, s),
 				AWS:        randAWSProvider(r, s),
 				Bless:      randBlessProvider(r, s),
 				Datadog:    randDatadogProvider(r),
diff --git a/config/v2/resolvers.go b/config/v2/resolvers.go
index 307b38a8..0146a084 100644
--- a/config/v2/resolvers.go
+++ b/config/v2/resolvers.go
@@ -79,7 +79,28 @@ func ResolveStringMap(getter func(Common) map[string]string, commons ...Common)
 	return resolved
 }
 
-// ResolveAWSProvider will return an AWSProvder iff one of the required fields is set somewhere in
+func ResolveAuth0Provider(commons ...Common) *Auth0Provider {
+	var domain, version *string
+	for _, c := range commons {
+		if c.Providers == nil || c.Providers.Auth0 == nil {
+			continue
+		}
+		if c.Providers.Auth0.Version != nil {
+			version = c.Providers.Auth0.Version
+		}
+
+		if c.Providers.Auth0.Domain != nil {
+			domain = c.Providers.Auth0.Domain
+		}
+	}
+
+	if domain != nil && version != nil {
+		return &Auth0Provider{Version: version, Domain: domain}
+	}
+	return nil
+}
+
+// ResolveAWSProvider will return an AWSProvder if one of the required fields is set somewhere in
 // the set of Common config objects passed in. Otherwise it will return nil.
 func ResolveAWSProvider(commons ...Common) *AWSProvider {
 	var profile, region, role, version *string
diff --git a/go.mod b/go.mod
index 5ec918d0..a99239d8 100644
--- a/go.mod
+++ b/go.mod
@@ -39,14 +39,17 @@ require (
 	github.com/mitchellh/go-wordwrap v1.0.1 // indirect
 	github.com/peterbourgon/diskv v2.0.1+incompatible
 	github.com/pkg/errors v0.9.1
+	github.com/rogpeppe/go-internal v1.8.0 // indirect
 	github.com/segmentio/go-prompt v1.2.1-0.20161017233205-f0d19b6901ad
 	github.com/sirupsen/logrus v1.8.1
 	github.com/spf13/afero v1.2.2
 	github.com/spf13/cobra v1.1.3
 	github.com/stretchr/testify v1.7.0
 	golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
-	golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 // indirect
-	golang.org/x/term v0.0.0-20210317153231-de623e64d2a6 // indirect
+	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
+	golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
+	golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 // indirect
+	golang.org/x/tools v0.1.0 // indirect
 	gopkg.in/go-playground/validator.v9 v9.31.0
 	gopkg.in/ini.v1 v1.62.0
 	gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
diff --git a/go.sum b/go.sum
index 46aef98c..0bc36eb2 100644
--- a/go.sum
+++ b/go.sum
@@ -695,6 +695,7 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
 github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
+github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -731,6 +732,8 @@ github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYe
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.5.2 h1:qLvObTrvO/XRCqmkKxUlOBc48bI3efyDuAZe25QiF0w=
 github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
+github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
 github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -836,6 +839,7 @@ github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZ
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/zalando/go-keyring v0.1.0/go.mod h1:RaxNwUITJaHVdQ0VC7pELPZ3tOWn13nr0gZMZEhpVU0=
 github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
@@ -986,6 +990,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1039,11 +1045,12 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 h1:rF3Ohx8DRyl8h2zw9qojyLHLhrJpEMgyPOImREEryf0=
-golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210317153231-de623e64d2a6 h1:EC6+IGYTjPpRfv9a2b/6Puw0W+hLtAhkV1tPsXhutqs=
-golang.org/x/term v0.0.0-20210317153231-de623e64d2a6/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 h1:VqE9gduFZ4dbR7XoL77lHFp0/DyDUBKSXK7CMFkVcV0=
+golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1116,6 +1123,8 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
 golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
 golang.org/x/tools v0.0.0-20201028111035-eafbe7b904eb h1:KVWk3RW1AZlxWum4tYqegLgwJHb5oouozcGM8HfNQaw=
 golang.org/x/tools v0.0.0-20201028111035-eafbe7b904eb/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/plan/plan.go b/plan/plan.go
index e9457855..a3ee76e9 100644
--- a/plan/plan.go
+++ b/plan/plan.go
@@ -121,6 +121,7 @@ func (c CIComponent) generateCIConfig(
 }
 
 type ProviderConfiguration struct {
+	Auth0                  *Auth0Provider      `yaml:"auth0"`
 	AWS                    *AWSProvider        `yaml:"aws"`
 	AWSAdditionalProviders []AWSProvider       `yaml:"aws_regional_providers"`
 	Bless                  *BlessProvider      `yaml:"bless"`
@@ -199,6 +200,10 @@ type GithubProvider struct {
 	BaseURL      *string `yaml:"base_url"`
 }
 
+type Auth0Provider struct {
+	Domain string `yaml:"domain,omitempty"`
+}
+
 //SnowflakeProvider represents Snowflake DB provider configuration
 type SnowflakeProvider struct {
 	Account string `yaml:"account,omitempty"`
@@ -613,6 +618,19 @@ func resolveComponentCommon(commons ...v2.Common) ComponentCommon {
 		}
 	}
 
+	var auth0Plan *Auth0Provider
+	auth0Config := v2.ResolveAuth0Provider(commons...)
+	if auth0Config != nil {
+		auth0Plan = &Auth0Provider{
+			Domain: *auth0Config.Domain,
+		}
+
+		providerVersions["auth0"] = ProviderVersion{
+			Source:  "alexkappa/auth0",
+			Version: auth0Config.Version,
+		}
+	}
+
 	var githubPlan *GithubProvider
 	githubConfig := v2.ResolveGithubProvider(commons...)
 
@@ -854,6 +872,7 @@ func resolveComponentCommon(commons ...v2.Common) ComponentCommon {
 	return ComponentCommon{
 		Backend: backend,
 		ProviderConfiguration: ProviderConfiguration{
+			Auth0:                  auth0Plan,
 			AWS:                    awsPlan,
 			AWSAdditionalProviders: additionalProviders,
 			Bless:                  blessPlan,
diff --git a/templates/common/auth0_provider.tmpl b/templates/common/auth0_provider.tmpl
new file mode 100644
index 00000000..1758b048
--- /dev/null
+++ b/templates/common/auth0_provider.tmpl
@@ -0,0 +1,5 @@
+{{ define "auth0_provider" }}
+provider auth0 {
+  domain = "{{ .Domain }}"
+}
+{{ end }}
diff --git a/templates/component/terraform/fogg.tf.tmpl b/templates/component/terraform/fogg.tf.tmpl
index 4f8e4681..d31445cf 100644
--- a/templates/component/terraform/fogg.tf.tmpl
+++ b/templates/component/terraform/fogg.tf.tmpl
@@ -42,6 +42,9 @@
     {{ template "sentry_provider" .ProviderConfiguration.Sentry }}
 {{ end }}{{ end }}
 
+{{ if .ProviderConfiguration.Auth0 }}
+  {{ template "auth0_provider" .ProviderConfiguration.Auth0 }}
+{{ end }}
 
 terraform {
   required_version = "={{ .TerraformVersion }}"


Test patch:
diff --git a/apply/golden_file_test.go b/apply/golden_file_test.go
index f76bf3e6..d09a9d48 100644
--- a/apply/golden_file_test.go
+++ b/apply/golden_file_test.go
@@ -22,6 +22,7 @@ func TestIntegration(t *testing.T) {
 	var testCases = []struct {
 		fileName string
 	}{
+		{"auth0_provider_yaml"},
 		{"okta_provider_yaml"},
 		{"github_provider_yaml"},
 		{"bless_provider_yaml"},
diff --git a/testdata/auth0_provider_yaml/.fogg-version b/testdata/auth0_provider_yaml/.fogg-version
new file mode 100644
index 00000000..64e78fd8
--- /dev/null
+++ b/testdata/auth0_provider_yaml/.fogg-version
@@ -0,0 +1,1 @@
+undefined-pre+undefined.dirty
\ No newline at end of file
diff --git a/testdata/auth0_provider_yaml/.gitattributes b/testdata/auth0_provider_yaml/.gitattributes
new file mode 100644
index 00000000..ebf21819
--- /dev/null
+++ b/testdata/auth0_provider_yaml/.gitattributes
@@ -0,0 +1,5 @@
+fogg.tf linguist-generated
+Makefile linguist-generated
+.travis.yml linguist-generated
+.circleci/config.yml linguist-generated
+.terraformignore linguist-generated
diff --git a/testdata/auth0_provider_yaml/.gitignore b/testdata/auth0_provider_yaml/.gitignore
new file mode 100644
index 00000000..16291b8b
--- /dev/null
+++ b/testdata/auth0_provider_yaml/.gitignore
@@ -0,0 +1,38 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+# Compiled files
+*.tfstate
+*.tfstate.*.backup
+*.tfstate.backup
+*tfvars
+
+# Module directory
+.terraform/
+
+# Pycharm folder
+.idea
+
+# Editor Swap Files
+*.swp
+*.swo
+*.swn
+*.swm
+*.swl
+*.swk
+
+.fogg
+/terraform.d/plugins
+/terraform.d/modules
+
+.DS_Store
+.vscode
+.envrc
+
+# Scala language server
+.metals
+
+buildevents.plan
+check-plan.output
+
+venv
diff --git a/testdata/auth0_provider_yaml/.terraform.d/plugin-cache/.gitignore b/testdata/auth0_provider_yaml/.terraform.d/plugin-cache/.gitignore
new file mode 100644
index 00000000..504d4d91
--- /dev/null
+++ b/testdata/auth0_provider_yaml/.terraform.d/plugin-cache/.gitignore
@@ -0,0 +1,5 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+*
+!.gitignore
diff --git a/testdata/auth0_provider_yaml/.terraformignore b/testdata/auth0_provider_yaml/.terraformignore
new file mode 100644
index 00000000..e472f375
--- /dev/null
+++ b/testdata/auth0_provider_yaml/.terraformignore
@@ -0,0 +1,10 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+
+.fogg/
+terraform.d/**
+**/terraform.d
+**/.terraform.d/**
+**/.terraform/**
+**/.git/**
diff --git a/testdata/auth0_provider_yaml/Makefile b/testdata/auth0_provider_yaml/Makefile
new file mode 100644
index 00000000..a688b05a
--- /dev/null
+++ b/testdata/auth0_provider_yaml/Makefile
@@ -0,0 +1,150 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+include scripts/common.mk
+
+ENVS=bar
+MODULES=
+ACCOUNTS=foo
+
+all: check
+
+setup: ## set up working directory by installing dependencies
+	curl -s https://raw.githubusercontent.com/chanzuckerberg/fogg/vundefined-pre+undefined.dirty/download.sh | bash -s -- -b .fogg/bin vundefined-pre+undefined.dirty
+	.fogg/bin/fogg setup
+.PHONY: setup
+
+lint: lint-terraform ## lint the code in this repo
+.PHONY: lint
+
+lint-terraform: lint-accounts lint-envs lint-modules ## lint the terraform code in this repo
+.PHONY: lint-terraform
+
+lint-accounts:  ## lint the terrarform code in terraform/accounts
+	@for account in $(ACCOUNTS); do \
+		$(MAKE) -C terraform/accounts/$$account lint || exit $$?; \
+	done
+.PHONY: lint-accounts
+
+lint-envs: ## lint the terraform code in terraform/envs
+	@for env in $(ENVS); do \
+		$(MAKE) -C terraform/envs/$$env lint || exit $$?; \
+	done; \
+	$(MAKE) -C terraform/global lint || exit $$?
+.PHONY: lint-envs
+
+lint-modules: ## lint the terraform code in terraform/modules
+	@for module in $(MODULES); do \
+		$(MAKE) -C terraform/modules/$$module lint || exit $$?; \
+	done
+.PHONY: lint-modules
+
+fmt: fmt-fogg fmt-accounts fmt-envs fmt-global fmt-modules ## format code in this repo
+.PHONY: fmt
+
+fmt-fogg:
+	.fogg/bin/fogg fmt
+.PHONY: fmt-fogg
+
+fmt-accounts: ## format code in terraform/accounts
+	@for account in $(ACCOUNTS); do \
+		$(MAKE) -C terraform/accounts/$$account fmt || exit $$?; \
+	done
+.PHONY: fmt-accounts
+
+fmt-envs: ## format the code in teraform/envs
+	@for env in $(ENVS); do \
+		$(MAKE) -C terraform/envs/$$env fmt || exit $$?; \
+	done
+.PHONY: fmt-envs
+
+fmt-global: ## format the code in terraform/global
+	$(MAKE) -C terraform/global fmt || exit $$?
+.PHONY: fmt-global
+
+fmt-modules:  ## format the code in terraform/modules
+	@for module in $(MODULES); do \
+		$(MAKE) -C terraform/modules/$$module fmt || exit $$?; \
+	done
+.PHONY: fmt-modules
+
+docs: docs-envs docs-global docs-modules ## update docs
+.PHONY: docs
+
+docs-accounts: ## update docs in terraform/accounts
+	@for account in $(ACCOUNTS); do \
+		$(MAKE) -C terraform/accounts/$$account docs || exit $$?; \
+	done
+.PHONY: docs-accounts
+
+docs-envs: ## update the docs in terraform/envs
+	@for env in $(ENVS); do \
+		$(MAKE) -C terraform/envs/$$env docs || exit $$?; \
+	done
+.PHONY: docs-envs
+
+docs-global: ## update the docs in terraform/global
+	$(MAKE) -C terraform/global docs || exit $$?;
+.PHONY: docs-global
+
+docs-modules: ## update the docs in terraform/modules
+	@for module in $(MODULES); do \
+		$(MAKE) -C terraform/modules/$$module docs || exit $$?; \
+	done
+.PHONY: docs-modules
+
+test:
+.PHONY: test
+
+check: check-plan check-docs ## check all code in the repo
+.PHONY: check
+
+check-plan: check-plan-accounts check-plan-envs check-plan-global ## check terraform plans across all components
+.PHONY: check-plan
+
+check-plan-accounts: ## check terraform plans in terraform/accounts
+	@for account in $(ACCOUNTS); do \
+		$(MAKE) -C terraform/accounts/$$account check-plan || exit $$?; \
+	done
+.PHONY: check-plan-accounts
+
+check-plan-envs: ## check terraform plans in terraform/envs
+	@for env in $(ENVS); do \
+		$(MAKE) -C terraform/envs/$$env check-plan || exit $$?; \
+	done
+.PHONY: check-plan-envs
+
+check-plan-global: ## check terraform plans in terraform/global
+	$(MAKE) -C terraform/global check-plan || exit $$?
+.PHONY: check-plan-global
+
+check-docs: ## check terraform docs
+	@for mod in $(MODULES); do \
+		$(MAKE) -C terraform/modules/$$module check-docs || exit $$?; \
+	done
+.PHONY: check-docs
+
+clean: clean-accounts clean-envs clean-global ## clean the repo
+.PHONY: clean
+
+clean-accounts: ## clean in terraform/accounts
+	@for account in $(ACCOUNTS); do \
+		$(MAKE) -C terraform/accounts/$$account clean || exit $$?; \
+	done
+.PHONY: clean-accounts
+
+clean-envs: ## clean in terraform/envs
+	@for env in $(ENVS); do \
+		$(MAKE) -C terraform/envs/$$env clean || exit $$?; \
+	done
+.PHONY: clean-envs
+
+clean-global: ## clean in terraform/global
+	$(MAKE) -C terraform/global clean || exit $$?
+.PHONY: clean-global
+
+
+help: ## display help for this makefile
+	@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+.PHONY: help
+
diff --git a/testdata/auth0_provider_yaml/README.md b/testdata/auth0_provider_yaml/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/fogg.yml b/testdata/auth0_provider_yaml/fogg.yml
new file mode 100644
index 00000000..4c8aa63d
--- /dev/null
+++ b/testdata/auth0_provider_yaml/fogg.yml
@@ -0,0 +1,29 @@
+{
+    "version": 2,
+    "defaults": {
+        "providers": {
+            "auth0": {
+                "domain": "adomain",
+                "version": "aversion"
+            }
+        },
+        "backend": {
+            "bucket": "bucket",
+            "region": "region",
+            "profile": "foofoo"
+        },
+        "project": "foofoo",
+        "owner": "foo@example.com",
+        "terraform_version": "1.1.1"
+    },
+    "accounts": {
+        "foo": {}
+    },
+    "envs": {
+        "bar": {
+            "components": {
+                "bam": {}
+            }
+        }
+    }
+}
diff --git a/testdata/auth0_provider_yaml/scripts/common.mk b/testdata/auth0_provider_yaml/scripts/common.mk
new file mode 100644
index 00000000..0a154791
--- /dev/null
+++ b/testdata/auth0_provider_yaml/scripts/common.mk
@@ -0,0 +1,32 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+SHELL=/bin/bash -o pipefail
+TF_VARS := $(patsubst %,-e%,$(filter TF_VAR_%,$(.VARIABLES)))
+REPO_ROOT := $(shell git rev-parse --show-toplevel)
+REPO_RELATIVE_PATH := $(shell git rev-parse --show-prefix)
+AUTO_APPROVE := false
+export AWS_SDK_LOAD_CONFIG := 1
+
+TFENV_DIR ?= $(REPO_ROOT)/.fogg/tfenv
+export PATH :=$(TFENV_DIR)/libexec:$(TFENV_DIR)/versions/$(TERRAFORM_VERSION)/:$(REPO_ROOT)/.fogg/bin:$(PATH)
+export TF_PLUGIN_CACHE_DIR=$(REPO_ROOT)/.terraform.d/plugin-cache
+export TF_IN_AUTOMATION=1
+terraform_command ?= $(TFENV_DIR)/versions/$(TERRAFORM_VERSION)/terraform
+
+ifeq ($(TF_BACKEND_KIND),remote)
+	REFRESH := true
+else
+	REFRESH := false
+endif
+
+
+tfenv: ## install the tfenv tool
+	@if [ ! -d ${TFENV_DIR} ]; then \
+		git clone -q https://github.com/chanzuckerberg/tfenv.git $(TFENV_DIR); \
+	fi
+.PHONY: tfenv
+
+terraform: tfenv ## ensure that the proper version of terraform is installed
+	@${TFENV_DIR}/bin/tfenv install $(TERRAFORM_VERSION)
+.PHONY: terraform
diff --git a/testdata/auth0_provider_yaml/scripts/component.mk b/testdata/auth0_provider_yaml/scripts/component.mk
new file mode 100644
index 00000000..2eb92973
--- /dev/null
+++ b/testdata/auth0_provider_yaml/scripts/component.mk
@@ -0,0 +1,135 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+SELF_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
+CHECK_PLANFILE_PATH ?= check-plan.output
+
+include $(SELF_DIR)/common.mk
+
+all:
+.PHONY: all
+
+setup: ## set up local dependencies for this repo
+	$(MAKE) -C $(REPO_ROOT) setup
+.PHONY: setup
+
+check: lint check-plan ## run all checks for this component
+.PHONY: check
+
+fmt: terraform ## format code in this component
+	$(terraform_command) fmt $(TF_ARGS)
+.PHONY: fmt
+
+lint: lint-terraform-fmt lint-tflint ## run all linters for this component
+.PHONY: lint
+
+lint-tflint: ## run the tflint linter for this component
+	@printf "tflint: "
+ifeq ($(TFLINT_ENABLED),1)
+	@tflint || exit $$?;
+else
+	@echo "disabled"
+endif
+.PHONY: lint-tflint
+
+lint-terraform-fmt: terraform ## run `terraform fmt` in check mode
+	@printf "fmt check: "
+	@for f in $(TF); do \
+		printf . \
+		$(terraform_command) fmt $(TF_ARGS) --check=true --diff=true $$f || exit $$? ; \
+	done
+	@echo
+.PHONY: lint-terraform-fmt
+
+check-auth: check-auth-aws check-auth-heroku ## check that authentication is properly set up for this component
+.PHONY: check-auth
+
+check-auth-aws:
+	@for p in $(AWS_BACKEND_PROFILE) $(AWS_PROVIDER_PROFILE); do \
+		aws --profile $$p sts get-caller-identity > /dev/null || (echo "AWS AUTH error. This component is configured to use a profile named '$$p'. Please add one to your ~/.aws/config" && exit -1); \
+	done
+	@for r in $(AWS_BACKEND_ROLE_ARN) $(AWS_PROVIDER_ROLE_ARN); do \
+		aws sts assume-role --role-arn $$r --role-session-name fogg-auth-test > /dev/null || (echo "AWS AUTH error. This component is configured to use a role named '$$r'." && exit -1); \
+	done
+.PHONY: check-auth-aws
+
+check-auth-heroku:
+ifeq ($(HEROKU_PROVIDER),1)
+	@echo "Checking heroku auth..."
+	@if command heroku >/dev/null; then \
+		heroku auth:whoami || timeout 15 heroku auth:login || (echo "Not authenticated to heroku. For SSO accounts, run 'heroku login', for non-sso accounts set HEROKU_EMAIL and HEROKU_API_KEY" && exit -1); \
+	else \
+		echo "Heroku CLI not installed, can't check auth."; \
+	fi
+endif
+.PHONY: check-auth-heroku
+
+refresh:
+	@if [ "$(TF_BACKEND_KIND)" != "remote" ]; then \
+		$(terraform_command) refresh $(TF_ARGS); \
+		date +%s > .terraform/refreshed_at; \
+	else \
+		echo "remote backend does not support the refresh command, skipping"; \
+	fi
+.PHONY: refresh
+
+refresh-cached:
+	@last_refresh=`cat .terraform/refreshed_at 2>/dev/null || echo '0'`; \
+	current_time=`date +%s`; \
+	if (( current_time - last_refresh > 600 )); then \
+		echo "It has been awhile since the last refresh. It is time."; \
+		$(MAKE) refresh; \
+	else \
+		echo "Not time to refresh yet."; \
+	fi;
+.PHONY: refresh-cached
+
+plan: check-auth init fmt refresh-cached ## run a terraform plan
+	$(terraform_command) plan $(TF_ARGS) -refresh=$(REFRESH) -input=false
+.PHONY: plan
+
+apply: check-auth init refresh ## run a terraform apply
+	@$(terraform_command) apply $(TF_ARGS) -refresh=$(REFRESH) -auto-approve=$(AUTO_APPROVE)
+.PHONY: apply
+
+docs:
+	echo
+.PHONY: docs
+
+clean: ## clean modules and plugins for this component
+	-rm -rfv .terraform/modules
+	-rm -rfv .terraform/plugins
+.PHONY: clean
+
+test:
+.PHONY: test
+
+init: terraform check-auth ## run terraform init for this component
+	@$(terraform_command) init -input=false
+.PHONY: init
+
+check-plan: check-auth init refresh-cached ## run a terraform plan and check that it does not fail
+	@if [ "$(TF_BACKEND_KIND)" != "remote" ]; then \
+		$(terraform_command) plan $(TF_ARGS) -detailed-exitcode -lock=false -refresh=$(REFRESH) -out=$(CHECK_PLANFILE_PATH) ; \
+		ERR=$$?; \
+		if [ -n "$(BUILDEVENT_FILE)" ]; then \
+			fogg exp entropy -f $(CHECK_PLANFILE_PATH) -o $(BUILDEVENT_FILE) ; \
+		fi; \
+		rm $(CHECK_PLANFILE_PATH) 2>/dev/null; \
+	else \
+		$(terraform_command) plan $(TF_ARGS) -detailed-exitcode -lock=false; \
+		ERR=$$?; \
+	fi; \
+	if [ $$ERR -eq 0 ] ; then \
+		echo "Success"; \
+	elif [ $$ERR -eq 1 ] ; then \
+		echo "Error in plan execution."; \
+		exit 1; \
+	elif [ $$ERR -eq 2 ] ; then \
+		echo "Diff";  \
+	fi;
+.PHONY: check-plan
+
+run: check-auth ## run an arbitrary terraform command, CMD. ex `make run CMD='show'`
+	@$(terraform_command) $(CMD)
+.PHONY: run
diff --git a/testdata/auth0_provider_yaml/scripts/failed_output_only b/testdata/auth0_provider_yaml/scripts/failed_output_only
new file mode 100644
index 00000000..a21d3dab
--- /dev/null
+++ b/testdata/auth0_provider_yaml/scripts/failed_output_only
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+t=`mktemp` && \
+exec $@  2>&1 > $t || \
+(
+    a=$?;
+    echo $a;
+    cat $t;
+    rm $t;
+    exit $a
+)
+
+
diff --git a/testdata/auth0_provider_yaml/scripts/module.mk b/testdata/auth0_provider_yaml/scripts/module.mk
new file mode 100644
index 00000000..d8353c0d
--- /dev/null
+++ b/testdata/auth0_provider_yaml/scripts/module.mk
@@ -0,0 +1,49 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+SELF_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
+
+include $(SELF_DIR)/common.mk
+
+all: fmt lint doc
+.PHONY: all
+
+fmt: terraform ## run terraform fmt on this module
+	@printf "fmt: ";
+	@for f in $(TF); do printf .; $(terraform_command) fmt $(TF_ARGS) $$f; done
+	@echo
+.PHONY: fmt
+
+check: lint check-docs ## run all checks on this module
+.PHONY: check
+
+lint: lint-tf ## run all linters on this module
+.PHONY: lint
+
+lint-tf: terraform ## run terraform linters on this module
+	@printf "fmt: ";
+	@for f in $(TF); do \
+	  printf .; $(terraform_command) fmt $(TF_ARGS) --check=true --diff=true || exit $$? ; \
+	done
+	@echo
+.PHONY: lint-tf
+
+readme: ## update this module's README.md 
+	bash $(REPO_ROOT)/scripts/update-readme.sh update
+.PHONY: readme
+
+docs: readme ## update all docs for this module
+.PHONY: docs
+
+check-docs: ## check that this module's docs are up-to-date
+	@bash $(REPO_ROOT)/scripts/update-readme.sh check; \
+	if [ ! $$? -eq 0 ];  then \
+		echo "Docs are out of date, run \`make docs\`"; \
+	fi
+.PHONY: check-docs
+
+clean:
+.PHONY: clean
+
+test:
+.PHONY: test
diff --git a/testdata/auth0_provider_yaml/scripts/update-readme.sh b/testdata/auth0_provider_yaml/scripts/update-readme.sh
new file mode 100644
index 00000000..abe8fb47
--- /dev/null
+++ b/testdata/auth0_provider_yaml/scripts/update-readme.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+# I would have written this directly in the Makefile, but that was difficult.
+
+CMD="$1"
+
+TMP=`mktemp`
+TMP2=`mktemp`
+terraform-docs md . > "$TMP"
+sed '/^<!-- START -->$/,/<!-- END -->/{//!d;}' README.md | sed "/^<!-- START -->$/r $TMP" > $TMP2
+
+case "$CMD" in
+    update)
+        mv $TMP2 README.md
+    ;;
+    check)
+        diff $TMP2 README.md >/dev/null
+    ;;
+esac
+
+exit $?
diff --git a/testdata/auth0_provider_yaml/terraform.d/.keep b/testdata/auth0_provider_yaml/terraform.d/.keep
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/accounts/foo/Makefile b/testdata/auth0_provider_yaml/terraform/accounts/foo/Makefile
new file mode 100644
index 00000000..f3b9270b
--- /dev/null
+++ b/testdata/auth0_provider_yaml/terraform/accounts/foo/Makefile
@@ -0,0 +1,20 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+
+export TERRAFORM_VERSION := 1.1.1
+export TFLINT_ENABLED := 0
+export TF_PLUGIN_CACHE_DIR := ../../..//.terraform.d/plugin-cache
+export TF_BACKEND_KIND := s3
+
+export AWS_BACKEND_PROFILE := foofoo
+
+
+
+include ../../..//scripts/component.mk
+
+
+help: ## display help for this makefile
+	@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+.PHONY: help
+
diff --git a/testdata/auth0_provider_yaml/terraform/accounts/foo/README.md b/testdata/auth0_provider_yaml/terraform/accounts/foo/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/accounts/foo/fogg.tf b/testdata/auth0_provider_yaml/terraform/accounts/foo/fogg.tf
new file mode 100644
index 00000000..22455fe7
--- /dev/null
+++ b/testdata/auth0_provider_yaml/terraform/accounts/foo/fogg.tf
@@ -0,0 +1,137 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+provider auth0 {
+  domain = "adomain"
+}
+terraform {
+  required_version = "=1.1.1"
+
+  backend s3 {
+
+    bucket = "bucket"
+
+    key     = "terraform/foofoo/accounts/foo.tfstate"
+    encrypt = true
+    region  = "region"
+    profile = "foofoo"
+
+
+  }
+  required_providers {
+
+    archive = {
+      source = "hashicorp/archive"
+
+      version = "~> 2.0"
+
+    }
+
+    auth0 = {
+      source = "alexkappa/auth0"
+
+      version = "aversion"
+
+    }
+
+    local = {
+      source = "hashicorp/local"
+
+      version = "~> 2.0"
+
+    }
+
+    null = {
+      source = "hashicorp/null"
+
+      version = "~> 3.0"
+
+    }
+
+    random = {
+      source = "hashicorp/random"
+
+      version = "~> 2.2"
+
+    }
+
+    template = {
+      source = "hashicorp/template"
+
+      version = "~> 2.2"
+
+    }
+
+    tls = {
+      source = "hashicorp/tls"
+
+      version = "~> 3.0"
+
+    }
+
+  }
+}
+variable env {
+  type    = string
+  default = "accounts"
+}
+variable project {
+  type    = string
+  default = "foofoo"
+}
+variable component {
+  type    = string
+  default = "foo"
+}
+variable account {
+  type    = string
+  default = "foo"
+}
+variable owner {
+  type    = string
+  default = "foo@example.com"
+}
+variable tags {
+  type = object({ project : string, env : string, service : string, owner : string, managedBy : string })
+  default = {
+    project   = "foofoo"
+    env       = "accounts"
+    service   = "foo"
+    owner     = "foo@example.com"
+    managedBy = "terraform"
+  }
+}
+data terraform_remote_state global {
+  backend = "s3"
+  config = {
+
+
+    bucket = "bucket"
+
+    key     = "terraform/foofoo/global.tfstate"
+    region  = "region"
+    profile = "foofoo"
+
+
+  }
+}
+data terraform_remote_state foo {
+  backend = "s3"
+  config = {
+
+
+    bucket = "bucket"
+
+    key     = "terraform/foofoo/accounts/foo.tfstate"
+    region  = "region"
+    profile = "foofoo"
+
+
+  }
+}
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
diff --git a/testdata/auth0_provider_yaml/terraform/accounts/foo/main.tf b/testdata/auth0_provider_yaml/terraform/accounts/foo/main.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/accounts/foo/outputs.tf b/testdata/auth0_provider_yaml/terraform/accounts/foo/outputs.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/accounts/foo/terraform.d b/testdata/auth0_provider_yaml/terraform/accounts/foo/terraform.d
new file mode 120000
index 00000000..29617d28
--- /dev/null
+++ b/testdata/auth0_provider_yaml/terraform/accounts/foo/terraform.d
@@ -0,0 +1,1 @@
+../../../terraform.d
\ No newline at end of file
diff --git a/testdata/auth0_provider_yaml/terraform/accounts/foo/variables.tf b/testdata/auth0_provider_yaml/terraform/accounts/foo/variables.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/envs/bar/Makefile b/testdata/auth0_provider_yaml/terraform/envs/bar/Makefile
new file mode 100644
index 00000000..e5f90fa2
--- /dev/null
+++ b/testdata/auth0_provider_yaml/terraform/envs/bar/Makefile
@@ -0,0 +1,51 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+COMPONENTS=bam
+
+all:
+.PHONY: all
+
+lint: ## lint all components in the env
+	@for c in $(COMPONENTS); do \
+		echo $$c; \
+		$(MAKE) -C $$c lint || exit $$? ; \
+	done
+.PHONY: lint
+
+fmt: ## format terraform code in all components in this env
+	@for c in $(COMPONENTS); do \
+		echo $$c; \
+		$(MAKE) -C $$c fmt || exit $$? ; \
+	done
+.PHONY: fmt
+
+check-plan: ## check all plans in this environment
+	@for c in $(COMPONENTS); do \
+		echo $$c; \
+		$(MAKE) -C $$c check-plan || exit $$? ; \
+	done
+.PHONY: check-plan
+
+docs: ## generate docs for all components in this env
+	@for c in $(COMPONENTS); do \
+		echo $$c; \
+		$(MAKE) -C $$c docs || exit $$? ; \
+	done
+.PHONY: docs
+
+clean: ## clean all components in this env
+	@for c in $(COMPONENTS); do \
+		echo $$c; \
+		$(MAKE) -C $$c clean || exit $$? ; \
+	done
+.PHONY: clean
+
+test:
+.PHONY: test
+
+
+help: ## display help for this makefile
+	@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+.PHONY: help
+
diff --git a/testdata/auth0_provider_yaml/terraform/envs/bar/README.md b/testdata/auth0_provider_yaml/terraform/envs/bar/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/envs/bar/bam/Makefile b/testdata/auth0_provider_yaml/terraform/envs/bar/bam/Makefile
new file mode 100644
index 00000000..529c552c
--- /dev/null
+++ b/testdata/auth0_provider_yaml/terraform/envs/bar/bam/Makefile
@@ -0,0 +1,20 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+
+export TERRAFORM_VERSION := 1.1.1
+export TFLINT_ENABLED := 0
+export TF_PLUGIN_CACHE_DIR := ../../../..//.terraform.d/plugin-cache
+export TF_BACKEND_KIND := s3
+
+export AWS_BACKEND_PROFILE := foofoo
+
+
+
+include ../../../..//scripts/component.mk
+
+
+help: ## display help for this makefile
+	@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+.PHONY: help
+
diff --git a/testdata/auth0_provider_yaml/terraform/envs/bar/bam/README.md b/testdata/auth0_provider_yaml/terraform/envs/bar/bam/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/envs/bar/bam/fogg.tf b/testdata/auth0_provider_yaml/terraform/envs/bar/bam/fogg.tf
new file mode 100644
index 00000000..0e9c81dd
--- /dev/null
+++ b/testdata/auth0_provider_yaml/terraform/envs/bar/bam/fogg.tf
@@ -0,0 +1,133 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+provider auth0 {
+  domain = "adomain"
+}
+terraform {
+  required_version = "=1.1.1"
+
+  backend s3 {
+
+    bucket = "bucket"
+
+    key     = "terraform/foofoo/envs/bar/components/bam.tfstate"
+    encrypt = true
+    region  = "region"
+    profile = "foofoo"
+
+
+  }
+  required_providers {
+
+    archive = {
+      source = "hashicorp/archive"
+
+      version = "~> 2.0"
+
+    }
+
+    auth0 = {
+      source = "alexkappa/auth0"
+
+      version = "aversion"
+
+    }
+
+    local = {
+      source = "hashicorp/local"
+
+      version = "~> 2.0"
+
+    }
+
+    null = {
+      source = "hashicorp/null"
+
+      version = "~> 3.0"
+
+    }
+
+    random = {
+      source = "hashicorp/random"
+
+      version = "~> 2.2"
+
+    }
+
+    template = {
+      source = "hashicorp/template"
+
+      version = "~> 2.2"
+
+    }
+
+    tls = {
+      source = "hashicorp/tls"
+
+      version = "~> 3.0"
+
+    }
+
+  }
+}
+variable env {
+  type    = string
+  default = "bar"
+}
+variable project {
+  type    = string
+  default = "foofoo"
+}
+variable component {
+  type    = string
+  default = "bam"
+}
+variable owner {
+  type    = string
+  default = "foo@example.com"
+}
+variable tags {
+  type = object({ project : string, env : string, service : string, owner : string, managedBy : string })
+  default = {
+    project   = "foofoo"
+    env       = "bar"
+    service   = "bam"
+    owner     = "foo@example.com"
+    managedBy = "terraform"
+  }
+}
+data terraform_remote_state global {
+  backend = "s3"
+  config = {
+
+
+    bucket = "bucket"
+
+    key     = "terraform/foofoo/global.tfstate"
+    region  = "region"
+    profile = "foofoo"
+
+
+  }
+}
+data terraform_remote_state foo {
+  backend = "s3"
+  config = {
+
+
+    bucket = "bucket"
+
+    key     = "terraform/foofoo/accounts/foo.tfstate"
+    region  = "region"
+    profile = "foofoo"
+
+
+  }
+}
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
diff --git a/testdata/auth0_provider_yaml/terraform/envs/bar/bam/main.tf b/testdata/auth0_provider_yaml/terraform/envs/bar/bam/main.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/envs/bar/bam/outputs.tf b/testdata/auth0_provider_yaml/terraform/envs/bar/bam/outputs.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/envs/bar/bam/terraform.d b/testdata/auth0_provider_yaml/terraform/envs/bar/bam/terraform.d
new file mode 120000
index 00000000..b482d75b
--- /dev/null
+++ b/testdata/auth0_provider_yaml/terraform/envs/bar/bam/terraform.d
@@ -0,0 +1,1 @@
+../../../../terraform.d
\ No newline at end of file
diff --git a/testdata/auth0_provider_yaml/terraform/envs/bar/bam/variables.tf b/testdata/auth0_provider_yaml/terraform/envs/bar/bam/variables.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/global/Makefile b/testdata/auth0_provider_yaml/terraform/global/Makefile
new file mode 100644
index 00000000..dc1cec4d
--- /dev/null
+++ b/testdata/auth0_provider_yaml/terraform/global/Makefile
@@ -0,0 +1,20 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+
+export TERRAFORM_VERSION := 1.1.1
+export TFLINT_ENABLED := 0
+export TF_PLUGIN_CACHE_DIR := ../..//.terraform.d/plugin-cache
+export TF_BACKEND_KIND := s3
+
+export AWS_BACKEND_PROFILE := foofoo
+
+
+
+include ../..//scripts/component.mk
+
+
+help: ## display help for this makefile
+	@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
+.PHONY: help
+
diff --git a/testdata/auth0_provider_yaml/terraform/global/README.md b/testdata/auth0_provider_yaml/terraform/global/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/global/fogg.tf b/testdata/auth0_provider_yaml/terraform/global/fogg.tf
new file mode 100644
index 00000000..27e3b5db
--- /dev/null
+++ b/testdata/auth0_provider_yaml/terraform/global/fogg.tf
@@ -0,0 +1,105 @@
+# Auto-generated by fogg. Do not edit
+# Make improvements in fogg, so that everyone can benefit.
+
+provider auth0 {
+  domain = "adomain"
+}
+terraform {
+  required_version = "=1.1.1"
+
+  backend s3 {
+
+    bucket = "bucket"
+
+    key     = "terraform/foofoo/global.tfstate"
+    encrypt = true
+    region  = "region"
+    profile = "foofoo"
+
+
+  }
+  required_providers {
+
+    archive = {
+      source = "hashicorp/archive"
+
+      version = "~> 2.0"
+
+    }
+
+    auth0 = {
+      source = "alexkappa/auth0"
+
+      version = "aversion"
+
+    }
+
+    local = {
+      source = "hashicorp/local"
+
+      version = "~> 2.0"
+
+    }
+
+    null = {
+      source = "hashicorp/null"
+
+      version = "~> 3.0"
+
+    }
+
+    random = {
+      source = "hashicorp/random"
+
+      version = "~> 2.2"
+
+    }
+
+    template = {
+      source = "hashicorp/template"
+
+      version = "~> 2.2"
+
+    }
+
+    tls = {
+      source = "hashicorp/tls"
+
+      version = "~> 3.0"
+
+    }
+
+  }
+}
+variable env {
+  type    = string
+  default = ""
+}
+variable project {
+  type    = string
+  default = "foofoo"
+}
+variable component {
+  type    = string
+  default = "global"
+}
+variable owner {
+  type    = string
+  default = "foo@example.com"
+}
+variable tags {
+  type = object({ project : string, env : string, service : string, owner : string, managedBy : string })
+  default = {
+    project   = "foofoo"
+    env       = ""
+    service   = "global"
+    owner     = "foo@example.com"
+    managedBy = "terraform"
+  }
+}
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
diff --git a/testdata/auth0_provider_yaml/terraform/global/main.tf b/testdata/auth0_provider_yaml/terraform/global/main.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/global/outputs.tf b/testdata/auth0_provider_yaml/terraform/global/outputs.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/auth0_provider_yaml/terraform/global/terraform.d b/testdata/auth0_provider_yaml/terraform/global/terraform.d
new file mode 120000
index 00000000..a1f7d0d3
--- /dev/null
+++ b/testdata/auth0_provider_yaml/terraform/global/terraform.d
@@ -0,0 +1,1 @@
+../../terraform.d
\ No newline at end of file