Skip to content

Commit 11917b7

Browse files
Add CLAUDE.md
1 parent 6ce54c1 commit 11917b7

File tree

1 file changed

+294
-0
lines changed

1 file changed

+294
-0
lines changed

CLAUDE.md

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Development Commands
6+
7+
### Setup
8+
- `poetry install --with=dev --with=main` - Install all dependencies including dev tools
9+
- `poetry shell` - Activate virtual environment for development
10+
11+
### Testing
12+
- `poetry run pytest` - Run unit tests
13+
- `poetry run pytest --verbose --cov=./ --cov-report=xml` - Run unit tests with coverage
14+
- `make test-unit` - Run unit tests in Docker (with coverage)
15+
- `make test-unit-no-cov` - Run unit tests in Docker (no coverage)
16+
- `make test-int` - Run integration tests using bats in Docker
17+
- `make tests` - Run full test suite (unit + integration)
18+
19+
### Code Quality
20+
- `poetry run black .` - Format code with Black (line length: 120)
21+
- `poetry run pylint leverage/` - Run linting
22+
- `poetry run pre-commit install` - Install pre-commit hooks
23+
- `poetry run pre-commit run --all-files` - Run pre-commit checks manually
24+
25+
### Build and Distribution
26+
- `make build` - Build distributables (cleans first)
27+
- `make check` - Check distributables with twine
28+
- `poetry build` - Build package using Poetry
29+
- `make clean` - Clean build artifacts
30+
31+
### Docker
32+
- `make build-image` - Build Docker testing image
33+
- All test commands can run in Docker using the testing image
34+
35+
## Architecture
36+
37+
Leverage CLI is a Python-based command-line tool for managing Binbash Leverage projects. It uses a dockerized approach to encapsulate infrastructure tools.
38+
39+
### Core Structure
40+
- `leverage/leverage.py` - Main CLI entry point using Click framework
41+
- `leverage/modules/` - Command modules (aws, terraform, kubectl, etc.)
42+
- `leverage/container.py` - Docker container management and execution
43+
- `leverage/conf.py` - Configuration loading from build.env files
44+
- `leverage/tasks.py` - Task system for build scripts
45+
- `leverage/path.py` - Path utilities and git repository handling
46+
47+
### Key Components
48+
- **Module System**: Commands are organized in modules under `leverage/modules/`
49+
- **Container Integration**: Heavy use of Docker containers for tool execution
50+
- **Configuration Management**: Hierarchical loading of build.env files
51+
- **Task System**: Decorator-based task definition system for build scripts
52+
- **AWS Integration**: Extensive AWS credential and service management
53+
54+
### Command Structure
55+
The CLI follows this pattern:
56+
```
57+
leverage [global-options] <module> <subcommand> [args]
58+
```
59+
60+
Key modules include:
61+
- `project` - Project initialization and management
62+
- `terraform`/`tf`/`tofu` - Terraform/OpenTofu operations
63+
- `aws` - AWS service interactions
64+
- `credentials` - Credential management
65+
- `kubectl`/`kc` - Kubernetes operations
66+
- `run` - Custom task execution
67+
- `shell` - Interactive shell access
68+
69+
### Version Management
70+
- Supports Python 3.9-3.13
71+
- Version defined in `leverage/__init__.py`
72+
- Minimum tool versions enforced via `MINIMUM_VERSIONS`
73+
- Docker image versioning through `__toolbox_version__`
74+
75+
### Configuration
76+
- Uses `build.env` files for project configuration
77+
- Hierarchical loading from project root to current directory
78+
- Environment-specific overrides supported
79+
80+
## Docker Container Architecture for Terraform/OpenTofu
81+
82+
The CLI uses a containerized approach for all Terraform/OpenTofu operations to ensure consistent tool versions and isolated execution environments.
83+
84+
### Container Classes
85+
86+
#### TFContainer (`leverage/container.py:436-687`)
87+
Primary container for Terraform/OpenTofu execution:
88+
- **Image**: `binbash/leverage-toolbox` with user-specific permissions
89+
- **Binaries**: `/bin/terraform` (when `terraform=True`) or `/bin/tofu` (default)
90+
- **Mount Points**:
91+
- Project root → `/leverage` (guest base path)
92+
- AWS credentials directory → `/tmp/.aws`
93+
- Git config file → `/etc/gitconfig`
94+
- Optional: TF plugin cache directory (maintains symlinks)
95+
- Optional: SSH agent socket → `/ssh-agent`
96+
97+
#### TFautomvContainer (`leverage/container.py:689-717`)
98+
Extends TFContainer for TFAutomv operations:
99+
- **Binary**: `/usr/local/bin/tfautomv`
100+
- Inherits all TFContainer mounts and configuration
101+
102+
### Configuration File Management
103+
104+
#### Environment Variables in Containers:
105+
- `COMMON_CONFIG_FILE``common.tfvars`
106+
- `ACCOUNT_CONFIG_FILE``account.tfvars`
107+
- `BACKEND_CONFIG_FILE``backend.tfvars`
108+
- `AWS_SHARED_CREDENTIALS_FILE``/tmp/.aws/credentials`
109+
- `AWS_CONFIG_FILE``/tmp/.aws/config`
110+
- `SSO_CACHE_DIR``/tmp/.aws/sso/cache`
111+
112+
#### Terraform Variable Files:
113+
The `tf_default_args` property automatically includes:
114+
- All `*.tfvars` files from `common/` directory
115+
- All `*.tfvars` files from account-specific directory
116+
117+
### Docker Execution Points
118+
119+
#### Terraform/OpenTofu Commands (`leverage/modules/tf.py`)
120+
- Container creation for `tofu` and `terraform` commands (lines 38, 56)
121+
- Command execution via `tf.start()` for all operations
122+
- **Supported Commands**: `init`, `plan`, `apply`, `destroy`, `output`, `version`, `shell`, `format`, `validate`, `import`, `refresh-credentials`
123+
124+
#### TFAutomv Commands (`leverage/modules/tfautomv.py`)
125+
- Container creation for `tfautomv` commands (line 24)
126+
- Command execution via `tf.start_in_layer()` (line 36)
127+
128+
### Container Lifecycle
129+
130+
1. **Image Verification**: `ensure_image()` builds local image with user permissions
131+
2. **Container Creation**: `_create_container()` with mounted volumes and environment
132+
3. **Authentication Setup**: SSO token validation or MFA credential handling
133+
4. **Command Execution**: Interactive (`_start()`) or silent (`_exec()`)
134+
5. **Cleanup**: Automatic container stop and removal
135+
136+
### Authentication & Credentials
137+
138+
#### SSO Authentication:
139+
- Token validation before container execution
140+
- Automatic credential refresh via `refresh_layer_credentials()`
141+
- Browser-based authentication flow with user code
142+
143+
#### MFA Authentication:
144+
- Script-based authentication via `aws-mfa-entrypoint.sh`
145+
- Environment variable adjustments for credential paths
146+
147+
#### Credential Mounting:
148+
- Host AWS credentials directory mounted to container
149+
- Separate credential files for different authentication methods
150+
151+
### Backend Configuration Management
152+
153+
#### S3 Backend Handling:
154+
- Automatic `backend.tfvars` parameter injection for `init` commands
155+
- Dynamic state key generation based on layer path structure
156+
- Backend block validation in `config.tf` files
157+
- Support for legacy naming conventions (tf- vs terraform-)
158+
159+
**IMPORTANT**: As of the latest update, Leverage CLI now uses **host-based execution** instead of Docker containers:
160+
161+
## Host-Based Execution Architecture
162+
163+
The CLI has been updated to use host-based execution for improved performance and flexibility while maintaining all functionality.
164+
165+
### Core Runner Classes
166+
167+
#### Runner (`leverage/modules/runner.py`)
168+
Generic command runner base class:
169+
- **Purpose**: Provides common execution functionality for all binary runners
170+
- **Binary Discovery**: Searches for binaries in PATH or accepts absolute paths
171+
- **Environment Management**: Merges instance-level and run-time environment variables
172+
- **Execution Modes**:
173+
- `run()` - Interactive execution (returns exit code) or silent (returns exit code, stdout, stderr)
174+
- `exec()` - Convenience method for non-interactive execution with output capture
175+
- **Working Directory**: Supports execution in any specified directory
176+
- **Validation**: Automatic binary existence validation on initialization
177+
178+
#### TFRunner (`leverage/modules/tfrunner.py`)
179+
Terraform/OpenTofu-specific runner extending Runner:
180+
- **Binaries**: Uses system-installed `terraform` or `tofu` binaries
181+
- **Configuration**: Accepts `terraform=True` for Terraform, defaults to OpenTofu
182+
- **Error Messages**: Provides installation URLs when binaries are not found
183+
- Terraform: https://developer.hashicorp.com/terraform/install
184+
- OpenTofu: https://opentofu.org/docs/intro/install/
185+
- **Environment Variables**: Initialized with AWS credential file paths via `env_vars` parameter
186+
- **No Containers**: Direct binary execution on host system
187+
188+
### Command Flow Architecture
189+
190+
#### Terraform/OpenTofu Command Flow (`leverage/modules/tf.py`)
191+
192+
1. **CLI Entry Points**:
193+
- `@click.group() tofu()` (lines 22-35) - Creates TFRunner with OpenTofu binary
194+
- `@click.group() terraform()` (lines 38-51) - Creates TFRunner with Terraform binary
195+
- Both set up credential environment variables for AWS config and credentials files
196+
197+
2. **Command Decoration**:
198+
- `@pass_runner` - Injects TFRunner instance from Click context
199+
- `@pass_paths` - Injects PathsHandler instance for file/directory management
200+
201+
3. **Supported Commands**:
202+
- `init` - Layer initialization with backend configuration injection
203+
- `plan` - Execution plan generation with auto-discovered tfvars
204+
- `apply` - Infrastructure changes with conditional tfvars injection
205+
- `destroy` - Infrastructure destruction
206+
- `output` - Output variable display
207+
- `version` - Binary version display
208+
- `format` - Code formatting (recursive by default)
209+
- `force-unlock` - State file lock removal
210+
- `validate` - Configuration validation
211+
- `validate-layout` - Leverage convention validation
212+
- `import` - Resource import
213+
- `refresh-credentials` - AWS credential refresh
214+
215+
4. **Multi-Layer Support**:
216+
- `--layers` option for operating on multiple layers from account directory
217+
- Layer validation and backend key management via `invoke_for_all_commands()`
218+
- Automatic backend key generation based on layer path structure
219+
220+
### Authentication Management
221+
222+
#### SSO Authentication (`leverage/modules/auth.py`)
223+
224+
**Token Validation** (`check_sso_token()` - lines 98-127):
225+
- Validates SSO token existence in cache directory
226+
- Checks token expiration against current time
227+
- Provides clear error messages for missing or expired tokens
228+
- Token file location: `~/.aws/sso/cache/<sso_role>`
229+
230+
**Credential Refresh** (`refresh_layer_credentials()` - lines 130-204):
231+
- Parses Terraform files to discover required AWS profiles
232+
- Uses boto3 SSO client to retrieve temporary credentials
233+
- Updates AWS config file with credential expiration timestamps
234+
- Writes temporary credentials to AWS credentials file
235+
- Implements 30-minute early renewal to avoid mid-operation expiration
236+
- Supports cross-account profile resolution
237+
238+
**Profile Discovery** (`get_profiles()` - lines 68-88):
239+
- Scans `config.tf`, `locals.tf`, `runtime.tf` for profile references
240+
- Extracts profile variables from Terraform configurations
241+
- Reads backend profile from `backend.tfvars`
242+
243+
### Configuration Management
244+
245+
#### Automatic tfvars Discovery (`tf_default_args()` - lines 133-154):
246+
- Discovers all `*.tfvars` files in `common/` directory
247+
- Discovers all `*.tfvars` files in account-specific directory
248+
- Returns as `-var-file=<path>` arguments for Terraform/OpenTofu
249+
- Used automatically in plan, destroy, validate, and conditionally in apply
250+
251+
#### Backend Configuration:
252+
- Backend config file path injected during `init` command (line 336)
253+
- Automatic backend key generation in `invoke_for_all_commands()` (lines 291-294)
254+
- Backend key validation in `validate_layout()` (lines 538-550)
255+
- Support for legacy naming conventions (tf- vs terraform-, base- vs tools-)
256+
257+
### Execution Flow
258+
259+
**Standard Command Execution**:
260+
1. User runs `leverage tofu|terraform <command> [args]`
261+
2. Click creates TFRunner instance with credential environment variables
262+
3. Command function decorated with `@pass_runner` and `@pass_paths`
263+
4. Authentication check via `check_sso_token(paths)`
264+
5. Credential refresh via `refresh_layer_credentials(paths)`
265+
6. TFRunner.run() executes binary with:
266+
- Merged environment variables (instance + runtime)
267+
- Specified working directory
268+
- Auto-discovered tfvars (for applicable commands)
269+
- User-provided arguments
270+
7. Exit code returned to CLI
271+
272+
**Multi-Layer Execution**:
273+
1. User runs command with `--layers layer1,layer2` from account directory
274+
2. `invoke_for_all_commands()` validates all layers
275+
3. Backend keys generated/validated for each layer
276+
4. Command executed sequentially for each layer with layer-specific working directory
277+
278+
### Benefits of Host-Based Execution
279+
280+
- **Performance**: No container startup overhead or image building
281+
- **Flexibility**: Use any installed tool version (including custom builds)
282+
- **IDE Integration**: Better debugging and tooling support
283+
- **Simplicity**: Direct binary execution with standard environment variables
284+
- **Plugin Compatibility**: Native Terraform/OpenTofu plugin caching
285+
- **Development Speed**: Faster iteration during development
286+
287+
### Host Requirements
288+
289+
For full functionality, ensure the following binaries are installed and available in PATH:
290+
- `terraform` or `tofu` (for Terraform/OpenTofu operations)
291+
- `aws` CLI (for SSO authentication via boto3)
292+
293+
Optional binaries:
294+
- `tfautomv` (for TFAutomv operations)

0 commit comments

Comments
 (0)