Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/quick-start-advanced/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ARG GEODESIC_OS=debian
# https://atmos.tools/
# https://github.com/cloudposse/atmos
# https://github.com/cloudposse/atmos/releases
ARG ATMOS_VERSION=1.172.0
ARG ATMOS_VERSION=1.173.0

# Terraform: https://github.com/hashicorp/terraform/releases
ARG TF_VERSION=1.5.7
Expand Down
12 changes: 8 additions & 4 deletions internal/exec/describe_component.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
u "github.com/cloudposse/atmos/pkg/utils"
)

// ExecuteDescribeComponentCmd executes `describe component` command
// ExecuteDescribeComponentCmd executes `describe component` command.
func ExecuteDescribeComponentCmd(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return errors.New("invalid arguments. The command requires one argument `component`")
Expand Down Expand Up @@ -106,26 +106,30 @@
var configAndStacksInfo schema.ConfigAndStacksInfo
configAndStacksInfo.ComponentFromArg = component
configAndStacksInfo.Stack = stack
configAndStacksInfo.ComponentSection = make(map[string]any)

atmosConfig, err := cfg.InitCliConfig(configAndStacksInfo, true)
if err != nil {
return nil, err
}

configAndStacksInfo.ComponentType = "terraform"
configAndStacksInfo.ComponentType = cfg.TerraformComponentType
configAndStacksInfo, err = ProcessStacks(atmosConfig, configAndStacksInfo, true, processTemplates, processYamlFunctions, skip)
configAndStacksInfo.ComponentSection[cfg.ComponentTypeSectionName] = cfg.TerraformComponentType
if err != nil {
configAndStacksInfo.ComponentType = "helmfile"
configAndStacksInfo.ComponentType = cfg.HelmfileComponentType
configAndStacksInfo, err = ProcessStacks(atmosConfig, configAndStacksInfo, true, processTemplates, processYamlFunctions, skip)
configAndStacksInfo.ComponentSection[cfg.ComponentTypeSectionName] = cfg.HelmfileComponentType
if err != nil {
configAndStacksInfo.ComponentSection[cfg.ComponentTypeSectionName] = ""

Check warning on line 124 in internal/exec/describe_component.go

View check run for this annotation

Codecov / codecov/patch

internal/exec/describe_component.go#L124

Added line #L124 was not covered by tests
return nil, err
}
}

return configAndStacksInfo.ComponentSection, nil
}

// FilterAbstractComponents This function removes abstract components and returns the list of components
// FilterAbstractComponents This function removes abstract components and returns the list of components.
func FilterAbstractComponents(componentsMap map[string]any) []string {
if componentsMap == nil {
return []string{}
Expand Down
2 changes: 1 addition & 1 deletion internal/exec/template_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type AtmosFuncs struct {
}

func (f AtmosFuncs) Component(component string, stack string) (any, error) {
return componentFunc(f.atmosConfig, f.configAndStacksInfo, component, stack)
return componentFunc(f.atmosConfig, component, stack)
}

func (f AtmosFuncs) GomplateDatasource(alias string, args ...string) (any, error) {
Expand Down
15 changes: 8 additions & 7 deletions internal/exec/template_funcs_component.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

func componentFunc(
atmosConfig *schema.AtmosConfiguration,
configAndStacksInfo *schema.ConfigAndStacksInfo,
component string,
stack string,
) (any, error) {
Expand All @@ -30,12 +29,12 @@
if found && existingSections != nil {
log.Debug("Cache hit for template function", "function", functionName)

if outputsSection, ok := existingSections.(map[string]any)["outputs"]; ok {
if outputsSection, ok := existingSections.(map[string]any)[cfg.OutputsSectionName]; ok {
y, err2 := u.ConvertToYAML(outputsSection)
if err2 != nil {
log.Error(err2)
} else {
log.Debug("Result of the template function", "function", functionName, "outputs", y)
log.Debug("'outputs' of the template function", "function", functionName, cfg.OutputsSectionName, y)
}
}

Expand All @@ -49,7 +48,8 @@

// Process Terraform remote state
var terraformOutputs map[string]any
if configAndStacksInfo.ComponentType == cfg.TerraformComponentType {
componentType := sections[cfg.ComponentTypeSectionName]
if componentType == cfg.TerraformComponentType {
// Check if the component in the stack is configured with the 'static' remote state backend,
// in which case get the `output` from the static remote state instead of executing `terraform output`
remoteStateBackendStaticTypeOutputs, err := GetComponentRemoteStateBackendStaticType(sections)
Expand All @@ -69,7 +69,7 @@
}

outputs := map[string]any{
"outputs": terraformOutputs,
cfg.OutputsSectionName: terraformOutputs,
}

sections = lo.Assign(sections, outputs)
Expand All @@ -80,12 +80,13 @@

log.Debug("Executed template function", "function", functionName)

if configAndStacksInfo.ComponentType == cfg.TerraformComponentType {
// Print the `outputs` section of the Terraform component
if componentType == cfg.TerraformComponentType {
y, err2 := u.ConvertToYAML(terraformOutputs)
if err2 != nil {
log.Error(err2)
} else {
log.Debug("Result of the template function", "function", functionName, "outputs", y)
log.Debug("'outputs' of the template function", "function", functionName, cfg.OutputsSectionName, y)
}
}

Expand Down
26 changes: 25 additions & 1 deletion internal/exec/template_funcs_component_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ func TestComponentFunc(t *testing.T) {
atmosConfig, err := cfg.InitCliConfig(info, true)
assert.NoError(t, err)

d, err := componentFunc(&atmosConfig, &info, "component-2", "nonprod")
// Test terraform component `component-2`
d, err := componentFunc(&atmosConfig, "component-2", "nonprod")
assert.NoError(t, err)

y, err := u.ConvertToYAML(d)
Expand All @@ -71,4 +72,27 @@ func TestComponentFunc(t *testing.T) {
assert.Contains(t, y, "foo: component-1-a")
assert.Contains(t, y, "bar: component-1-b")
assert.Contains(t, y, "baz: component-1-b--component-1-c")

// Test helmfile component `component-3`
d, err = componentFunc(&atmosConfig, "component-3", "nonprod")
assert.NoError(t, err)

y, err = u.ConvertToYAML(d)
assert.NoError(t, err)

assert.Contains(t, y, "foo: component-1-a")
assert.Contains(t, y, "bar: component-1-b")
assert.Contains(t, y, "baz: component-1-b")

// Test helmfile component `component-4`
d, err = componentFunc(&atmosConfig, "component-4", "nonprod")
assert.NoError(t, err)

y, err = u.ConvertToYAML(d)
assert.NoError(t, err)

assert.Contains(t, y, "foo: component-1-a")
assert.Contains(t, y, "bar: component-1-b")
// Helmfile components don't have `outputs` (terraform output) - this should result in `<no value>`
assert.Contains(t, y, "baz: <no value>")
}
2 changes: 2 additions & 0 deletions pkg/config/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ const (
GithubSectionName = "github"
TerraformCliVarsSectionName = "tf_cli_vars"
CliArgsSectionName = "cli_args"
ComponentTypeSectionName = "component_type"
OutputsSectionName = "outputs"

LogsLevelFlag = "--logs-level"
LogsFileFlag = "--logs-file"
Expand Down
2 changes: 2 additions & 0 deletions tests/fixtures/scenarios/stack-templates-3/atmos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ components:
deploy_run_init: true
init_run_reconfigure: true
auto_generate_backend_file: false
helmfile:
base_path: "components/helmfile"

stacks:
base_path: "stacks"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,17 @@ components:
foo: '{{ (atmos.Component "component-1" .stack).outputs.foo }}'
bar: '{{ (atmos.Component "component-1" .stack).outputs.bar }}'
baz: '{{ (atmos.Component "component-1" .stack).outputs.bar }}--{{ (atmos.Component "component-1" .stack).outputs.baz }}'

helmfile:
component-3:
vars:
foo: '{{ (atmos.Component "component-1" .stack).vars.foo }}'
bar: '{{ (atmos.Component "component-1" .stack).settings.config.b }}'
baz: '{{ (atmos.Component "component-1" .stack).vars.bar }}'

component-4:
vars:
foo: '{{ (atmos.Component "component-1" .stack).outputs.foo }}'
bar: '{{ (atmos.Component "component-3" .stack).vars.bar }}'
# Helmfile components don't have `outputs` (terraform output) - this should result in `<no value>`
baz: '{{ (atmos.Component "component-3" .stack).outputs.baz }}'
2 changes: 2 additions & 0 deletions website/docs/cli/commands/describe/describe-component.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ The output contains the following sections:

- `component` - the Terraform/OpenTofu component for which the Atmos component provides configuration

- `component_type` - the type of the component (`terraform` or `helmfile`)

- `component_info` - a block describing the Terraform or Helmfile components that the Atmos component manages. The `component_info` block has the
following sections:
- `component_path` - the filesystem path to the Terraform/OpenTofu or Helmfile component
Expand Down
2 changes: 1 addition & 1 deletion website/docs/integrations/atlantis.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ on:
branches: [ main ]

env:
ATMOS_VERSION: 1.172.0
ATMOS_VERSION: 1.173.0
ATMOS_CLI_CONFIG_PATH: ./

jobs:
Expand Down
Loading