Skip to content

Commit a69e896

Browse files
milldrgithub-actions[bot]
authored andcommitted
(github actions) generated latest snippets
1 parent 799e559 commit a69e896

15 files changed

Lines changed: 507 additions & 61 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
name: account-map-migration
3+
description:
4+
Use when fixing legacy account-map component references. Covers migration from dynamic account-map lookups to static
5+
account_map variable with Atmos Auth.
6+
---
7+
8+
# Account Map Migration
9+
10+
This implementation is migrating away from the `account-map` component to use Atmos Auth for authentication. Instead of
11+
dynamically looking up account IDs via the account-map component, we use a static `account_map` variable defined in
12+
`stacks/orgs/acme/_defaults.yaml`.
13+
14+
## Key Patterns
15+
16+
- **`account_map_enabled: false`** - Disables the legacy account-map component lookup
17+
- **`account_map` variable** - Static map containing `full_account_map` (account names to IDs),
18+
`iam_role_arn_templates`, and account name references
19+
- **Dummy `iam_roles` module** in `providers.tf` - Satisfies legacy module dependencies that expect this output
20+
21+
## When You Encounter Legacy References
22+
23+
You may still see references to `account_map` in remote-state configurations that need to be fixed. When creating new
24+
components or fixing existing ones, use the pattern from recently updated components (e.g., `vpc`, `ecr`) that use the
25+
static `account_map` variable instead of the account-map component.
26+
27+
## Reference Implementation
28+
29+
See `components/terraform/vpc/providers.tf` for the current pattern with:
30+
31+
- `account_map_enabled = false`
32+
- Static `account_map` variable usage
33+
- Dummy `iam_roles` module for compatibility
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
---
2+
name: atmos-authentication
3+
description:
4+
Use when authenticating with AWS via Atmos. Covers ATMOS_PROFILE setup, SSO login, and how Atmos automatically assumes
5+
the correct identity per stack.
6+
---
7+
8+
# Atmos Authentication
9+
10+
Atmos Auth handles AWS authentication automatically based on your profile and the target stack.
11+
12+
## Quick Start
13+
14+
```bash
15+
# Set your profile (required for all atmos commands)
16+
export ATMOS_PROFILE=devops # or: developers, managers
17+
18+
# Run commands - Atmos auto-selects the correct identity per stack
19+
# If not authenticated, this will automatically launch the IDP to sign in
20+
atmos terraform plan vpc -s plat-use2-dev
21+
```
22+
23+
## How It Works
24+
25+
1. **Set your profile**: `export ATMOS_PROFILE=<profile-name>` (or prefix each command)
26+
2. **Run commands**: Atmos automatically assumes the correct identity for each stack based on the stack name. If you're not authenticated or credentials have expired, Atmos will automatically launch the IDP to sign in.
27+
28+
When you run `atmos terraform plan <component> -s <stack>`, Atmos:
29+
30+
1. Renders all stack config, then determines the default identity for the stack
31+
2. If there's a single default identity (e.g., `plat-dev/terraform`), it's selected automatically
32+
3. If multiple identities are marked as default, you'll be prompted to select one
33+
4. Looks up that identity name in your profile to get the actual credentials
34+
5. Assumes the configured Permission Set or IAM role
35+
6. Runs the Terraform command with those credentials
36+
37+
We intentionally set only a single default identity per stack to avoid prompts.
38+
39+
## Identity Configuration
40+
41+
Each stack defines its default identity in its `_defaults.yaml` file:
42+
43+
```yaml
44+
# stacks/orgs/acme/plat/dev/_defaults.yaml
45+
auth:
46+
identities:
47+
plat-dev/terraform:
48+
default: true
49+
```
50+
51+
This is simple YAML configuration - no special Atmos magic. The identity name (`plat-dev/terraform`) is then resolved
52+
by your profile to determine the actual AWS credentials to use.
53+
54+
## Manual Authentication
55+
56+
You don't need to authenticate separately before running Atmos commands - authentication happens automatically when needed.
57+
However, if you want to pre-authenticate a session or refresh expired credentials, use:
58+
59+
```bash
60+
atmos auth login --provider acme-sso # Triggers browser SSO login
61+
```
62+
63+
Once authenticated, credentials are cached and subsequent commands work automatically.
64+
65+
## Profiles
66+
67+
Profiles are defined in `profiles/<profile-name>/atmos.yaml`. Each maps identities to Permission Sets:
68+
69+
| Profile | Core Accounts | Platform Dev/Sandbox | Platform Staging/Prod |
70+
| ------------ | -------------------- | -------------------- | --------------------- |
71+
| `devops` | TerraformApplyAccess | TerraformApplyAccess | TerraformApplyAccess |
72+
| `developers` | TerraformStateAccess | TerraformApplyAccess | TerraformPlanAccess |
73+
| `managers` | TerraformStateAccess | TerraformPlanAccess | TerraformPlanAccess |
74+
75+
**Permission Set capabilities:**
76+
77+
- `TerraformApplyAccess` - Full plan and apply
78+
- `TerraformPlanAccess` - Plan only (no apply)
79+
- `TerraformStateAccess` - Read state only (for cross-account references)
80+
81+
## Identity Naming Convention
82+
83+
Identities follow the pattern: `<tenant>-<stage>/terraform`
84+
85+
Examples:
86+
87+
- `plat-dev/terraform` - Platform dev account
88+
- `core-auto/terraform` - Core automation account
89+
- `plat-prod/terraform` - Platform production account
90+
91+
## Special Cases
92+
93+
**superadmin profile**: IAM user with MFA for breakglass access. Avoid unless SSO is unavailable.
94+
95+
**github profile**: OIDC-based authentication for CI/CD pipelines. Not for interactive use.
96+
97+
## Troubleshooting
98+
99+
If authentication fails:
100+
101+
1. Verify `ATMOS_PROFILE` is set: `echo $ATMOS_PROFILE`
102+
2. Re-authenticate with the provider: `atmos auth login --provider acme-sso`
103+
3. Check you have the required Permission Set in AWS IAM Identity Center
104+
4. Verify the identity exists in `profiles/$ATMOS_PROFILE/atmos.yaml`
105+
106+
## Debugging
107+
108+
Enable debug logging to see detailed output:
109+
110+
```bash
111+
ATMOS_LOGS_LEVEL=debug atmos terraform plan <component> -s <stack>
112+
```
113+
114+
Inspect the rendered configuration (final YAML after all imports and merges):
115+
116+
```bash
117+
atmos describe stacks # Describe all stacks (large output)
118+
atmos describe component <component> -s <stack> # Describe a single component
119+
```
120+
121+
The `describe` commands output the fully-resolved YAML configuration, which is useful for:
122+
123+
- Debugging variable values and inheritance
124+
- Seeing which vars come from catalog vs stack overrides
125+
- Verifying `!terraform.state` references resolve correctly
126+
127+
Reset local Terraform state and cached configuration to start fresh:
128+
129+
```bash
130+
atmos terraform clean <component> -s <stack>
131+
```
132+
133+
This destroys the local `.terraform` directory and any rendered configuration files, useful when:
134+
135+
- Provider versions are out of sync
136+
- Module cache is corrupted
137+
- You want to force re-initialization
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
name: atmos-functions
3+
description:
4+
Use when wiring cross-component dependencies in stack YAML. Covers !terraform.state syntax for passing outputs between
5+
components without remote-state lookups.
6+
---
7+
8+
# Cross-Component Dependencies with Atmos Functions
9+
10+
**Preferred approach: Atmos Functions** - Use Atmos template functions in stack YAML to pass values between components
11+
at plan/apply time. This avoids Terraform remote state lookups entirely.
12+
13+
## `!terraform.state` Syntax
14+
15+
Two-parameter form (current stack):
16+
17+
```yaml
18+
!terraform.state <component> <output>
19+
```
20+
21+
Three-parameter form (specific stack):
22+
23+
```yaml
24+
!terraform.state <component> <stack> <output>
25+
```
26+
27+
## Examples
28+
29+
```yaml
30+
components:
31+
terraform:
32+
my-component:
33+
vars:
34+
# Current stack lookups (component output)
35+
vpc_id: !terraform.state vpc vpc_id
36+
subnet_ids: !terraform.state vpc private_subnet_ids
37+
38+
# Cross-stack lookup (component stack output)
39+
grafana_role_arn: !terraform.state grafana core-use2-auto workspace_iam_role_arn
40+
41+
# Nested output with YQ expression
42+
role_arn: !terraform.state iam-role/my-role plat-use2-dev .role.arn
43+
```
44+
45+
## Best Practices
46+
47+
- **Define lookups in catalog defaults** - Put `!terraform.state` expressions in
48+
`stacks/catalog/<component>/defaults.yaml` rather than in stack files. The function automatically resolves based on
49+
the current stack context.
50+
- **Use current-stack lookups when possible** - Omit the stack parameter to look up components in the same stack, making
51+
configs more portable.
52+
- **Cross-stack lookups for shared resources** - Use the three-parameter form when referencing centralized resources
53+
(e.g., Grafana in core-auto from plat accounts).
54+
55+
## Legacy Approach (Being Phased Out)
56+
57+
Some older components still use Cloud Posse's `remote-state` Terraform module with `remote-state.tf` files. This pattern
58+
is being phased out in favor of Atmos functions. The tfstate backend is in the core-auto account.
59+
60+
When you encounter `remote-state.tf` files, prefer converting them to `!terraform.state` expressions in the catalog.
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
---
2+
name: developing-components
3+
description:
4+
Use when creating new Terraform/OpenTofu components or modifying existing ones. Covers required files, catalog
5+
defaults, stack configuration, and naming conventions.
6+
---
7+
8+
# Developing Components
9+
10+
Components are opinionated Terraform root modules that implement a specific AWS resource with predefined conventions.
11+
12+
## Before Creating a New Component
13+
14+
**Always check for existing components first.** Creating new components adds maintenance burden.
15+
16+
### 1. Check Local Generic Components
17+
18+
Many use cases can be solved by configuring existing generic components via catalog:
19+
20+
- **`iam-role`** - Any IAM role. Create `stacks/catalog/iam-role/my-role.yaml` instead of a new component.
21+
- **`s3-bucket`** - Any S3 bucket with standard configurations.
22+
- **`lambda`** - Lambda functions with common patterns.
23+
24+
### 2. Check Cloud Posse Component Library
25+
26+
Browse https://docs.cloudposse.com/components/library/ for pre-built components. Common ones:
27+
28+
- `eks/cluster`, `eks/alb-controller` - Kubernetes
29+
- `aurora-postgres`, `rds` - Databases
30+
- `elasticache-redis` - Caching
31+
- `ecs`, `ecs-service` - Container workloads
32+
- `cloudwatch-logs`, `sns-topic`, `sqs-queue` - AWS services
33+
34+
To vendor a Cloud Posse component:
35+
36+
```bash
37+
# Add to component.yaml in the component directory, then:
38+
atmos vendor pull -c <component-name>
39+
```
40+
41+
### 3. When to Create a Custom Component
42+
43+
Create a new component when:
44+
45+
- **Tightly coupled resources** - The resources share the same lifecycle and must be created/destroyed together. For
46+
example, an application-specific ECS service with its ALB target group, CloudWatch alarms, and autoscaling policies.
47+
- **Unique to your infrastructure** - The configuration is specific to your organization and wouldn't benefit from Cloud
48+
Posse's generic abstractions.
49+
- **Single account/region deployment** - All resources deploy to one AWS account and region. If resources span accounts
50+
or regions, split into separate components.
51+
52+
**Teralithic components** (all-in-one) are appropriate when:
53+
54+
- Resources are always deployed together and never independently
55+
- Splitting would create artificial boundaries requiring complex cross-component wiring
56+
- The blast radius is acceptable (all resources affected by any change)
57+
58+
**Avoid** custom components when:
59+
60+
- You're wrapping a single AWS resource (use generic components instead)
61+
- The resources have different lifecycles (e.g., database vs. application)
62+
- You might reuse this pattern elsewhere (vendor or create a generic component)
63+
64+
---
65+
66+
## New Component Structure
67+
68+
Every new component requires three parts:
69+
70+
## 1. Root Module (`components/terraform/<component-name>/`)
71+
72+
Required files (copy from an existing component like `ecs`):
73+
74+
- **`context.tf`** - Always identical across all components. Copy from any existing component. Provides Cloud Posse's
75+
null-label context for consistent naming.
76+
- **`providers.tf`** - Standard provider configuration. Copy from an existing component. Includes the
77+
`account_map_enabled` variable and dummy `iam_roles` module for compatibility.
78+
- **`versions.tf`** - OpenTofu/Terraform and provider version constraints
79+
- **`variables.tf`** - Component-specific input variables
80+
- **`main.tf`** - Main resource definitions
81+
- **`outputs.tf`** - Output values
82+
83+
**Note on remote-state.tf**: Avoid creating `remote-state.tf` files for new components. Instead, use Atmos functions
84+
(`!terraform.state`) in stack YAML to pass values from other components. This keeps components simpler and moves
85+
cross-component wiring to the stack configuration layer.
86+
87+
## 2. Catalog Defaults (`stacks/catalog/<component-name>/defaults.yaml`)
88+
89+
Define organization-wide default values for the component, including dependency lookups:
90+
91+
```yaml
92+
components:
93+
terraform:
94+
<component-name>/defaults:
95+
metadata:
96+
component: <component-name>
97+
type: abstract # Makes this a base configuration, not directly deployable
98+
vars:
99+
enabled: true
100+
name: <component-name>
101+
# Static defaults
102+
some_setting: "default-value"
103+
# Dynamic lookups - resolved at plan time based on current stack
104+
vpc_id: !terraform.state vpc vpc_id
105+
subnet_ids: !terraform.state vpc private_subnet_ids
106+
```
107+
108+
## 3. Stack Configuration (`stacks/orgs/acme/<tenant>/<stage>/<region>/<layer>.yaml`)
109+
110+
Import the catalog - often no component block is needed if catalog defaults are complete:
111+
112+
```yaml
113+
import:
114+
- orgs/acme/plat/dev/_defaults
115+
- mixins/region/us-east-1
116+
- catalog/<component-name>/defaults
117+
```
118+
119+
If overrides are needed:
120+
121+
```yaml
122+
import:
123+
- catalog/<component-name>/defaults
124+
125+
components:
126+
terraform:
127+
<component-name>:
128+
vars:
129+
# Account/region-specific overrides only
130+
some_setting: "override-value"
131+
```
132+
133+
## Naming Conventions
134+
135+
- Use descriptive, specific names that indicate the component's purpose
136+
- Prefix with the service/platform when specific (e.g., `ecs-adot-collector` not just `adot-collector`)
137+
- Use slashes for component hierarchies in catalogs (e.g., `iam-role/grafana-cloudwatch-access`,
138+
`grafana/datasource/cloudwatch`)
139+
140+
## Stack File Organization
141+
142+
Stack files in `stacks/orgs/acme/` mirror the AWS account structure:
143+
144+
- `orgs/acme/core/` - Core accounts (root, audit, security, identity, network, dns, auto, artifacts)
145+
- `orgs/acme/plat/` - Platform accounts (sandbox, dev, staging, prod)
146+
147+
Within each stage, organized by region:
148+
149+
- `global-region/` - Global (us-east-1) resources like IAM
150+
- `us-east-2/` - Regional resources
151+
152+
Regional stack files are typically split by layer:
153+
154+
- `foundation.yaml` - VPC, networking, base infrastructure
155+
- `platform.yaml` - Shared platform services (ECS clusters, databases)
156+
- `app.yaml` - Application-specific resources

examples/snippets/.github/workflows/atmos-pro-terraform-apply.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ jobs:
5353

5454
- name: Apply Atmos Component
5555
uses: cloudposse/github-action-atmos-terraform-apply@v4
56+
env:
57+
ATMOS_PROFILE: "github"
5658
with:
5759
# Atmos Pro args
5860
component: ${{ inputs.component }}

0 commit comments

Comments
 (0)