Skip to content

Commit

Permalink
Add metadata.terraform_workspace_pattern (#138)
Browse files Browse the repository at this point in the history
* updates

* updates

* updates

* Add `metadata.terraform_workspace_pattern`

* Add `metadata.terraform_workspace_pattern`

* Add `metadata.terraform_workspace_pattern`
  • Loading branch information
aknysh committed Apr 18, 2022
1 parent a09ad46 commit 803ec0f
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 42 deletions.
Expand Up @@ -40,3 +40,7 @@ components:
val2: "5"
val3: 7
val4: null
metadata:
# Override Terraform workspace
# Note that by default, Terraform workspace is generated from the context, e.g. `<environment>-<stage>`
terraform_workspace_pattern: "{tenant}-{environment}-{stage}-{component}"
37 changes: 37 additions & 0 deletions internal/exec/stack_utils.go
@@ -0,0 +1,37 @@
package exec

import (
"fmt"
c "github.com/cloudposse/atmos/pkg/config"
"strings"
)

// BuildTerraformWorkspace builds Terraform workspace
func BuildTerraformWorkspace(
stack string,
stackNamePattern string,
componentMetadata map[interface{}]interface{},
context c.Context,
) (string, error) {

contextPrefix, err := c.GetContextPrefix(stack, context, stackNamePattern)
if err != nil {
return "", err
}

var workspace string

if terraformWorkspacePattern, terraformWorkspacePatternExist := componentMetadata["terraform_workspace_pattern"].(string); terraformWorkspacePatternExist {
// Terraform workspace can be overridden per component in YAML config `metadata.terraform_workspace_pattern`
workspace = c.ReplaceContextTokens(context, terraformWorkspacePattern)
} else if terraformWorkspace, terraformWorkspaceExist := componentMetadata["terraform_workspace"].(string); terraformWorkspaceExist {
// Terraform workspace can be overridden per component in YAML config `metadata.terraform_workspace`
workspace = terraformWorkspace
} else if context.BaseComponent == "" {
workspace = contextPrefix
} else {
workspace = fmt.Sprintf("%s-%s", contextPrefix, context.Component)
}

return strings.Replace(workspace, "/", "-", -1), nil
}
21 changes: 11 additions & 10 deletions internal/exec/utils.go
Expand Up @@ -417,23 +417,23 @@ func ProcessStacks(configAndStacksInfo c.ConfigAndStacksInfo, checkStack bool) (

// Process context
configAndStacksInfo.Context = c.GetContextFromVars(configAndStacksInfo.ComponentVarsSection)
configAndStacksInfo.Context.Component = configAndStacksInfo.ComponentFromArg
configAndStacksInfo.Context.BaseComponent = configAndStacksInfo.BaseComponentPath
configAndStacksInfo.ContextPrefix, err = c.GetContextPrefix(configAndStacksInfo.Stack, configAndStacksInfo.Context, c.Config.Stacks.NamePattern)
if err != nil {
return configAndStacksInfo, err
}

// workspace
var workspace string
// Terraform workspace can be overridden per component in YAML config `metadata.terraform_workspace`
if componentTerraformWorkspace, componentTerraformWorkspaceExist := configAndStacksInfo.ComponentMetadataSection["terraform_workspace"].(string); componentTerraformWorkspaceExist {
workspace = componentTerraformWorkspace
} else if len(configAndStacksInfo.BaseComponent) == 0 {
workspace = configAndStacksInfo.ContextPrefix
} else {
workspace = fmt.Sprintf("%s-%s", configAndStacksInfo.ContextPrefix, configAndStacksInfo.ComponentFromArg)
workspace, err := BuildTerraformWorkspace(
configAndStacksInfo.Stack,
c.Config.Stacks.NamePattern,
configAndStacksInfo.ComponentMetadataSection,
configAndStacksInfo.Context,
)
if err != nil {
return configAndStacksInfo, err
}

workspace = strings.Replace(workspace, "/", "-", -1)
configAndStacksInfo.TerraformWorkspace = workspace
configAndStacksInfo.ComponentSection["workspace"] = workspace

Expand Down Expand Up @@ -637,6 +637,7 @@ func processArgsAndFlags(inputArgsAndFlags []string) (c.ArgsAndFlagsInfo, error)
return info, nil
}

// generateComponentBackendConfig generates backend config for components
func generateComponentBackendConfig(backendType string, backendConfig map[interface{}]interface{}) map[string]interface{} {
return map[string]interface{}{
"terraform": map[string]interface{}{
Expand Down
13 changes: 7 additions & 6 deletions pkg/config/schema.go
Expand Up @@ -56,12 +56,13 @@ type ProcessedConfiguration struct {
}

type Context struct {
Namespace string
Tenant string
Environment string
Stage string
Region string
Component string
Namespace string
Tenant string
Environment string
Stage string
Region string
Component string
BaseComponent string
}

type ArgsAndFlagsInfo struct {
Expand Down
21 changes: 10 additions & 11 deletions pkg/config/utils.go
Expand Up @@ -428,16 +428,15 @@ func GetContextPrefix(stack string, context Context, stackNamePattern string) (s
return contextPrefix, nil
}

// ReplaceContextTokens replaces tokens in the context pattern
// ReplaceContextTokens replaces context tokens in the provided pattern and returns a string with all the tokens replaced
func ReplaceContextTokens(context Context, pattern string) string {
return strings.Replace(
strings.Replace(
strings.Replace(
strings.Replace(
strings.Replace(pattern,
"{component}", context.Component, 1),
"{namespace}", context.Namespace, 1),
"{environment}", context.Environment, 1),
"{tenant}", context.Tenant, 1),
"{stage}", context.Stage, 1)
r := strings.NewReplacer(
"{base-component}", context.BaseComponent,
"{component}", context.Component,
"{namespace}", context.Namespace,
"{environment}", context.Environment,
"{tenant}", context.Tenant,
"{stage}", context.Stage,
)
return r.Replace(pattern)
}
45 changes: 30 additions & 15 deletions pkg/spacelift/spacelift_stack_processor.go
Expand Up @@ -2,6 +2,7 @@ package spacelift

import (
"fmt"
e "github.com/cloudposse/atmos/internal/exec"
c "github.com/cloudposse/atmos/pkg/config"
s "github.com/cloudposse/atmos/pkg/stack"
u "github.com/cloudposse/atmos/pkg/utils"
Expand Down Expand Up @@ -366,7 +367,27 @@ func TransformStackConfigToSpaceliftStacks(
componentInheritance = i.([]string)
}

// Process base component
// Base component can be specified in two places:
// `component` attribute (legacy)
// `metadata.component` attribute
// `metadata.component` takes precedence over `component`
baseComponentName := ""
if baseComponent, baseComponentExist := componentMap["component"]; baseComponentExist {
baseComponentName = baseComponent.(string)
}
// First check if component's `metadata` section exists
// Then check if `metadata.component` exists
if componentMetadata, componentMetadataExists := componentMap["metadata"].(map[interface{}]interface{}); componentMetadataExists {
if componentFromMetadata, componentFromMetadataExists := componentMetadata["component"].(string); componentFromMetadataExists {
baseComponentName = componentFromMetadata
}
}

context := c.GetContextFromVars(componentVars)
context.Component = component
context.BaseComponent = baseComponentName

contextPrefix, err := c.GetContextPrefix(stackName, context, stackNamePattern)
if err != nil {
return nil, err
Expand All @@ -381,11 +402,6 @@ func TransformStackConfigToSpaceliftStacks(
spaceliftConfig["deps"] = componentDeps
spaceliftConfig["stacks"] = componentStacks
spaceliftConfig["inheritance"] = componentInheritance

baseComponentName := ""
if baseComponent, baseComponentExist := componentMap["component"]; baseComponentExist {
baseComponentName = baseComponent.(string)
}
spaceliftConfig["base_component"] = baseComponentName

// backend
Expand All @@ -409,16 +425,16 @@ func TransformStackConfigToSpaceliftStacks(
spaceliftConfig["metadata"] = componentMetadata

// workspace
var workspace string
// Terraform workspace can be overridden per component in YAML config `metadata.terraform_workspace`
if componentTerraformWorkspace, componentTerraformWorkspaceExist := componentMetadata["terraform_workspace"].(string); componentTerraformWorkspaceExist {
workspace = componentTerraformWorkspace
} else if backendTypeName == "s3" && baseComponentName == "" {
workspace = contextPrefix
} else {
workspace = fmt.Sprintf("%s-%s", contextPrefix, component)
workspace, err := e.BuildTerraformWorkspace(
stackName,
stackNamePattern,
componentMetadata,
context,
)
if err != nil {
return nil, err
}
spaceliftConfig["workspace"] = strings.Replace(workspace, "/", "-", -1)
spaceliftConfig["workspace"] = workspace

// labels
labels := []string{}
Expand Down Expand Up @@ -460,7 +476,6 @@ func TransformStackConfigToSpaceliftStacks(
spaceliftConfig["labels"] = u.UniqueStrings(labels)

// Spacelift stack name
context.Component = component
spaceliftStackName, spaceliftStackNamePattern := buildSpaceliftStackName(spaceliftSettings, context, contextPrefix)

// Add Spacelift stack config to the final map
Expand Down

0 comments on commit 803ec0f

Please sign in to comment.