diff --git a/README.md b/README.md index 7f15036..167c78b 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ gcp-org: - `inventory_path` = relative path to the folder with jsons - `cmd_to_exec` = name of the binary to execute (`tofu` or `terraform`) - `backend` = Config values for backend provider. All the child key:values will be provided to `init` and `$tofugu_state_path` will be replaced by generated path. -For example, it will look like `tofu init -backend-config=bucket=gcp-tfstates -backend-config=prefix=account_free-tier/free_instance.tfstate` +For example, when you will execute `tofugu cook ...... -- init`, TofuGu actually will execute `init -backend-config=bucket=gcp-tfstates -backend-config=prefix=account_free-tier/free_instance.tfstate` At least ```yaml @@ -185,9 +185,9 @@ Examples: - [Shared module for VPC creation](examples/tofies/shared-modules/create_vpc) - [Shared module for VPC creation used in code](examples/tofies/demo-org/vpc/main.tf#L3) -## Remote state in S3 +## Remote state (Terraform Backend where state data files are stored) -AWS, Google Cloud and some other backends are supported! You could configure any backend provider in `tofugu config file` +AWS, Google Cloud and some other backends are supported! You could configure any backend provider in [TofuGu Config file](#hometofugu) [For AWS S3 your terraform code (`tofi`) should contains at least:](examples/tofies/demo-org/vpc/versions.tf#L4): ``` @@ -209,6 +209,35 @@ If for the `demo-org` config `bucket` is NOT set, then `$tofugu_state_path` will This could be useful, if you want to store by default tfstate for all the organisations in the same/default bucket `default-tfstates` but for some specific organisation you need to store tfstates in dedicated bucket `demo-org-tfstates` +## Data Source Configuration (data "terraform_remote_state") + +To simplify "Data Source Configuration" (`data "terraform_remote_state" "tfstate" { }`) will be nice to have backend config values as tfvars. + +`var.tofugu_backend_config` will contain all the parameters from [TofuGu config (backend Section)](#hometofugu) + +[For example, for AWS S3](examples/tofies/demo-org/vpc/data.tf): +``` +data "terraform_remote_state" "network" { + backend = "s3" + config = { + bucket = var.tofugu_backend_config.bucket + key = "network/terraform.tfstate" + region = var.tofugu_backend_config.region + } +} +``` +[And for GCS](examples/tofies/gcp-org/free_instance/data.tf): +``` +data "terraform_remote_state" "free_instance" { + backend = "gcs" + config = { + bucket = var.tofugu_backend_config.bucket + prefix = "account_free-tier/free_instance.tfstate" + } +} +``` + +You will set `key/prefix` to another tofie's tfstate, which outputs you want to use. ## $HOME/.tofurc diff --git a/cmd/cook.go b/cmd/cook.go index 4b381bd..23c2cd7 100644 --- a/cmd/cook.go +++ b/cmd/cook.go @@ -40,16 +40,21 @@ var cookCmd = &cobra.Command{ tofuguStruct.ParseTofiManifest("tofi_manifest.json") tofuguStruct.ParseDimensions() - backendConfig := tofuguStruct.SetupBackendConfig() + backendTofuguConfig := tofuguStruct.SetupBackendConfig() tofuguStruct.PrepareTemp() tofuguStruct.GenerateVarsByDims() tofuguStruct.GenerateVarsByDimOptional("defaults") tofuguStruct.GenerateVarsByEnvVars() + tofuguStruct.GenerateVarsByDimAndData("config", "backend", backendTofuguConfig) //Local variables for child execution forceCleanTempDir, _ := cmd.Flags().GetBool("clean") + var backendConfig []string + for param, value := range backendTofuguConfig { + backendConfig = append(backendConfig, "-backend-config="+param+"="+value.(string)) + } cmdArgs := args if args[0] == "init" { cmdArgs = append(cmdArgs, backendConfig...) diff --git a/examples/tofies/demo-org/vpc/data.tf b/examples/tofies/demo-org/vpc/data.tf new file mode 100644 index 0000000..09d1cf9 --- /dev/null +++ b/examples/tofies/demo-org/vpc/data.tf @@ -0,0 +1,8 @@ +# data "terraform_remote_state" "network" { +# backend = "s3" +# config = { +# bucket = var.tofugu_backend_config.bucket +# key = "network/terraform.tfstate" +# region = var.tofugu_backend_config.region +# } +# } \ No newline at end of file diff --git a/examples/tofies/gcp-org/free_instance/data.tf b/examples/tofies/gcp-org/free_instance/data.tf new file mode 100644 index 0000000..a630832 --- /dev/null +++ b/examples/tofies/gcp-org/free_instance/data.tf @@ -0,0 +1,7 @@ +# data "terraform_remote_state" "free_instance" { +# backend = "gcs" +# config = { +# bucket = var.tofugu_backend_config.bucket +# prefix = "account_free-tier/free_instance.tfstate" +# } +# } \ No newline at end of file diff --git a/utils/externals.go b/utils/externals.go index 6b256b1..13a0179 100644 --- a/utils/externals.go +++ b/utils/externals.go @@ -35,9 +35,7 @@ func (tofuguStruct *Tofugu) GetObjectFromViperByOrgOrDefault(keyName string) map } } -func (tofuguStruct *Tofugu) SetupBackendConfig() []string { - var backendFinalConfig []string - +func (tofuguStruct *Tofugu) SetupBackendConfig() map[string]interface{} { var stateS3Path string if !viper.IsSet(tofuguStruct.OrgName + ".backend") { stateS3Path = stateS3Path + "org_" + tofuguStruct.OrgName + "/" @@ -52,12 +50,13 @@ func (tofuguStruct *Tofugu) SetupBackendConfig() []string { if len(backendTofuguConfig) == 0 { log.Println("Tofugu: no backend config provied!") } + + var backendTofuguConfigMap = make(map[string]interface{}, len(backendTofuguConfig)) for param, value := range backendTofuguConfig { - replacedVar := strings.Replace(value.(string), "$tofugu_state_path", tofuguStruct.StateS3Path, 1) - backendFinalConfig = append(backendFinalConfig, "-backend-config="+param+"="+replacedVar) + backendTofuguConfigMap[param] = strings.Replace(value.(string), "$tofugu_state_path", tofuguStruct.StateS3Path, 1) } - return backendFinalConfig + return backendTofuguConfigMap } func (tofuguStruct *Tofugu) GetDimData(dimensionKey string, dimensionValue string, skipOnNotFound bool) map[string]interface{} { diff --git a/utils/generatevars.go b/utils/generatevars.go index b627752..adbc271 100644 --- a/utils/generatevars.go +++ b/utils/generatevars.go @@ -36,6 +36,14 @@ func (tofuguStruct *Tofugu) GenerateVarsByDimOptional(optionType string) { } } +func (tofuguStruct *Tofugu) GenerateVarsByDimAndData(optionType string, dimKey string, dimensionJsonMap map[string]interface{}) { + targetAutoTfvarMap := map[string]interface{}{ + "tofugu_" + dimKey + "_" + optionType: dimensionJsonMap, + } + writeTfvarsMaps(targetAutoTfvarMap, dimKey+"_"+optionType, tofuguStruct.CmdWorkTempDir) + log.Println("TofuGu attached " + optionType + " in var.tofugu_" + dimKey + "_" + optionType) +} + func (tofuguStruct *Tofugu) GenerateVarsByEnvVars() { targetAutoTfvarMap := make(map[string]interface{}) diff --git a/utils/preparetemp.go b/utils/preparetemp.go index c39ecb2..2a4ed73 100644 --- a/utils/preparetemp.go +++ b/utils/preparetemp.go @@ -7,6 +7,10 @@ import ( ) func (tofuguStruct *Tofugu) PrepareTemp() { + if tofuguStruct.StateS3Path == "" { + log.Fatalf("StateS3Path is empty \n") + } + tmpFolderNameSuffix := tofuguStruct.OrgName + tofuguStruct.StateS3Path + tofuguStruct.TofiName cmdTempDirFullPath := os.TempDir() + "/tofugu-" + GetMD5Hash(tmpFolderNameSuffix)