Skip to content

Commit

Permalink
Skip component if metadata.enabled is set to false (#756)
Browse files Browse the repository at this point in the history
* skip components if not enabled

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

* by default make component is enabled

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

* refactor code

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

* use disable instead of enable to use default value

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

* rename to metadata.enabled

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

* make by default enabled value is true

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

* fix bug

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

* add doc

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

* update doc

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

* fix typo

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

* fix indentation

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

* Update website/docs/core-concepts/stacks/define-components.mdx

Co-authored-by: Erik Osterman (CEO @ Cloud Posse) <[email protected]>

* Update website/docs/core-concepts/stacks/define-components.mdx

Co-authored-by: Erik Osterman (CEO @ Cloud Posse) <[email protected]>

* Update website/docs/core-concepts/stacks/define-components.mdx

Co-authored-by: Erik Osterman (CEO @ Cloud Posse) <[email protected]>

* Update website/docs/core-concepts/stacks/define-components.mdx

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix note

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>

---------

Signed-off-by: Pulak Kanti Bhowmick <[email protected]>
Co-authored-by: Erik Osterman (CEO @ Cloud Posse) <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 8, 2024
1 parent 4617630 commit 3342e8e
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 8 deletions.
5 changes: 5 additions & 0 deletions internal/exec/helmfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ func ExecuteHelmfile(info schema.ConfigAndStacksInfo) error {
return errors.New("stack must be specified")
}

if !info.ComponentIsEnabled {
u.LogInfo(cliConfig, fmt.Sprintf("component '%s' is not enabled and skipped", info.ComponentFromArg))
return nil
}

err = checkHelmfileConfig(cliConfig)
if err != nil {
return err
Expand Down
12 changes: 9 additions & 3 deletions internal/exec/stack_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,14 @@ func BuildTerraformWorkspace(cliConfig schema.CliConfiguration, configAndStacksI
return strings.Replace(workspace, "/", "-", -1), nil
}

// ProcessComponentMetadata processes component metadata and returns a base component (if any) and whether the component is real or abstract
// ProcessComponentMetadata processes component metadata and returns a base component (if any) and whether the component is real or abstract and whether the component is disabled or not
func ProcessComponentMetadata(
component string,
componentSection map[string]any,
) (map[string]any, string, bool) {
) (map[string]any, string, bool, bool) {
baseComponentName := ""
componentIsAbstract := false
componentIsEnabled := true
var componentMetadata map[string]any

// Find base component in the `component` attribute
Expand All @@ -75,6 +76,11 @@ func ProcessComponentMetadata(
componentIsAbstract = true
}
}
if enabledValue, exists := componentMetadata["enabled"]; exists {
if enabled, ok := enabledValue.(bool); ok && !enabled {
componentIsEnabled = false
}
}
// Find base component in the `metadata.component` attribute
// `metadata.component` overrides `component`
if componentMetadataComponent, componentMetadataComponentExists := componentMetadata[cfg.ComponentSectionName].(string); componentMetadataComponentExists {
Expand All @@ -87,7 +93,7 @@ func ProcessComponentMetadata(
baseComponentName = ""
}

return componentMetadata, baseComponentName, componentIsAbstract
return componentMetadata, baseComponentName, componentIsAbstract, componentIsEnabled
}

// BuildDependentStackNameFromDependsOnLegacy builds the dependent stack name from "settings.spacelift.depends_on" config
Expand Down
5 changes: 5 additions & 0 deletions internal/exec/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ func ExecuteTerraform(info schema.ConfigAndStacksInfo) error {
return errors.New("stack must be specified")
}

if !info.ComponentIsEnabled {
u.LogInfo(cliConfig, fmt.Sprintf("component '%s' is not enabled and skipped", info.ComponentFromArg))
return nil
}

err = checkTerraformConfig(cliConfig)
if err != nil {
return err
Expand Down
8 changes: 5 additions & 3 deletions internal/exec/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ func ProcessComponentConfig(
}

// Process component metadata and find a base component (if any) and whether the component is real or abstract
componentMetadata, baseComponentName, componentIsAbstract := ProcessComponentMetadata(component, componentSection)
componentMetadata, baseComponentName, componentIsAbstract, componentIsEnabled := ProcessComponentMetadata(component, componentSection)
configAndStacksInfo.ComponentIsEnabled = componentIsEnabled

// Remove the ENV vars that are set to `null` in the `env` section.
// Setting an ENV var to `null` in stack config has the effect of unsetting it
Expand Down Expand Up @@ -391,7 +392,7 @@ func ProcessStacks(
}
}

if foundStackCount == 0 {
if foundStackCount == 0 && configAndStacksInfo.ComponentIsEnabled {
cliConfigYaml := ""

if cliConfig.Logs.Level == u.LogLevelTrace {
Expand Down Expand Up @@ -573,8 +574,9 @@ func ProcessStacks(
configAndStacksInfo.ComponentEnvList = u.ConvertEnvVars(configAndStacksInfo.ComponentEnvSection)

// Process component metadata
_, baseComponentName, _ := ProcessComponentMetadata(configAndStacksInfo.ComponentFromArg, configAndStacksInfo.ComponentSection)
_, baseComponentName, _, componentIsEnabled := ProcessComponentMetadata(configAndStacksInfo.ComponentFromArg, configAndStacksInfo.ComponentSection)
configAndStacksInfo.BaseComponentPath = baseComponentName
configAndStacksInfo.ComponentIsEnabled = componentIsEnabled

// Process component path and name
configAndStacksInfo.ComponentFolderPrefix = ""
Expand Down
1 change: 1 addition & 0 deletions pkg/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ type ConfigAndStacksInfo struct {
ComponentImportsSection []string
NeedHelp bool
ComponentIsAbstract bool
ComponentIsEnabled bool
ComponentMetadataSection AtmosSectionMapType
TerraformWorkspace string
JsonSchemaDir string
Expand Down
4 changes: 2 additions & 2 deletions pkg/spacelift/spacelift_stack_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ func TransformStackConfigToSpaceliftStacks(
}

// Process component metadata and find a base component (if any) and whether the component is real or abstract
componentMetadata, baseComponentName, componentIsAbstract := e.ProcessComponentMetadata(component, componentMap)
componentMetadata, baseComponentName, componentIsAbstract, componentIsEnabled := e.ProcessComponentMetadata(component, componentMap)

if componentIsAbstract {
if componentIsAbstract || !componentIsEnabled {
continue
}

Expand Down
22 changes: 22 additions & 0 deletions website/docs/core-concepts/stacks/define-components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,25 @@ There are two types of components:
<dt>`abstract`</dt>
<dd>An `abstract` component is more like a blueprint. It can’t be deployed on its own. Instead, it’s a base configuration that needs to be extended or inherited by other components. This is similar to an ["abstract base classes"](https://en.wikipedia.org/wiki/Abstract_type) in programming—it defines reusable configurations, but it’s not complete enough to be deployed directly.</dd>
</dl>

### Disabling Components with `metadata.enabled`

The `metadata.enabled` parameter controls whether a component is included in deployment. By default, components are enabled. Setting `metadata.enabled` to `false` skips the component entirely—no workspace is created, and no Terraform commands are executed. Disabling a component does not cause deletion. It just signals that it's no longer managed by Atmos.

:::info Note
This should not be confused with [Cloud Posse's conventions and best practices](/best-practices/terraform/) of having modules and components define a [Terraform input named `enabled`](/best-practices/terraform/#use-feature-flags-list-or-map-inputs-for-optional-functionality). This is a general convention and `vars.enabled` is not a special variable. Atmos does not treat it differently from any other variable.
:::

**Example**:
```yaml
# Disable a component in a specific environment
components:
terraform:
vpc:
metadata:
type: real
enabled: false
vars:
name: primary-vpc
```
Using the `metadata.enabled` flag makes it easy to ensure that only the intended components are active in each environment.

0 comments on commit 3342e8e

Please sign in to comment.