Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement state locking with dynamo-db #213

Merged
merged 12 commits into from
Apr 16, 2019
7 changes: 6 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type defaults struct {
AWSRegions []string `json:"aws_regions,omitempty"`
ExtraVars map[string]string `json:"extra_vars"`
InfraBucket string `json:"infra_s3_bucket" validate:"required"`
InfraDynamoTable string `json:"infra_dynamo_db_table" validate:"required"`
Owner string `json:"owner" validate:"required"`
Project string `json:"project" validate:"required"`
TerraformVersion string `json:"terraform_version" validate:"required"`
Expand All @@ -45,6 +46,7 @@ type Account struct {
AWSRegions []string `json:"aws_regions"`
ExtraVars map[string]string `json:"extra_vars,omitempty"`
InfraBucket *string `json:"infra_s3_bucket"`
InfraDynamoTable *string `json:"infra_dynamo_db_table"`
Owner *string `json:"owner"`
Project *string `json:"project"`
TerraformVersion *string `json:"terraform_version"`
Expand All @@ -61,6 +63,7 @@ type Env struct {
AWSRegions []string `json:"aws_regions"`
ExtraVars map[string]string `json:"extra_vars,omitempty"`
InfraBucket *string `json:"infra_s3_bucket"`
InfraDynamoTable *string `json:"infra_dynamo_db_table"`
Owner *string `json:"owner"`
Project *string `json:"project"`
TerraformVersion *string `json:"terraform_version"`
Expand All @@ -79,6 +82,7 @@ type Component struct {
AWSRegions []string `json:"aws_regions"`
ExtraVars map[string]string `json:"extra_vars,omitempty"`
InfraBucket *string `json:"infra_s3_bucket"`
InfraDynamoTable *string `json:"infra_dynamo_db_table"`
ModuleSource *string `json:"module_source"`
Owner *string `json:"owner"`
Project *string `json:"project"`
Expand Down Expand Up @@ -113,7 +117,7 @@ type Config struct {
TravisCI *TravisCI `json:"travis_ci"`
}

func InitConfig(project, region, bucket, awsProfile, owner, awsProviderVersion string) *Config {
func InitConfig(project, region, bucket, table, awsProfile, owner, awsProviderVersion string) *Config {
return &Config{
Defaults: defaults{
AWSProfileBackend: awsProfile,
Expand All @@ -123,6 +127,7 @@ func InitConfig(project, region, bucket, awsProfile, owner, awsProviderVersion s
AWSRegionProvider: region,
ExtraVars: map[string]string{},
InfraBucket: bucket,
InfraDynamoTable: table,
Owner: owner,
Project: project,
TerraformVersion: "0.11.7",
Expand Down
9 changes: 7 additions & 2 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func TestParseDefaults(t *testing.T) {
"aws_profile_backend": "czi",
"aws_profile_provider": "czi",
"infra_s3_bucket": "the-bucket",
"infra_dynamo_db_table": "the-table",
"project": "test-project",
"terraform_version": "0.11.0"
}
Expand All @@ -34,6 +35,7 @@ func TestParseDefaults(t *testing.T) {
assert.Equal(t, "czi", c.Defaults.AWSProfileBackend)
assert.Equal(t, "czi", c.Defaults.AWSProfileProvider)
assert.Equal(t, "the-bucket", c.Defaults.InfraBucket)
assert.Equal(t, "the-table", c.Defaults.InfraDynamoTable)
assert.Equal(t, "test-project", c.Defaults.Project)
assert.Equal(t, "0.11.0", c.Defaults.TerraformVersion)
assert.Equal(t, true, c.Docker)
Expand All @@ -53,6 +55,7 @@ func TestParse(t *testing.T) {
assert.Equal(t, "czi", c.Defaults.AWSProfileBackend)
assert.Equal(t, "czi", c.Defaults.AWSProfileProvider)
assert.Equal(t, "the-bucket", c.Defaults.InfraBucket)
assert.Equal(t, "the-table", c.Defaults.InfraDynamoTable)
assert.Equal(t, "test-project", c.Defaults.Project)
assert.Equal(t, "0.11.0", c.Defaults.TerraformVersion)

Expand Down Expand Up @@ -96,7 +99,7 @@ func TestValidation(t *testing.T) {

err, ok := e.(validator.ValidationErrors)
assert.True(t, ok)
assert.Len(t, err, 9)
assert.Len(t, err, 10)
}

func TestExtraVarsValidation(t *testing.T) {
Expand All @@ -109,6 +112,7 @@ func TestExtraVarsValidation(t *testing.T) {
"aws_profile_provider": "czi",
"aws_provider_version": "czi",
"infra_s3_bucket": "the-bucket",
"infra_dynamo_db_table": "the-table",
"project": "test-project",
"owner": "[email protected]",
"terraform_version": "0.11.0"
Expand All @@ -129,13 +133,14 @@ func TestExtraVarsValidation(t *testing.T) {
}

func TestInitConfig(t *testing.T) {
c := InitConfig("proj", "reg", "buck", "prof", "[email protected]", "0.99.0")
c := InitConfig("proj", "reg", "buck", "table", "prof", "[email protected]", "0.99.0")
assert.Equal(t, "prof", c.Defaults.AWSProfileBackend)
assert.Equal(t, "prof", c.Defaults.AWSProfileProvider)
assert.Equal(t, "reg", c.Defaults.AWSRegionBackend)
assert.Equal(t, "reg", c.Defaults.AWSRegionProvider)
assert.Equal(t, "0.99.0", c.Defaults.AWSProviderVersion)
assert.Equal(t, "buck", c.Defaults.InfraBucket)
assert.Equal(t, "table", c.Defaults.InfraDynamoTable)
assert.Equal(t, "[email protected]", c.Defaults.Owner)
assert.Equal(t, "proj", c.Defaults.Project)
assert.Equal(t, "0.11.7", c.Defaults.TerraformVersion)
Expand Down
3 changes: 2 additions & 1 deletion config/testdata/full.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"aws_region_provider": "us-west-1",
"aws_provider_version": "0.1.0",
"infra_s3_bucket": "the-bucket",
"infra_dynamo_db_table": "the-table",
"owner": "[email protected]",
"project": "test-project",
"terraform_version": "0.11.0"
Expand All @@ -25,4 +26,4 @@
}
},
"modules": {}
}
}
9 changes: 5 additions & 4 deletions init/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ import (

const AWSProviderVersion = "1.27.0"

func userPrompt() (string, string, string, string, string) {
func userPrompt() (string, string, string, string, string, string) {
project := prompt.StringRequired("project name?")
region := prompt.StringRequired("aws region?")
bucket := prompt.StringRequired("infra bucket name?")
table := prompt.StringRequired("infra dynamo table name?")
profile := prompt.StringRequired("auth profile?")
owner := prompt.StringRequired("owner?")

return project, region, bucket, profile, owner
return project, region, bucket, table, profile, owner
}

func writeConfig(fs afero.Fs, config *config.Config) error {
Expand All @@ -35,8 +36,8 @@ func writeConfig(fs afero.Fs, config *config.Config) error {
}

func Init(fs afero.Fs) error {
project, region, bucket, profile, owner := userPrompt()
config := config.InitConfig(project, region, bucket, profile, owner, AWSProviderVersion)
project, region, bucket, table, profile, owner := userPrompt()
config := config.InitConfig(project, region, bucket, table, profile, owner, AWSProviderVersion)
e := writeConfig(fs, config)
return e
}
5 changes: 5 additions & 0 deletions plan/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type AWSConfiguration struct {
AWSRegionProvider string `yaml:"aws_region_provider"`
AWSRegions []string `yaml:"aws_regions"`
InfraBucket string `yaml:"infra_bucket"`
InfraDynamoTable string `yaml:"infra_dynamo_table"`
}

// Common represents common fields
Expand Down Expand Up @@ -158,6 +159,7 @@ func (p *Plan) buildAccounts(c *config.Config) map[string]Account {
accountPlan.AllAccounts = resolveAccounts(c.Accounts)
accountPlan.TerraformVersion = resolveRequired(defaults.TerraformVersion, config.TerraformVersion)
accountPlan.InfraBucket = resolveRequired(defaults.InfraBucket, config.InfraBucket)
accountPlan.InfraDynamoTable = resolveRequired(defaults.InfraDynamoTable, config.InfraDynamoTable)
accountPlan.Owner = resolveRequired(defaults.Owner, config.Owner)
accountPlan.PathToRepoRoot = "../../../"
accountPlan.Project = resolveRequired(defaults.Project, config.Project)
Expand Down Expand Up @@ -211,6 +213,7 @@ func (p *Plan) buildGlobal(conf *config.Config) Component {

componentPlan.TerraformVersion = conf.Defaults.TerraformVersion
componentPlan.InfraBucket = conf.Defaults.InfraBucket
componentPlan.InfraDynamoTable = conf.Defaults.InfraDynamoTable
componentPlan.Owner = conf.Defaults.Owner
componentPlan.PathToRepoRoot = "../../"
componentPlan.Project = conf.Defaults.Project
Expand Down Expand Up @@ -245,6 +248,7 @@ func (p *Plan) buildEnvs(conf *config.Config) (map[string]Env, error) {

envPlan.TerraformVersion = resolveRequired(defaults.TerraformVersion, envConf.TerraformVersion)
envPlan.InfraBucket = resolveRequired(defaults.InfraBucket, envConf.InfraBucket)
envPlan.InfraDynamoTable = resolveRequired(defaults.InfraDynamoTable, envConf.InfraDynamoTable)
envPlan.Owner = resolveRequired(defaults.Owner, envConf.Owner)
envPlan.Project = resolveRequired(defaults.Project, envConf.Project)
envPlan.ExtraVars = resolveExtraVars(defaultExtraVars, envConf.ExtraVars)
Expand All @@ -271,6 +275,7 @@ func (p *Plan) buildEnvs(conf *config.Config) (map[string]Env, error) {

componentPlan.TerraformVersion = resolveRequired(envPlan.TerraformVersion, componentConf.TerraformVersion)
componentPlan.InfraBucket = resolveRequired(envPlan.InfraBucket, componentConf.InfraBucket)
componentPlan.InfraDynamoTable = resolveRequired(envPlan.InfraDynamoTable, componentConf.InfraDynamoTable)
componentPlan.Owner = resolveRequired(envPlan.Owner, componentConf.Owner)
componentPlan.Project = resolveRequired(envPlan.Project, componentConf.Project)

Expand Down
18 changes: 10 additions & 8 deletions templates/account/fogg.tf.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ terraform {
required_version = "={{ .TerraformVersion }}"

backend "s3" {
bucket = "{{ .InfraBucket }}"
key = "terraform/{{ .Project }}/accounts/{{ .AccountName }}.tfstate"
encrypt = true
region = "{{ .AWSRegionBackend }}"
profile = "{{ .AWSProfileBackend }}"
bucket = "{{ .InfraBucket }}"
dynamodb_table = "{{ .InfraDynamoTable }}"
key = "terraform/{{ .Project }}/accounts/{{ .AccountName }}.tfstate"
encrypt = true
region = "{{ .AWSRegionBackend }}"
profile = "{{ .AWSProfileBackend }}"
}
}

Expand Down Expand Up @@ -75,9 +76,10 @@ data "terraform_remote_state" "global" {
backend = "s3"

config {
bucket = "{{ .InfraBucket }}"
key = "terraform/{{ .Project }}/global.tfstate"
region = "{{ .AWSRegionBackend }}"
bucket = "{{ .InfraBucket }}"
dynamodb_table = "{{ .InfraDynamoTable }}"
key = "terraform/{{ .Project }}/global.tfstate"
region = "{{ .AWSRegionBackend }}"
{{ if .AWSProfileBackend }}profile = "{{ .AWSProfileBackend }}"{{ end }}
}
}
26 changes: 15 additions & 11 deletions templates/component/fogg.tf.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ terraform {
required_version = "~>{{ .TerraformVersion }}"

backend "s3" {
bucket = "{{ .InfraBucket }}"
bucket = "{{ .InfraBucket }}"
dynamodb_table = "{{ .InfraDynamoTable }}"
{{/* {%- if env is defined and component_name is defined %} */}}
key = "terraform/{{ .Project }}/envs/{{ .Env }}/components/{{ .Component }}.tfstate"
key = "terraform/{{ .Project }}/envs/{{ .Env }}/components/{{ .Component }}.tfstate"

{{/*
{%- else %}
Expand Down Expand Up @@ -91,9 +92,10 @@ data "terraform_remote_state" "global" {
backend = "s3"

config {
bucket = "{{ $out.InfraBucket }}"
key = "terraform/{{ .Project }}/global.tfstate"
region = "{{ $out.AWSRegionBackend }}"
bucket = "{{ $out.InfraBucket }}"
dynamodb_table = "{{ $out.InfraDynamoTable }}"
key = "terraform/{{ .Project }}/global.tfstate"
region = "{{ $out.AWSRegionBackend }}"
{{ if $out.AWSProfileBackend }}profile = "{{ $out.AWSProfileBackend }}"{{ end }}
}
}
Expand All @@ -103,9 +105,10 @@ data "terraform_remote_state" "{{ $component }}" {
backend = "s3"

config {
bucket = "{{ $out.InfraBucket }}"
key = "terraform/{{ $out.Project }}/envs/{{ $out.Env }}/components/{{ $component }}.tfstate"
region = "{{ $out.AWSRegionBackend }}"
bucket = "{{ $out.InfraBucket }}"
dynamodb_table = "{{ $out.InfraDynamoTable }}"
key = "terraform/{{ $out.Project }}/envs/{{ $out.Env }}/components/{{ $component }}.tfstate"
region = "{{ $out.AWSRegionBackend }}"
{{ if $out.AWSProfileBackend }}profile = "{{ $out.AWSProfileBackend }}"{{ end }}
}
}
Expand All @@ -117,9 +120,10 @@ data "terraform_remote_state" "{{ $accountName }}" {
backend = "s3"

config {
bucket = "{{ $account.InfraBucket }}"
key = "terraform/{{ .Project }}/accounts/{{ $account.AccountName }}.tfstate"
region = "{{ $account.AWSRegionBackend }}"
bucket = "{{ $account.InfraBucket }}"
dynamodb_table = "{{ $account.InfraDynamoTable }}"
key = "terraform/{{ .Project }}/accounts/{{ $account.AccountName }}.tfstate"
region = "{{ $account.AWSRegionBackend }}"
{{ if $account.AWSProfileBackend }}profile = "{{ $account.AWSProfileBackend }}"{{ end }}
}
}
Expand Down
10 changes: 6 additions & 4 deletions templates/global/fogg.tf.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ terraform {
required_version = "~>{{ .TerraformVersion }}"

backend "s3" {
bucket = "{{ .InfraBucket }}"
bucket = "{{ .InfraBucket }}"
dynamodb_table = "{{ .InfraDynamoTable }}"
{{/* {%- if env is defined and component_name is defined %} */}}
key = "terraform/{{ .Project }}/{{ .Component }}.tfstate"

Expand Down Expand Up @@ -92,9 +93,10 @@ data "terraform_remote_state" "{{ $component }}" {
backend = "s3"

config {
bucket = "{{ $out.InfraBucket }}"
key = "terraform/{{ $out.Project }}/envs/{{ $out.Env }}/components/{{ $component }}.tfstate"
region = "{{ $out.AWSRegionBackend }}"
bucket = "{{ $out.InfraBucket }}"
dynamodb_table = "{{ .InfraDynamoTable }}"
key = "terraform/{{ $out.Project }}/envs/{{ $out.Env }}/components/{{ $component }}.tfstate"
region = "{{ $out.AWSRegionBackend }}"
{{ if $out.AWSProfileBackend }}profile = "{{ $out.AWSProfileBackend }}"{{ end }}
}
}
Expand Down