Repository: chanzuckerberg/fogg
Pull request #522 (2021-02-05 21:59:26)

[refactor] use same templates for components, accounts and global
Rather than separate and not quite equivalent implementations, use one.

One side effect is that for components,  terraform version constraints are now tighter (= rather than ~>). This was the way accounts were set up and probably the way we should work.

### Test Plan
* CI

### References


clubhouse[bot]: This pull request has been linked to [Clubhouse Story #8417: move providers to terraform block](https://app.clubhouse.io/infraeng/story/8417/move-providers-to-terraform-block).
codecov-io: # [Codecov](https://codecov.io/gh/chanzuckerberg/fogg/pull/522?src=pr&el=h1) Report
> :exclamation: No coverage uploaded for pull request base (`main@9d16ae4`). [Click here to learn what that means](https://docs.codecov.io/docs/error-reference#section-missing-base-commit).
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/chanzuckerberg/fogg/pull/522/graphs/tree.svg?width=650&height=150&src=pr&token=57DhtZ7g2A)](https://codecov.io/gh/chanzuckerberg/fogg/pull/522?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##             main     #522   +/-   ##
=======================================
  Coverage        ?   57.21%           
=======================================
  Files           ?       21           
  Lines           ?     1877           
  Branches        ?        0           
=======================================
  Hits            ?     1074           
  Misses          ?      648           
  Partials        ?      155           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/chanzuckerberg/fogg/pull/522?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/chanzuckerberg/fogg/pull/522?src=pr&el=footer). Last update [9d16ae4...7c1d8bf](https://codecov.io/gh/chanzuckerberg/fogg/pull/522?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

ryanking: @jgadling not intended, and not able to reproduce

Patch:
diff --git a/apply/apply.go b/apply/apply.go
index ccb2f8c8..4a1bdccf 100644
--- a/apply/apply.go
+++ b/apply/apply.go
@@ -69,7 +69,8 @@ func Apply(fs afero.Fs, conf *v2.Config, tmp *templates.T, upgrade bool) error {
 		}
 	}
 
-	e = applyAccounts(fs, p, &tmp.Account, &tmp.Common)
+	tfBox := tmp.Components[v2.ComponentKindTerraform]
+	e = applyAccounts(fs, p, &tfBox, &tmp.Common)
 	if e != nil {
 		return errs.WrapUser(e, "unable to apply accounts")
 	}
@@ -79,7 +80,8 @@ func Apply(fs afero.Fs, conf *v2.Config, tmp *templates.T, upgrade bool) error {
 		return errs.WrapUser(e, "unable to apply envs")
 	}
 
-	e = applyGlobal(fs, p.Global, &tmp.Global, &tmp.Common)
+	tfBox = tmp.Components[v2.ComponentKindTerraform]
+	e = applyGlobal(fs, p.Global, &tfBox, &tmp.Common)
 	if e != nil {
 		return errs.WrapUser(e, "unable to apply global")
 	}
diff --git a/cmd/components_paths.go b/cmd/components_paths.go
index 90ebacaf..e0cbac0c 100644
--- a/cmd/components_paths.go
+++ b/cmd/components_paths.go
@@ -50,12 +50,12 @@ var componentsListCmd = &cobra.Command{
 		fmt.Println("terraform/global")
 
 		for _, a := range p.Accounts {
-			fmt.Printf("terraform/accounts/%s\n", a.AccountName)
+			fmt.Printf("terraform/accounts/%s\n", a.Name)
 		}
 
 		for _, e := range p.Envs {
 			for _, c := range e.Components {
-				fmt.Printf("terraform/envs/%s/%s\n", e.Env, c.Component)
+				fmt.Printf("terraform/envs/%s/%s\n", e.Env, c.Name)
 			}
 		}
 		return nil
diff --git a/plan/plan.go b/plan/plan.go
index be0ee8a7..a5663fb1 100644
--- a/plan/plan.go
+++ b/plan/plan.go
@@ -34,12 +34,18 @@ type Common struct {
 type ComponentCommon struct {
 	Common `yaml:",inline"`
 
-	Backend   Backend           `yaml:"backend"`
-	ExtraVars map[string]string `yaml:"extra_vars"`
-	Owner     string            `yaml:"owner"`
-	Project   string            `yaml:"project"`
-	Providers Providers         `yaml:"providers"`
-	TfLint    TfLint            `yaml:"tf_lint"`
+	AccountBackends   map[string]Backend      `yaml:"account_backends"`
+	Accounts          map[string]*json.Number `yaml:"all_accounts"`
+	Backend           Backend                 `yaml:"backend"`
+	ComponentBackends map[string]Backend      `yaml:"comonent_backends"`
+	Env               string                  ` yaml:"env"`
+	ExtraVars         map[string]string       `yaml:"extra_vars"`
+	Name              string                  `yaml:"name"`
+	Owner             string                  `yaml:"owner"`
+	Project           string                  `yaml:"project"`
+	Providers         Providers               `yaml:"providers"`
+
+	TfLint TfLint `yaml:"tf_lint"`
 
 	TravisCI        TravisCIComponent
 	CircleCI        CircleCIComponent
@@ -224,27 +230,19 @@ type Module struct {
 type Account struct {
 	ComponentCommon `yaml:",inline"`
 
-	AccountBackends map[string]Backend      `yaml:"account_backends"` // Reference accounts for remote state
-	AllAccounts     map[string]*json.Number `yaml:"all_accounts"`
-	AccountName     string                  `yaml:"account_name"`
-	Global          *Component
+	Account string     `yaml:"account"`
+	Global  *Component `yaml:"global"`
 }
 
 // Component is a component
 type Component struct {
 	ComponentCommon `yaml:",inline"`
 
-	Accounts        map[string]Account `yaml:"accounts"` // Reference accounts for remote state
-	AccountBackends map[string]Backend `yaml:"account_backends"`
-	Component       string             `yaml:"component"`
-	EKS             *v2.EKSConfig      `yaml:"eks,omitempty"`
-	Env             string
-
-	Kind              *v2.ComponentKind  `yaml:"kind,omitempty"`
-	ModuleSource      *string            `yaml:"module_source"`
-	ModuleName        *string            `yaml:"module_name"`
-	ComponentBackends map[string]Backend `yaml:"component_backends"`
-	Global            *Component         `yaml:"global"`
+	EKS          *v2.EKSConfig     `yaml:"eks,omitempty"`
+	Kind         *v2.ComponentKind `yaml:"kind,omitempty"`
+	ModuleSource *string           `yaml:"module_source"`
+	ModuleName   *string           `yaml:"module_name"`
+	Global       *Component        `yaml:"global"`
 }
 
 // Env is an env
@@ -304,8 +302,10 @@ func (p *Plan) buildAccounts(c *v2.Config) map[string]Account {
 	for name, acct := range c.Accounts {
 		accountPlan := Account{}
 
-		accountPlan.AccountName = name
 		accountPlan.ComponentCommon = resolveComponentCommon(defaults.Common, acct.Common)
+		accountPlan.Name = name
+		accountPlan.Account = name // for backwards compat
+		accountPlan.Env = "accounts"
 
 		if accountPlan.ComponentCommon.Backend.Kind == BackendKindS3 {
 			accountPlan.ComponentCommon.Backend.S3.KeyPath = fmt.Sprintf("terraform/%s/accounts/%s.tfstate", accountPlan.ComponentCommon.Project, name)
@@ -315,7 +315,7 @@ func (p *Plan) buildAccounts(c *v2.Config) map[string]Account {
 			panic(fmt.Sprintf("Invalid backend kind of %s", accountPlan.ComponentCommon.Backend.Kind))
 		}
 
-		accountPlan.AllAccounts = resolveAccounts(c.Accounts) //FIXME this needs to run as a second phase, not directly from the config
+		accountPlan.Accounts = resolveAccounts(c.Accounts) //FIXME this needs to run as a second phase, not directly from the config
 		accountPlan.PathToRepoRoot = "../../../"
 		accountPlan.Global = &p.Global
 		accountPlans[name] = accountPlan
@@ -368,7 +368,7 @@ func newEnvPlan() Env {
 func (p *Plan) buildGlobal(conf *v2.Config) Component {
 	// Global just uses defaults because that's the way sicc worked. We should make it directly configurable.
 	componentPlan := Component{}
-	componentPlan.Accounts = p.Accounts
+	componentPlan.Accounts = resolveAccounts(conf.Accounts)
 	defaults := conf.Defaults
 	global := conf.Global
 
@@ -382,7 +382,7 @@ func (p *Plan) buildGlobal(conf *v2.Config) Component {
 		panic(fmt.Sprintf("Invalid backend kind of %s", componentPlan.ComponentCommon.Backend.Kind))
 	}
 
-	componentPlan.Component = "global"
+	componentPlan.Name = "global"
 	componentPlan.ExtraVars = resolveExtraVars(defaults.ExtraVars, global.ExtraVars)
 	componentPlan.PathToRepoRoot = "../../"
 
@@ -399,7 +399,6 @@ func (p *Plan) buildEnvs(conf *v2.Config) (map[string]Env, error) {
 		envPlan.Env = envName
 
 		for componentName, componentConf := range conf.Envs[envName].Components {
-			accountRemoteStates := v2.ResolveOptionalStringSlice(v2.DependsOnAccountsGetter, defaults.Common, envConf.Common, componentConf.Common)
 
 			componentPlan := Component{
 				Kind: componentConf.Kind,
@@ -413,6 +412,8 @@ func (p *Plan) buildEnvs(conf *v2.Config) (map[string]Env, error) {
 				componentPlan.EKS = resolveEKSConfig(envPlan.EKS, componentConf.EKS)
 			}
 
+			componentPlan.ComponentCommon = resolveComponentCommon(defaults.Common, envConf.Common, componentConf.Common)
+			accountRemoteStates := v2.ResolveOptionalStringSlice(v2.DependsOnAccountsGetter, defaults.Common, envConf.Common, componentConf.Common)
 			accountBackends := map[string]Backend{}
 			for k, v := range p.Accounts {
 				if accountRemoteStates == nil || util.SliceContainsString(accountRemoteStates, k) {
@@ -421,9 +422,7 @@ func (p *Plan) buildEnvs(conf *v2.Config) (map[string]Env, error) {
 			}
 			componentPlan.AccountBackends = accountBackends
 
-			componentPlan.Accounts = p.Accounts
-
-			componentPlan.ComponentCommon = resolveComponentCommon(defaults.Common, envConf.Common, componentConf.Common)
+			componentPlan.Accounts = resolveAccounts(conf.Accounts)
 
 			if componentPlan.ComponentCommon.Backend.Kind == BackendKindS3 {
 				componentPlan.ComponentCommon.Backend.S3.KeyPath = fmt.Sprintf("terraform/%s/envs/%s/components/%s.tfstate", componentPlan.ComponentCommon.Project, envName, componentName)
@@ -434,7 +433,7 @@ func (p *Plan) buildEnvs(conf *v2.Config) (map[string]Env, error) {
 			}
 
 			componentPlan.Env = envName
-			componentPlan.Component = componentName
+			componentPlan.Name = componentName
 			componentPlan.ModuleSource = componentConf.ModuleSource
 			componentPlan.ModuleName = componentConf.ModuleName
 			componentPlan.PathToRepoRoot = "../../../../"
@@ -713,11 +712,9 @@ func resolveExtraVars(vars ...map[string]string) map[string]string {
 func resolveAccounts(accounts map[string]v2.Account) map[string]*json.Number {
 	a := make(map[string]*json.Number)
 	for name, account := range accounts {
-		var acctID *json.Number
-		if account.Providers != nil && account.Providers.AWS != nil {
-			acctID = account.Providers.AWS.AccountID
+		if account.Providers != nil && account.Providers.AWS != nil && account.Providers.AWS.AccountID != nil {
+			a[name] = account.Providers.AWS.AccountID
 		}
-		a[name] = acctID
 	}
 	return a
 }
diff --git a/templates/account/Makefile.tmpl b/templates/account/Makefile.tmpl
deleted file mode 100644
index 7771c873..00000000
--- a/templates/account/Makefile.tmpl
+++ /dev/null
@@ -1,3 +0,0 @@
-{{ template "fogg_header" }}
-{{ template "make_vars" . }}
-{{ template "make_help" }}
diff --git a/templates/account/fogg.tf.tmpl b/templates/account/fogg.tf.tmpl
deleted file mode 100644
index 0e3be794..00000000
--- a/templates/account/fogg.tf.tmpl
+++ /dev/null
@@ -1,126 +0,0 @@
-# Auto-generated by fogg. Do not edit
-# Make improvements in fogg, so that everyone can benefit.
-
-{{if .Providers.AWS}}
-{{ template "aws_provider" .Providers.AWS}}
-  # Aliased Providers (for doing things in every region).
-  {{ range $p := .Providers.AWSAdditionalProviders }}
-    {{ template "aws_provider" $p}}
-  {{ end }}
-{{ end }}
-
-{{ if .Providers.Snowflake }}
-  {{ template "snowflake_provider" .Providers.Snowflake }}
-{{ end }}
-
-{{ if .Providers.Bless }}
-  {{ template "bless_provider" .Providers.Bless }}
-{{ end }}
-
-{{ if .Providers.Okta}}
-  {{ template "okta_provider" .Providers.Okta}}
-{{ end }}
-
-{{ if .Providers.Github}}
-  {{ template "github_provider" .Providers.Github}}
-{{ end }}
-
-{{ if .Providers.Heroku }}
-  {{ template "heroku_provider" .Providers.Heroku }}
-{{ end }}
-
-{{ if .Providers.Datadog }}
-  {{ template "datadog_provider" .Providers.Datadog }}
-{{ end }}
-
-{{ if .Providers.Tfe }}{{ if .Providers.Tfe.Enabled }}
-    {{ template "tfe_provider" .Providers.Tfe }}
-{{ end }}{{ end }}
-
-
-terraform {
-  required_version = "={{ .TerraformVersion }}"
-{{ template "backend" .Backend }}
-}
-
-variable project {
-  type    =  string
-  default = "{{ .Project }}"
-}
-
-{{ if .Providers.AWS }}
-  variable region {
-    type    =  string
-    default = "{{ .Providers.AWS.Region }}"
-  }
-{{ end }}
-
-{{ if .Providers.AWS }}{{ if .Providers.AWS.Profile }}
-  variable aws_profile {
-    type =  string
-    default =  "{{ .Providers.AWS.Profile }}"
-  }
-{{ end }}{{ end }}
-
-variable owner {
-  type =  string
-  default = "{{ .Owner }}"
-}
-
-variable account {
-    type = string
-    default = "{{ .AccountName }}"
-}
-
-variable tags {
-  type =  object({project: string, env: string, service: string, owner: string, managedBy: string})
-  default = {
-    project   = "{{ .Project }}"
-    env       = "accounts"
-    service   = "{{ .AccountName }}"
-    owner     = "{{ .Owner }}"
-    managedBy = "terraform"
-  }
-}
-
-# map of aws_accounts
-variable aws_accounts {
-  type =  map
-  default = {
-  {{ range $account, $id := .AllAccounts }}
-    {{ if $id }}
-        {{ $account }} = {{ $id }}
-    {{ end }}
-  {{ end }}
-  }
-}
-
-{{ range $key, $val := .ExtraVars }}
-variable {{ $key }} {
-  type =  string
-  default = "{{ $val }}"
-}
-{{ end }}
-
-data terraform_remote_state global {
-  backend = "{{ .Global.Backend.Kind }}"
-
-  config = {
-    {{ template "remote_backend" .Global.Backend }}
-  }
-}
-
-{{ $outer := . }}
-{{ range $accountName, $backend := .AccountBackends}}
-{{ if ne $accountName $outer.AccountName }}
-data terraform_remote_state {{ $accountName }} {
-  backend = "{{ $backend.Kind }}"
-
-  config = {
-    {{ template "remote_backend" $backend }}
-  }
-}
-{{ end }}
-{{ end }}
-
-{{ template "common_providers" }}
diff --git a/templates/account/terraform.d.ln b/templates/account/terraform.d.ln
deleted file mode 100644
index 1c961f51..00000000
--- a/templates/account/terraform.d.ln
+++ /dev/null
@@ -1,1 +0,0 @@
-terraform.d
\ No newline at end of file
diff --git a/templates/component/helm_template/Chart.yaml.tmpl b/templates/component/helm_template/Chart.yaml.tmpl
index 1b2b3283..26735ab5 100644
--- a/templates/component/helm_template/Chart.yaml.tmpl
+++ b/templates/component/helm_template/Chart.yaml.tmpl
@@ -2,5 +2,5 @@
 # Make improvements in fogg, so that everyone can benefit.
 
 apiVersion: v1
-name: {{ .Component }}
+name: {{ .Name }}
 version: 0.0.1 # TODO(el): figure out
diff --git a/templates/component/helm_template/Makefile.tmpl b/templates/component/helm_template/Makefile.tmpl
index 6b0fe4cc..855752c8 100644
--- a/templates/component/helm_template/Makefile.tmpl
+++ b/templates/component/helm_template/Makefile.tmpl
@@ -5,7 +5,7 @@ SHELL := /bin/bash
 include {{ .PathToRepoRoot }}/scripts/common.mk
 export PATH := $(REPO_ROOT)/.fogg/bin:$(PATH)
 
-KUBECTL_FLAGS := --wait=true --prune -l fogg/project={{ .Project }},fogg/env={{ .Env }},fogg/component={{ .Component }}
+KUBECTL_FLAGS := --wait=true --prune -l fogg/project={{ .Project }},fogg/env={{ .Env }},fogg/component={{ .Name }}
 
 # TODO(el): Replace with kubectl diff once that is supported (k8s >= 1.13)
 plan: set-eks-context
diff --git a/templates/component/helm_template/values.yaml.tmpl b/templates/component/helm_template/values.yaml.tmpl
index be601f1c..e209a5d2 100644
--- a/templates/component/helm_template/values.yaml.tmpl
+++ b/templates/component/helm_template/values.yaml.tmpl
@@ -4,14 +4,14 @@
 env: {{ .Env }}
 project: {{ .Project }}
 region: {{ .Providers.AWS.Region }}
-component: {{ .Component }}
+component: {{ .Name }}
 owner: {{ .Owner }}
 aws_profile: {{ .Providers.AWS.Profile }}
 tags:
   env: {{ .Env }}
   project: {{ .Project }}
   region: {{ .Providers.AWS.Region }}
-  component: {{ .Component }}
+  component: {{ .Name }}
   owner: {{ .Owner }}
   managedBy: kubectl
 
@@ -20,8 +20,6 @@ tags:
 {{ end }}
 
 aws_accounts:
-{{- range $accountName, $account := .Accounts -}}
-{{ if $account.Providers.AWS.AccountID }}
-  {{ $accountName }}: {{ $account.Providers.AWS.AccountID -}}
-{{ end -}}
+{{- range $accountName, $accountID := .Accounts -}}
+  {{ $accountName }}: {{ $accountID -}}
 {{ end }}
diff --git a/templates/component/terraform/fogg.tf.tmpl b/templates/component/terraform/fogg.tf.tmpl
index 17b17f10..0ca3b1a5 100644
--- a/templates/component/terraform/fogg.tf.tmpl
+++ b/templates/component/terraform/fogg.tf.tmpl
@@ -40,7 +40,7 @@
 
 
 terraform {
-  required_version = "~>{{ .TerraformVersion }}"
+  required_version = "={{ .TerraformVersion }}"
 
   {{ template "backend" .Backend }}
 }
@@ -64,9 +64,16 @@ variable project {
 
 variable component {
   type =  string
-  default = "{{ .Component }}"
+  default = "{{ .Name }}"
 }
 
+{{ if (avail "Account" .) }}
+variable account {
+  type =  string
+  default = "{{ .Account }}"
+}
+{{ end }}
+
 {{ if .Providers.AWS }}{{ if .Providers.AWS.Profile }}
   variable aws_profile {
     type =  string
@@ -84,7 +91,7 @@ variable tags {
   default = {
     project   = "{{ .Project }}"
     env       = "{{ .Env }}"
-    service   = "{{ .Component }}"
+    service   = "{{ .Name }}"
     owner     = "{{ .Owner }}"
     managedBy = "terraform"
   }
@@ -97,6 +104,7 @@ variable {{ $key }} {
 }
 {{ end }}
 
+{{ if .Global }}
 data terraform_remote_state global {
   backend = "{{ .Global.Backend.Kind }}"
 
@@ -104,10 +112,11 @@ data terraform_remote_state global {
     {{ template "remote_backend" .Global.Backend }}
   }
 }
+{{ end }}
 
 {{ $outer := . }}
 {{ range $component, $backend := .ComponentBackends  }}
-{{ if ne $component $outer.Component }}
+{{ if ne $component $outer.Name }}
 data terraform_remote_state {{ $component }} {
   backend = "{{ $backend.Kind }}"
 
@@ -118,7 +127,6 @@ data terraform_remote_state {{ $component }} {
 {{ end }}
 {{ end }}
 
-# remote state for accounts
 {{ range $name, $backend := .AccountBackends }}
 data terraform_remote_state {{ $name }} {
   backend = "{{ $backend.Kind }}"
@@ -129,14 +137,11 @@ data terraform_remote_state {{ $name }} {
 }
 {{ end }}
 
-# map of aws_accounts
 variable aws_accounts {
   type =  map
   default = {
-  {{ range $accountName, $account := .Accounts }}
-    {{ if $account.Providers.AWS }}
-        {{ $accountName }} = {{ $account.Providers.AWS.AccountID }}
-    {{ end }}
+  {{ range $account, $id := .Accounts }}
+    {{ $account }} = {{ $id }}
   {{ end }}
   }
 }
diff --git a/templates/global/Makefile.tmpl b/templates/global/Makefile.tmpl
deleted file mode 100644
index 7771c873..00000000
--- a/templates/global/Makefile.tmpl
+++ /dev/null
@@ -1,3 +0,0 @@
-{{ template "fogg_header" }}
-{{ template "make_vars" . }}
-{{ template "make_help" }}
diff --git a/templates/global/fogg.tf.tmpl b/templates/global/fogg.tf.tmpl
deleted file mode 100644
index 9de76228..00000000
--- a/templates/global/fogg.tf.tmpl
+++ /dev/null
@@ -1,97 +0,0 @@
-# Auto-generated by fogg. Do not edit
-# Make improvements in fogg, so that everyone can benefit.
-
-{{ if .Providers.AWS }}
-{{ template "aws_provider" .Providers.AWS}}
-  # Aliased Providers (for doing things in every region).
-  {{ range $p := .Providers.AWSAdditionalProviders }}
-    {{ template "aws_provider" $p}}
-  {{ end }}{{ end }}
-
-{{ if .Providers.Snowflake }}
-  {{ template "snowflake_provider" .Providers.Snowflake }}
-{{ end }}
-
-{{ if .Providers.Bless}}
-  {{ template "bless_provider" .Providers.Bless }}
-{{ end }}
-
-{{ if .Providers.Okta}}
-  {{ template "okta_provider" .Providers.Okta}}
-{{ end }}
-
-{{ if .Providers.Github}}
-  {{ template "github_provider" .Providers.Github}}
-{{ end }}
-
-{{ if .Providers.Heroku }}
-  {{ template "heroku_provider" .Providers.Heroku }}
-{{ end }}
-
-{{ if .Providers.Datadog }}
-  {{ template "datadog_provider" .Providers.Datadog }}
-{{ end }}
-
-{{ if .Providers.Tfe }}{{ if .Providers.Tfe.Enabled }}
-  {{ template "tfe_provider" .Providers.Tfe }}
-{{ end }}{{ end }}
-
-terraform {
-  required_version = "~>{{ .TerraformVersion }}"
-  {{ template "backend" .Backend -}}
-}
-
-variable env {
-  type    =  string
-  default = "{{ .Env }}"
-}
-
-variable project {
-  type    =  string
-  default = "{{ .Project }}"
-}
-
-{{ if .Providers.AWS }}
-  variable region {
-    type    =  string
-    default = "{{ .Providers.AWS.Region }}"
-  }
-{{ end }}
-
-variable component {
-  type =  string
-  default = "{{ .Component }}"
-}
-
-{{ if .Providers.AWS }}{{ if .Providers.AWS.Profile }}
-  variable aws_profile {
-    type =  string
-    default =  "{{ .Providers.AWS.Profile }}"
-  }
-{{ end }}{{ end }}
-
-variable owner {
-  type =  string
-  default = "{{ .Owner }}"
-}
-
-variable tags {
-  type =  object({project: string, env: string, service: string, owner: string, managedBy: string})
-  default = {
-    project   = "{{ .Project }}"
-    env       = "{{ .Env }}"
-    service   = "{{ .Component }}"
-    owner     = "{{ .Owner }}"
-    managedBy = "terraform"
-  }
-}
-
-{{ range $key, $val := .ExtraVars }}
-variable {{ $key }} {
-  type =  string
-  default = "{{ $val }}"
-}
-{{ end }}
-
-
-{{ template "common_providers" }}
diff --git a/templates/global/terraform.d.ln b/templates/global/terraform.d.ln
deleted file mode 100644
index 1c961f51..00000000
--- a/templates/global/terraform.d.ln
+++ /dev/null
@@ -1,1 +0,0 @@
-terraform.d
\ No newline at end of file
diff --git a/templates/templates.go b/templates/templates.go
index e9419d25..b112602d 100644
--- a/templates/templates.go
+++ b/templates/templates.go
@@ -6,11 +6,9 @@ import (
 )
 
 type T struct {
-	Account          packr.Box
 	Common           packr.Box
 	Components       map[v2.ComponentKind]packr.Box
 	Env              packr.Box
-	Global           packr.Box
 	Module           packr.Box
 	ModuleInvocation packr.Box
 	Repo             packr.Box
@@ -20,14 +18,12 @@ type T struct {
 }
 
 var Templates = &T{
-	Account: packr.NewBox("account"),
-	Common:  packr.NewBox("common"),
+	Common: packr.NewBox("common"),
 	Components: map[v2.ComponentKind]packr.Box{
 		v2.ComponentKindTerraform:    packr.NewBox("component/terraform"),
 		v2.ComponentKindHelmTemplate: packr.NewBox("component/helm_template"),
 	},
 	Env:              packr.NewBox("env"),
-	Global:           packr.NewBox("global"),
 	Module:           packr.NewBox("module"),
 	ModuleInvocation: packr.NewBox("module-invocation"),
 	Repo:             packr.NewBox("repo"),
diff --git a/util/template.go b/util/template.go
index 5779347e..d8cf0bfe 100644
--- a/util/template.go
+++ b/util/template.go
@@ -26,6 +26,18 @@ func dict(in interface{}) map[string]interface{} {
 	return nil
 }
 
+// https://stackoverflow.com/questions/44675087/golang-template-variable-isset
+func avail(name string, data interface{}) bool {
+	v := reflect.ValueOf(data)
+	if v.Kind() == reflect.Ptr {
+		v = v.Elem()
+	}
+	if v.Kind() != reflect.Struct {
+		return false
+	}
+	return v.FieldByName(name).IsValid()
+}
+
 // OpenTemplate will read `source` for a template, parse, configure and return a template.Template
 func OpenTemplate(label string, source io.Reader, commonTemplates *packr.Box) (*template.Template, error) {
 	// TODO we should probably cache these rather than open and parse them for every apply
@@ -46,6 +58,7 @@ func OpenTemplate(label string, source io.Reader, commonTemplates *packr.Box) (*
 
 	funcs := sprig.TxtFuncMap()
 	funcs["dict"] = dict
+	funcs["avail"] = avail
 
 	t, err := template.New(label).Funcs(funcs).Parse(s)
 	if err != nil {
@@ -53,7 +66,6 @@ func OpenTemplate(label string, source io.Reader, commonTemplates *packr.Box) (*
 	}
 
 	err = commonTemplates.Walk(func(path string, file packr.File) error {
-		logrus.Debugf("parsing common template %s", path)
 		s, err := readTemplate(file)
 		if err != nil {
 			return err


Test patch:
diff --git a/plan/plan_test.go b/plan/plan_test.go
index 827cee6b..30059d47 100644
--- a/plan/plan_test.go
+++ b/plan/plan_test.go
@@ -47,8 +47,7 @@ func TestResolveAccounts(t *testing.T) {
 
 	other := resolveAccounts(accounts)
 	r.NotNil(other)
-	var nilJsonNumber *json.Number
-	r.Equal(map[string]*json.Number{"bar": &bar, "foo": &foo, "baz": nilJsonNumber}, other)
+	r.Equal(map[string]*json.Number{"bar": &bar, "foo": &foo}, other)
 }
 
 func TestPlanBasicV2Yaml(t *testing.T) {
diff --git a/templates/templates_test.go b/templates/templates_test.go
index 3a2167f5..d584f4c6 100644
--- a/templates/templates_test.go
+++ b/templates/templates_test.go
@@ -3,6 +3,7 @@ package templates
 import (
 	"testing"
 
+	v2 "github.com/chanzuckerberg/fogg/config/v2"
 	"github.com/chanzuckerberg/fogg/util"
 	"github.com/gobuffalo/packr"
 	"github.com/stretchr/testify/require"
@@ -20,7 +21,7 @@ func TestOpenTemplate(t *testing.T) {
 		args    args
 		wantErr bool
 	}{
-		{"foo", args{temps.Account, "Makefile.tmpl"}, false},
+		{"foo", args{temps.Components[v2.ComponentKindTerraform], "Makefile.tmpl"}, false},
 	}
 
 	for _, tt := range tests {
diff --git a/templates/global/README.md.touch b/testdata/bless_provider_yaml/terraform/accounts/foo/README.md
similarity index 100%
rename from templates/global/README.md.touch
rename to testdata/bless_provider_yaml/terraform/accounts/foo/README.md
diff --git a/testdata/bless_provider_yaml/terraform/accounts/foo/fogg.tf b/testdata/bless_provider_yaml/terraform/accounts/foo/fogg.tf
index 3e71044c..d16b20e4 100644
--- a/testdata/bless_provider_yaml/terraform/accounts/foo/fogg.tf
+++ b/testdata/bless_provider_yaml/terraform/accounts/foo/fogg.tf
@@ -22,6 +22,7 @@ provider bless {
 }
 terraform {
   required_version = "=1.1.1"
+
   backend s3 {
 
     bucket = "bucket"
@@ -34,18 +35,26 @@ terraform {
 
   }
 }
+variable env {
+  type    = string
+  default = "accounts"
+}
 variable project {
   type    = string
   default = "foofoo"
 }
-variable owner {
+variable component {
   type    = string
-  default = "foo@example.com"
+  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 = {
@@ -56,27 +65,38 @@ variable tags {
     managedBy = "terraform"
   }
 }
-# map of aws_accounts
-variable aws_accounts {
-  type = map
-  default = {
+data terraform_remote_state global {
+  backend = "s3"
+  config = {
 
 
+    bucket = "bucket"
+
+    key     = "terraform/foofoo/global.tfstate"
+    region  = "region"
+    profile = "foofoo"
+
 
   }
 }
-data terraform_remote_state global {
+data terraform_remote_state foo {
   backend = "s3"
   config = {
 
 
     bucket = "bucket"
 
-    key     = "terraform/foofoo/global.tfstate"
+    key     = "terraform/foofoo/accounts/foo.tfstate"
     region  = "region"
     profile = "foofoo"
 
 
+  }
+}
+variable aws_accounts {
+  type = map
+  default = {
+
   }
 }
 provider random {
diff --git a/templates/global/main.tf.touch b/testdata/bless_provider_yaml/terraform/accounts/foo/main.tf
similarity index 100%
rename from templates/global/main.tf.touch
rename to testdata/bless_provider_yaml/terraform/accounts/foo/main.tf
diff --git a/templates/global/outputs.tf.touch b/testdata/bless_provider_yaml/terraform/accounts/foo/outputs.tf
similarity index 100%
rename from templates/global/outputs.tf.touch
rename to testdata/bless_provider_yaml/terraform/accounts/foo/outputs.tf
diff --git a/templates/global/variables.tf.touch b/testdata/bless_provider_yaml/terraform/accounts/foo/variables.tf
similarity index 100%
rename from templates/global/variables.tf.touch
rename to testdata/bless_provider_yaml/terraform/accounts/foo/variables.tf
diff --git a/testdata/bless_provider_yaml/terraform/envs/bar/bam/fogg.tf b/testdata/bless_provider_yaml/terraform/envs/bar/bam/fogg.tf
index feee987b..d612c962 100644
--- a/testdata/bless_provider_yaml/terraform/envs/bar/bam/fogg.tf
+++ b/testdata/bless_provider_yaml/terraform/envs/bar/bam/fogg.tf
@@ -21,7 +21,7 @@ provider bless {
   profile = "foofoofoo"
 }
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -75,7 +75,6 @@ data terraform_remote_state global {
 
   }
 }
-# remote state for accounts
 data terraform_remote_state foo {
   backend = "s3"
   config = {
@@ -90,13 +89,10 @@ data terraform_remote_state foo {
 
   }
 }
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
 
-
-
   }
 }
 provider random {
diff --git a/testdata/bless_provider_yaml/terraform/global/fogg.tf b/testdata/bless_provider_yaml/terraform/global/fogg.tf
index 41ffb33c..6783f767 100644
--- a/testdata/bless_provider_yaml/terraform/global/fogg.tf
+++ b/testdata/bless_provider_yaml/terraform/global/fogg.tf
@@ -21,7 +21,7 @@ provider bless {
   profile = "foofoofoo"
 }
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -61,6 +61,12 @@ variable tags {
     managedBy = "terraform"
   }
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }
diff --git a/testdata/circleci/terraform/global/fogg.tf b/testdata/circleci/terraform/global/fogg.tf
index 4e12bfc9..c3351b4f 100644
--- a/testdata/circleci/terraform/global/fogg.tf
+++ b/testdata/circleci/terraform/global/fogg.tf
@@ -1,7 +1,7 @@
 # Auto-generated by fogg. Do not edit
 # Make improvements in fogg, so that everyone can benefit.
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -41,6 +41,12 @@ variable tags {
     managedBy = "terraform"
   }
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }
diff --git a/testdata/github_actions/terraform/global/fogg.tf b/testdata/github_actions/terraform/global/fogg.tf
index 4e12bfc9..c3351b4f 100644
--- a/testdata/github_actions/terraform/global/fogg.tf
+++ b/testdata/github_actions/terraform/global/fogg.tf
@@ -1,7 +1,7 @@
 # Auto-generated by fogg. Do not edit
 # Make improvements in fogg, so that everyone can benefit.
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -41,6 +41,12 @@ variable tags {
     managedBy = "terraform"
   }
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }
diff --git a/testdata/github_provider_yaml/terraform/accounts/foo/README.md b/testdata/github_provider_yaml/terraform/accounts/foo/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/github_provider_yaml/terraform/accounts/foo/fogg.tf b/testdata/github_provider_yaml/terraform/accounts/foo/fogg.tf
index bac601e7..d0a9af0b 100644
--- a/testdata/github_provider_yaml/terraform/accounts/foo/fogg.tf
+++ b/testdata/github_provider_yaml/terraform/accounts/foo/fogg.tf
@@ -7,6 +7,7 @@ provider github {
 }
 terraform {
   required_version = "=1.1.1"
+
   backend s3 {
 
     bucket = "bucket"
@@ -19,18 +20,26 @@ terraform {
 
   }
 }
+variable env {
+  type    = string
+  default = "accounts"
+}
 variable project {
   type    = string
   default = "foo"
 }
-variable owner {
+variable component {
   type    = string
-  default = "foo@example.com"
+  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 = {
@@ -41,27 +50,38 @@ variable tags {
     managedBy = "terraform"
   }
 }
-# map of aws_accounts
-variable aws_accounts {
-  type = map
-  default = {
+data terraform_remote_state global {
+  backend = "s3"
+  config = {
 
 
+    bucket = "bucket"
+
+    key     = "terraform/foo/global.tfstate"
+    region  = "region"
+    profile = "foo"
+
 
   }
 }
-data terraform_remote_state global {
+data terraform_remote_state foo {
   backend = "s3"
   config = {
 
 
     bucket = "bucket"
 
-    key     = "terraform/foo/global.tfstate"
+    key     = "terraform/foo/accounts/foo.tfstate"
     region  = "region"
     profile = "foo"
 
 
+  }
+}
+variable aws_accounts {
+  type = map
+  default = {
+
   }
 }
 provider random {
diff --git a/testdata/github_provider_yaml/terraform/accounts/foo/main.tf b/testdata/github_provider_yaml/terraform/accounts/foo/main.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/github_provider_yaml/terraform/accounts/foo/outputs.tf b/testdata/github_provider_yaml/terraform/accounts/foo/outputs.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/github_provider_yaml/terraform/accounts/foo/variables.tf b/testdata/github_provider_yaml/terraform/accounts/foo/variables.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/github_provider_yaml/terraform/envs/bar/bam/fogg.tf b/testdata/github_provider_yaml/terraform/envs/bar/bam/fogg.tf
index 76199a97..0853fa04 100644
--- a/testdata/github_provider_yaml/terraform/envs/bar/bam/fogg.tf
+++ b/testdata/github_provider_yaml/terraform/envs/bar/bam/fogg.tf
@@ -6,7 +6,7 @@ provider github {
   base_url     = "https://example.com/"
 }
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -60,7 +60,6 @@ data terraform_remote_state global {
 
   }
 }
-# remote state for accounts
 data terraform_remote_state foo {
   backend = "s3"
   config = {
@@ -75,13 +74,10 @@ data terraform_remote_state foo {
 
   }
 }
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
 
-
-
   }
 }
 provider random {
diff --git a/testdata/github_provider_yaml/terraform/global/fogg.tf b/testdata/github_provider_yaml/terraform/global/fogg.tf
index abbdebff..bdac3d8e 100644
--- a/testdata/github_provider_yaml/terraform/global/fogg.tf
+++ b/testdata/github_provider_yaml/terraform/global/fogg.tf
@@ -6,7 +6,7 @@ provider github {
   base_url     = "https://example.com/"
 }
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -46,6 +46,12 @@ variable tags {
     managedBy = "terraform"
   }
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }
diff --git a/testdata/okta_provider_yaml/terraform/accounts/foo/README.md b/testdata/okta_provider_yaml/terraform/accounts/foo/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/okta_provider_yaml/terraform/accounts/foo/fogg.tf b/testdata/okta_provider_yaml/terraform/accounts/foo/fogg.tf
index bfc2d17e..5a978379 100644
--- a/testdata/okta_provider_yaml/terraform/accounts/foo/fogg.tf
+++ b/testdata/okta_provider_yaml/terraform/accounts/foo/fogg.tf
@@ -9,6 +9,7 @@ provider okta {
 }
 terraform {
   required_version = "=1.1.1"
+
   backend s3 {
 
     bucket = "bucket"
@@ -21,18 +22,26 @@ terraform {
 
   }
 }
+variable env {
+  type    = string
+  default = "accounts"
+}
 variable project {
   type    = string
   default = "foofoo"
 }
-variable owner {
+variable component {
   type    = string
-  default = "foo@example.com"
+  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 = {
@@ -43,27 +52,38 @@ variable tags {
     managedBy = "terraform"
   }
 }
-# map of aws_accounts
-variable aws_accounts {
-  type = map
-  default = {
+data terraform_remote_state global {
+  backend = "s3"
+  config = {
 
 
+    bucket = "bucket"
+
+    key     = "terraform/foofoo/global.tfstate"
+    region  = "region"
+    profile = "foofoo"
+
 
   }
 }
-data terraform_remote_state global {
+data terraform_remote_state foo {
   backend = "s3"
   config = {
 
 
     bucket = "bucket"
 
-    key     = "terraform/foofoo/global.tfstate"
+    key     = "terraform/foofoo/accounts/foo.tfstate"
     region  = "region"
     profile = "foofoo"
 
 
+  }
+}
+variable aws_accounts {
+  type = map
+  default = {
+
   }
 }
 provider random {
diff --git a/testdata/okta_provider_yaml/terraform/accounts/foo/main.tf b/testdata/okta_provider_yaml/terraform/accounts/foo/main.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/okta_provider_yaml/terraform/accounts/foo/outputs.tf b/testdata/okta_provider_yaml/terraform/accounts/foo/outputs.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/okta_provider_yaml/terraform/accounts/foo/variables.tf b/testdata/okta_provider_yaml/terraform/accounts/foo/variables.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/okta_provider_yaml/terraform/envs/bar/bam/fogg.tf b/testdata/okta_provider_yaml/terraform/envs/bar/bam/fogg.tf
index 991ae7f4..effea83b 100644
--- a/testdata/okta_provider_yaml/terraform/envs/bar/bam/fogg.tf
+++ b/testdata/okta_provider_yaml/terraform/envs/bar/bam/fogg.tf
@@ -8,7 +8,7 @@ provider okta {
   base_url = "oktapreview.com"
 }
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -62,7 +62,6 @@ data terraform_remote_state global {
 
   }
 }
-# remote state for accounts
 data terraform_remote_state foo {
   backend = "s3"
   config = {
@@ -77,13 +76,10 @@ data terraform_remote_state foo {
 
   }
 }
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
 
-
-
   }
 }
 provider random {
diff --git a/testdata/okta_provider_yaml/terraform/global/fogg.tf b/testdata/okta_provider_yaml/terraform/global/fogg.tf
index 74c92835..0b153e04 100644
--- a/testdata/okta_provider_yaml/terraform/global/fogg.tf
+++ b/testdata/okta_provider_yaml/terraform/global/fogg.tf
@@ -8,7 +8,7 @@ provider okta {
   base_url = "oktapreview.com"
 }
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -48,6 +48,12 @@ variable tags {
     managedBy = "terraform"
   }
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }
diff --git a/testdata/snowflake_provider_yaml/terraform/accounts/foo/README.md b/testdata/snowflake_provider_yaml/terraform/accounts/foo/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/snowflake_provider_yaml/terraform/accounts/foo/fogg.tf b/testdata/snowflake_provider_yaml/terraform/accounts/foo/fogg.tf
index 294399b3..590e3605 100644
--- a/testdata/snowflake_provider_yaml/terraform/accounts/foo/fogg.tf
+++ b/testdata/snowflake_provider_yaml/terraform/accounts/foo/fogg.tf
@@ -15,6 +15,7 @@ provider snowflake {
 }
 terraform {
   required_version = "=1.1.1"
+
   backend s3 {
 
     bucket = "bucket"
@@ -27,18 +28,26 @@ terraform {
 
   }
 }
+variable env {
+  type    = string
+  default = "accounts"
+}
 variable project {
   type    = string
   default = "foo"
 }
-variable owner {
+variable component {
   type    = string
-  default = "foo@example.com"
+  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 = {
@@ -49,27 +58,38 @@ variable tags {
     managedBy = "terraform"
   }
 }
-# map of aws_accounts
-variable aws_accounts {
-  type = map
-  default = {
+data terraform_remote_state global {
+  backend = "s3"
+  config = {
 
 
+    bucket = "bucket"
+
+    key     = "terraform/foo/global.tfstate"
+    region  = "region"
+    profile = "foo"
+
 
   }
 }
-data terraform_remote_state global {
+data terraform_remote_state foo {
   backend = "s3"
   config = {
 
 
     bucket = "bucket"
 
-    key     = "terraform/foo/global.tfstate"
+    key     = "terraform/foo/accounts/foo.tfstate"
     region  = "region"
     profile = "foo"
 
 
+  }
+}
+variable aws_accounts {
+  type = map
+  default = {
+
   }
 }
 provider random {
diff --git a/testdata/snowflake_provider_yaml/terraform/accounts/foo/main.tf b/testdata/snowflake_provider_yaml/terraform/accounts/foo/main.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/snowflake_provider_yaml/terraform/accounts/foo/outputs.tf b/testdata/snowflake_provider_yaml/terraform/accounts/foo/outputs.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/snowflake_provider_yaml/terraform/accounts/foo/variables.tf b/testdata/snowflake_provider_yaml/terraform/accounts/foo/variables.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/snowflake_provider_yaml/terraform/envs/bar/bam/fogg.tf b/testdata/snowflake_provider_yaml/terraform/envs/bar/bam/fogg.tf
index eecee584..f8722d5b 100644
--- a/testdata/snowflake_provider_yaml/terraform/envs/bar/bam/fogg.tf
+++ b/testdata/snowflake_provider_yaml/terraform/envs/bar/bam/fogg.tf
@@ -14,7 +14,7 @@ provider snowflake {
   region  = "us-west-2"
 }
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -68,7 +68,6 @@ data terraform_remote_state global {
 
   }
 }
-# remote state for accounts
 data terraform_remote_state foo {
   backend = "s3"
   config = {
@@ -83,13 +82,10 @@ data terraform_remote_state foo {
 
   }
 }
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
 
-
-
   }
 }
 provider random {
diff --git a/testdata/snowflake_provider_yaml/terraform/global/fogg.tf b/testdata/snowflake_provider_yaml/terraform/global/fogg.tf
index 95c95aaf..699014b4 100644
--- a/testdata/snowflake_provider_yaml/terraform/global/fogg.tf
+++ b/testdata/snowflake_provider_yaml/terraform/global/fogg.tf
@@ -14,7 +14,7 @@ provider snowflake {
   region  = "us-west-2"
 }
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -54,6 +54,12 @@ variable tags {
     managedBy = "terraform"
   }
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }
diff --git a/testdata/tfe_provider_yaml/terraform/accounts/foo/README.md b/testdata/tfe_provider_yaml/terraform/accounts/foo/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/tfe_provider_yaml/terraform/accounts/foo/fogg.tf b/testdata/tfe_provider_yaml/terraform/accounts/foo/fogg.tf
index 5d6c71c7..684bcce1 100644
--- a/testdata/tfe_provider_yaml/terraform/accounts/foo/fogg.tf
+++ b/testdata/tfe_provider_yaml/terraform/accounts/foo/fogg.tf
@@ -6,6 +6,7 @@ provider tfe {
 }
 terraform {
   required_version = "=1.1.1"
+
   backend s3 {
 
     bucket = "bucket"
@@ -18,18 +19,26 @@ terraform {
 
   }
 }
+variable env {
+  type    = string
+  default = "accounts"
+}
 variable project {
   type    = string
   default = "foo"
 }
-variable owner {
+variable component {
   type    = string
-  default = "foo@example.com"
+  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 = {
@@ -40,27 +49,38 @@ variable tags {
     managedBy = "terraform"
   }
 }
-# map of aws_accounts
-variable aws_accounts {
-  type = map
-  default = {
+data terraform_remote_state global {
+  backend = "s3"
+  config = {
 
 
+    bucket = "bucket"
+
+    key     = "terraform/foo/global.tfstate"
+    region  = "region"
+    profile = "foo"
+
 
   }
 }
-data terraform_remote_state global {
+data terraform_remote_state foo {
   backend = "s3"
   config = {
 
 
     bucket = "bucket"
 
-    key     = "terraform/foo/global.tfstate"
+    key     = "terraform/foo/accounts/foo.tfstate"
     region  = "region"
     profile = "foo"
 
 
+  }
+}
+variable aws_accounts {
+  type = map
+  default = {
+
   }
 }
 provider random {
diff --git a/testdata/tfe_provider_yaml/terraform/accounts/foo/main.tf b/testdata/tfe_provider_yaml/terraform/accounts/foo/main.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/tfe_provider_yaml/terraform/accounts/foo/outputs.tf b/testdata/tfe_provider_yaml/terraform/accounts/foo/outputs.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/tfe_provider_yaml/terraform/accounts/foo/variables.tf b/testdata/tfe_provider_yaml/terraform/accounts/foo/variables.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/tfe_provider_yaml/terraform/envs/bar/bam/fogg.tf b/testdata/tfe_provider_yaml/terraform/envs/bar/bam/fogg.tf
index cb5b4afe..6c6545be 100644
--- a/testdata/tfe_provider_yaml/terraform/envs/bar/bam/fogg.tf
+++ b/testdata/tfe_provider_yaml/terraform/envs/bar/bam/fogg.tf
@@ -1,7 +1,7 @@
 # Auto-generated by fogg. Do not edit
 # Make improvements in fogg, so that everyone can benefit.
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -55,7 +55,6 @@ data terraform_remote_state global {
 
   }
 }
-# remote state for accounts
 data terraform_remote_state foo {
   backend = "s3"
   config = {
@@ -70,13 +69,10 @@ data terraform_remote_state foo {
 
   }
 }
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
 
-
-
   }
 }
 provider random {
diff --git a/testdata/tfe_provider_yaml/terraform/global/fogg.tf b/testdata/tfe_provider_yaml/terraform/global/fogg.tf
index 89d4ddbf..ed6dcced 100644
--- a/testdata/tfe_provider_yaml/terraform/global/fogg.tf
+++ b/testdata/tfe_provider_yaml/terraform/global/fogg.tf
@@ -5,7 +5,7 @@ provider tfe {
   version = "~>1.1.1"
 }
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -45,6 +45,12 @@ variable tags {
     managedBy = "terraform"
   }
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }
diff --git a/testdata/v2_full_yaml/terraform/accounts/bar/README.md b/testdata/v2_full_yaml/terraform/accounts/bar/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/v2_full_yaml/terraform/accounts/bar/fogg.tf b/testdata/v2_full_yaml/terraform/accounts/bar/fogg.tf
index 7c8c12c8..76e0698b 100644
--- a/testdata/v2_full_yaml/terraform/accounts/bar/fogg.tf
+++ b/testdata/v2_full_yaml/terraform/accounts/bar/fogg.tf
@@ -50,6 +50,7 @@ provider bless {
 }
 terraform {
   required_version = "=0.100.0"
+
   backend s3 {
 
     bucket = "buck"
@@ -62,6 +63,10 @@ terraform {
 
   }
 }
+variable env {
+  type    = string
+  default = "accounts"
+}
 variable project {
   type    = string
   default = "proj"
@@ -70,14 +75,18 @@ variable region {
   type    = string
   default = "us-west-2"
 }
-variable owner {
+variable component {
   type    = string
-  default = "foo@example.com"
+  default = "bar"
 }
 variable account {
   type    = string
   default = "bar"
 }
+variable owner {
+  type    = string
+  default = "foo@example.com"
+}
 variable tags {
   type = object({ project : string, env : string, service : string, owner : string, managedBy : string })
   default = {
@@ -88,33 +97,32 @@ variable tags {
     managedBy = "terraform"
   }
 }
-# map of aws_accounts
-variable aws_accounts {
-  type = map
-  default = {
-
-
-    bar = 456
+variable foo {
+  type    = string
+  default = "bar1"
+}
+data terraform_remote_state global {
+  backend = "s3"
+  config = {
 
 
+    bucket = "buck"
 
-    foo = 123
+    key     = "terraform/proj/global.tfstate"
+    region  = "us-west-2"
+    profile = "profile"
 
 
   }
 }
-variable foo {
-  type    = string
-  default = "bar1"
-}
-data terraform_remote_state global {
+data terraform_remote_state bar {
   backend = "s3"
   config = {
 
 
     bucket = "buck"
 
-    key     = "terraform/proj/global.tfstate"
+    key     = "terraform/proj/accounts/bar.tfstate"
     region  = "us-west-2"
     profile = "profile"
 
@@ -135,6 +143,16 @@ data terraform_remote_state foo {
 
   }
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+    bar = 456
+
+    foo = 123
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }
diff --git a/testdata/v2_full_yaml/terraform/accounts/bar/main.tf b/testdata/v2_full_yaml/terraform/accounts/bar/main.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/v2_full_yaml/terraform/accounts/bar/outputs.tf b/testdata/v2_full_yaml/terraform/accounts/bar/outputs.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/v2_full_yaml/terraform/accounts/bar/variables.tf b/testdata/v2_full_yaml/terraform/accounts/bar/variables.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/v2_full_yaml/terraform/accounts/foo/README.md b/testdata/v2_full_yaml/terraform/accounts/foo/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/v2_full_yaml/terraform/accounts/foo/fogg.tf b/testdata/v2_full_yaml/terraform/accounts/foo/fogg.tf
index bfe59ee0..1c0aa136 100644
--- a/testdata/v2_full_yaml/terraform/accounts/foo/fogg.tf
+++ b/testdata/v2_full_yaml/terraform/accounts/foo/fogg.tf
@@ -22,6 +22,7 @@ provider bless {
 }
 terraform {
   required_version = "=0.100.0"
+
   backend s3 {
 
     bucket = "buck"
@@ -34,6 +35,10 @@ terraform {
 
   }
 }
+variable env {
+  type    = string
+  default = "accounts"
+}
 variable project {
   type    = string
   default = "proj"
@@ -42,14 +47,18 @@ variable region {
   type    = string
   default = "us-west-2"
 }
-variable owner {
+variable component {
   type    = string
-  default = "foo@example.com"
+  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 = {
@@ -60,21 +69,6 @@ variable tags {
     managedBy = "terraform"
   }
 }
-# map of aws_accounts
-variable aws_accounts {
-  type = map
-  default = {
-
-
-    bar = 456
-
-
-
-    foo = 123
-
-
-  }
-}
 variable foo {
   type    = string
   default = "bar1"
@@ -93,6 +87,16 @@ data terraform_remote_state global {
 
   }
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+    bar = 456
+
+    foo = 123
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }
diff --git a/testdata/v2_full_yaml/terraform/accounts/foo/main.tf b/testdata/v2_full_yaml/terraform/accounts/foo/main.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/v2_full_yaml/terraform/accounts/foo/outputs.tf b/testdata/v2_full_yaml/terraform/accounts/foo/outputs.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/v2_full_yaml/terraform/accounts/foo/variables.tf b/testdata/v2_full_yaml/terraform/accounts/foo/variables.tf
new file mode 100644
index 00000000..e69de29b
diff --git a/testdata/v2_full_yaml/terraform/envs/prod/datadog/fogg.tf b/testdata/v2_full_yaml/terraform/envs/prod/datadog/fogg.tf
index 46f3bc5f..5d68e637 100644
--- a/testdata/v2_full_yaml/terraform/envs/prod/datadog/fogg.tf
+++ b/testdata/v2_full_yaml/terraform/envs/prod/datadog/fogg.tf
@@ -14,7 +14,7 @@ provider aws {
 provider datadog {
 }
 terraform {
-  required_version = "~>0.100.0"
+  required_version = "=0.100.0"
 
   backend s3 {
 
@@ -94,20 +94,14 @@ data terraform_remote_state hero {
 
   }
 }
-# remote state for accounts
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
 
-
     bar = 456
 
-
-
     foo = 123
 
-
   }
 }
 provider random {
diff --git a/testdata/v2_full_yaml/terraform/envs/prod/hero/fogg.tf b/testdata/v2_full_yaml/terraform/envs/prod/hero/fogg.tf
index ed428126..5ab39868 100644
--- a/testdata/v2_full_yaml/terraform/envs/prod/hero/fogg.tf
+++ b/testdata/v2_full_yaml/terraform/envs/prod/hero/fogg.tf
@@ -14,7 +14,7 @@ provider aws {
 provider heroku {
 }
 terraform {
-  required_version = "~>0.100.0"
+  required_version = "=0.100.0"
 
   backend s3 {
 
@@ -80,20 +80,14 @@ data terraform_remote_state global {
 
   }
 }
-# remote state for accounts
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
 
-
     bar = 456
 
-
-
     foo = 123
 
-
   }
 }
 provider random {
diff --git a/testdata/v2_full_yaml/terraform/envs/prod/vpc/fogg.tf b/testdata/v2_full_yaml/terraform/envs/prod/vpc/fogg.tf
index ecabf810..5bb95a75 100644
--- a/testdata/v2_full_yaml/terraform/envs/prod/vpc/fogg.tf
+++ b/testdata/v2_full_yaml/terraform/envs/prod/vpc/fogg.tf
@@ -11,7 +11,7 @@ provider aws {
 # Aliased Providers (for doing things in every region).
 
 terraform {
-  required_version = "~>0.100.0"
+  required_version = "=0.100.0"
 
   backend s3 {
 
@@ -105,7 +105,6 @@ data terraform_remote_state hero {
 
   }
 }
-# remote state for accounts
 data terraform_remote_state bar {
   backend = "s3"
   config = {
@@ -134,19 +133,14 @@ data terraform_remote_state foo {
 
   }
 }
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
 
-
     bar = 456
 
-
-
     foo = 123
 
-
   }
 }
 provider random {
diff --git a/testdata/v2_full_yaml/terraform/envs/staging/comp1/fogg.tf b/testdata/v2_full_yaml/terraform/envs/staging/comp1/fogg.tf
index 4725c2cb..ee2c1450 100644
--- a/testdata/v2_full_yaml/terraform/envs/staging/comp1/fogg.tf
+++ b/testdata/v2_full_yaml/terraform/envs/staging/comp1/fogg.tf
@@ -11,7 +11,7 @@ provider aws {
 # Aliased Providers (for doing things in every region).
 
 terraform {
-  required_version = "~>0.100.0"
+  required_version = "=0.100.0"
 
   backend s3 {
 
@@ -105,7 +105,6 @@ data terraform_remote_state vpc {
 
   }
 }
-# remote state for accounts
 data terraform_remote_state bar {
   backend = "s3"
   config = {
@@ -134,19 +133,14 @@ data terraform_remote_state foo {
 
   }
 }
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
 
-
     bar = 456
 
-
-
     foo = 123
 
-
   }
 }
 provider random {
diff --git a/testdata/v2_full_yaml/terraform/envs/staging/comp2/fogg.tf b/testdata/v2_full_yaml/terraform/envs/staging/comp2/fogg.tf
index d50a7788..243fb55d 100644
--- a/testdata/v2_full_yaml/terraform/envs/staging/comp2/fogg.tf
+++ b/testdata/v2_full_yaml/terraform/envs/staging/comp2/fogg.tf
@@ -11,7 +11,7 @@ provider aws {
 # Aliased Providers (for doing things in every region).
 
 terraform {
-  required_version = "~>0.100.0"
+  required_version = "=0.100.0"
 
   backend s3 {
 
@@ -105,7 +105,6 @@ data terraform_remote_state vpc {
 
   }
 }
-# remote state for accounts
 data terraform_remote_state bar {
   backend = "s3"
   config = {
@@ -134,19 +133,14 @@ data terraform_remote_state foo {
 
   }
 }
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
 
-
     bar = 456
 
-
-
     foo = 123
 
-
   }
 }
 provider random {
diff --git a/testdata/v2_full_yaml/terraform/envs/staging/comp_helm_template/values.yaml b/testdata/v2_full_yaml/terraform/envs/staging/comp_helm_template/values.yaml
index f00d9b81..b7550568 100644
--- a/testdata/v2_full_yaml/terraform/envs/staging/comp_helm_template/values.yaml
+++ b/testdata/v2_full_yaml/terraform/envs/staging/comp_helm_template/values.yaml
@@ -18,6 +18,4 @@ tags:
 foo: bar2
 
 
-aws_accounts:
-  bar: 456
-  foo: 123
+aws_accounts:bar: 456foo: 123
diff --git a/testdata/v2_full_yaml/terraform/envs/staging/vpc/fogg.tf b/testdata/v2_full_yaml/terraform/envs/staging/vpc/fogg.tf
index 799ae0b3..4bd30364 100644
--- a/testdata/v2_full_yaml/terraform/envs/staging/vpc/fogg.tf
+++ b/testdata/v2_full_yaml/terraform/envs/staging/vpc/fogg.tf
@@ -11,7 +11,7 @@ provider aws {
 # Aliased Providers (for doing things in every region).
 
 terraform {
-  required_version = "~>0.100.0"
+  required_version = "=0.100.0"
 
   backend s3 {
 
@@ -105,7 +105,6 @@ data terraform_remote_state comp2 {
 
   }
 }
-# remote state for accounts
 data terraform_remote_state bar {
   backend = "s3"
   config = {
@@ -134,19 +133,14 @@ data terraform_remote_state foo {
 
   }
 }
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
 
-
     bar = 456
 
-
-
     foo = 123
 
-
   }
 }
 provider random {
diff --git a/testdata/v2_full_yaml/terraform/global/fogg.tf b/testdata/v2_full_yaml/terraform/global/fogg.tf
index 7579d0da..073a1048 100644
--- a/testdata/v2_full_yaml/terraform/global/fogg.tf
+++ b/testdata/v2_full_yaml/terraform/global/fogg.tf
@@ -11,7 +11,7 @@ provider aws {
 # Aliased Providers (for doing things in every region).
 
 terraform {
-  required_version = "~>0.100.0"
+  required_version = "=0.100.0"
 
   backend s3 {
 
@@ -63,6 +63,12 @@ variable foo {
   type    = string
   default = "bar1"
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }
diff --git a/testdata/v2_minimal_valid_yaml/terraform/global/fogg.tf b/testdata/v2_minimal_valid_yaml/terraform/global/fogg.tf
index 4e12bfc9..c3351b4f 100644
--- a/testdata/v2_minimal_valid_yaml/terraform/global/fogg.tf
+++ b/testdata/v2_minimal_valid_yaml/terraform/global/fogg.tf
@@ -1,7 +1,7 @@
 # Auto-generated by fogg. Do not edit
 # Make improvements in fogg, so that everyone can benefit.
 terraform {
-  required_version = "~>1.1.1"
+  required_version = "=1.1.1"
 
   backend s3 {
 
@@ -41,6 +41,12 @@ variable tags {
     managedBy = "terraform"
   }
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }
diff --git a/testdata/v2_no_aws_provider_yaml/terraform/envs/staging/vpc/fogg.tf b/testdata/v2_no_aws_provider_yaml/terraform/envs/staging/vpc/fogg.tf
index ecd8adf0..90913ef3 100644
--- a/testdata/v2_no_aws_provider_yaml/terraform/envs/staging/vpc/fogg.tf
+++ b/testdata/v2_no_aws_provider_yaml/terraform/envs/staging/vpc/fogg.tf
@@ -1,7 +1,7 @@
 # Auto-generated by fogg. Do not edit
 # Make improvements in fogg, so that everyone can benefit.
 terraform {
-  required_version = "~>0.100.0"
+  required_version = "=0.100.0"
 
   backend s3 {
 
@@ -59,8 +59,6 @@ data terraform_remote_state global {
 
   }
 }
-# remote state for accounts
-# map of aws_accounts
 variable aws_accounts {
   type = map
   default = {
diff --git a/testdata/v2_no_aws_provider_yaml/terraform/global/fogg.tf b/testdata/v2_no_aws_provider_yaml/terraform/global/fogg.tf
index 08fa3d7d..29e4ac44 100644
--- a/testdata/v2_no_aws_provider_yaml/terraform/global/fogg.tf
+++ b/testdata/v2_no_aws_provider_yaml/terraform/global/fogg.tf
@@ -1,7 +1,7 @@
 # Auto-generated by fogg. Do not edit
 # Make improvements in fogg, so that everyone can benefit.
 terraform {
-  required_version = "~>0.100.0"
+  required_version = "=0.100.0"
 
   backend s3 {
 
@@ -45,6 +45,12 @@ variable foo {
   type    = string
   default = "bar1"
 }
+variable aws_accounts {
+  type = map
+  default = {
+
+  }
+}
 provider random {
   version = "~> 2.2"
 }