Anchor is an open-source autonomous infrastructure replicator. Provide it with:
- A public Git repository that contains a basic REST API
- AWS Account 1 credentials (source) with admin access
- AWS Account 2 credentials (destination) with admin access
Anchor will:
- Reverse-engineer all resources in Account 1 using
terraformer - Iteratively fix and shape the exported Terraform so it can stand alone
- Deploy the resulting infrastructure to Account 2
- Ship a pull-request to the supplied repo containing a tidy
infra/terraformdirectory plus CI/CD workflows
Input ‑ Environment variables
| Variable | Description | Default |
|---|---|---|
REPO_URL |
HTTPS link to the Git repository | - |
SRC_AWS_ACCESS_KEY_ID / SRC_AWS_SECRET_ACCESS_KEY |
Admin creds for source account | - |
DEST_AWS_ACCESS_KEY_ID / DEST_AWS_SECRET_ACCESS_KEY |
Admin creds for destination account | - |
AWS_REGION |
AWS region to operate in | us-east-1 |
LOG_LEVEL |
Logging verbosity | INFO |
OPENAI_API_KEY |
OpenAI API key for LLM | - |
Output
- A new branch
anchor/infrain the repo infra/terraformdirectory that plans & applies without errors- GitHub Actions workflows:
terraform-plan.yml(runs on pull-request)terraform-apply.yml(runs on merge)
- Discovery — export AWS resources from Account 1 via
terraformer - Agent loop — LLM-driven agent cleans code, fixes validation errors, adds missing pieces, and applies to Account 2 while health-checking the endpoint
- Ship PR — push branch & open PR with Terraform code + CI/CD
repo/
├── infra/
│ └── terraform/
│ ├── main.tf
│ ├── variables.tf
│ └── ...
└── .github/workflows/
├── terraform-plan.yml
└── terraform-apply.yml
# Clone Anchor repo
$ git clone https://github.com/<you>/anchor.git && cd anchor
# Set environment variables
$ export OPENAI_API_KEY=sk-...
$ export SRC_AWS_ACCESS_KEY_ID=AKIA...
$ export SRC_AWS_SECRET_ACCESS_KEY=...
$ export DEST_AWS_ACCESS_KEY_ID=AKIA...
$ export DEST_AWS_SECRET_ACCESS_KEY=...
$ export AWS_REGION=us-east-1 # Optional, defaults to us-east-1
# Create output and logs directories
$ mkdir -p output logs
# Run with Docker Compose
$ docker-compose up --build
# Or run in detached mode
$ docker-compose up -d --build
# View logs
$ docker-compose logs -f
# Stop the container
$ docker-compose downThe Docker Compose setup includes:
- Automatic environment variable passing
- Volume mounts for output and logs
- Python output unbuffering for better logging
- Disabled EC2 metadata service lookups
- Default branch and repository configuration
You can customize the Docker Compose setup by:
- Modifying
docker-compose.ymlto change the target repository - Setting environment variables in
.env.localfile - Adjusting volume mounts for output and logs
- Changing the default branch name
# Clone Anchor dev repo
$ git clone https://github.com/<you>/anchor.git && cd anchor
# Install prerequisites (macOS example)
$ brew install go terraform
# Easiest: pre-built binary
$ brew install terraformer # or use their releases page
# Or build via Go
$ go install github.com/GoogleCloudPlatform/terraformer@latest
$ pip install -r requirements.txt # if Python components are used
# Run MVP
$ REPO_URL=https://github.com/org/repo.git \
SRC_AWS_ACCESS_KEY_ID=... \
SRC_AWS_SECRET_ACCESS_KEY=... \
DEST_AWS_ACCESS_KEY_ID=... \
DEST_AWS_SECRET_ACCESS_KEY=... \
python -m anchor.cmd.anchor $REPO_URLSet LOG_LEVEL=DEBUG to see:
- Full prompt/response exchanges with the LLM
- Terraform command outputs
- Workspace snapshots at each iteration
- Tool execution details
- Directory structure and main.tf content
# Docker
$ docker-compose up # Already has LOG_LEVEL=DEBUG in docker-compose.yml
# Local
$ LOG_LEVEL=DEBUG python -m anchor.cmd.anchor ...
⚠️ Use disposable AWS accounts — Anchor requires full admin privileges for now.
When you create IAM access keys for Anchor/Terraformer, select the purpose "Command Line Interface (CLI)" or "Local code" in the AWS Console. Anchor runs from your local machine, so it does not need a compute-service or third-party designation.
- Pluggable cloud providers (GCP, Azure)
- Least-privilege IAM synthesis
- Drift detection & cost diffing
- UI dashboard & audit log
- GitHub Actions IAM trust relationships for CI/CD deployments
Anchor is released under the Apache License 2.0. See LICENSE for details.
Follow these steps once in Account 1 (the source environment). They create a safe, read-only identity for Anchor/Terraformer to enumerate resources.
-
Create a customer managed policy
- Download or copy
aws-readonly-policy.jsonfrom this repo. - AWS Console → IAM → Policies → Create policy → JSON tab → paste the file → Next → name it
AnchorReadOnly→ create. - CLI equivalent:
aws iam create-policy \ --policy-name AnchorReadOnly \ --policy-document file://aws-readonly-policy.json
- Download or copy
-
Create a role that holds the policy (optional but recommended) Creating a role lets you keep long-lived keys minimal and use short-lived STS tokens.
- IAM → Roles → Create role → Trusted entity: AWS account → This account → Next.
- Attach the AnchorReadOnly policy, continue, and name the role
AnchorReadOnlyRole. - Record the resulting role ARN (
arn:aws:iam::<acct_id>:role/AnchorReadOnlyRole).
-
Create a user that can assume the role (or attach the policy directly)
Fast path — attach the policy directly:
aws iam create-user --user-name anchor_ro aws iam attach-user-policy \ --user-name anchor_ro \ --policy-arn arn:aws:iam::<acct_id>:policy/AnchorReadOnly aws iam create-access-key --user-name anchor_ro
Console: IAM → Users → Add user → "Access key ‑ Programmatic access" → skip console password → Next → Attach existing policies → search & tick AnchorReadOnly → create → download Access key ID / Secret.
Role path — least privilege with STS:
- Create user
anchor_stswith no policies. Generate access keys (CLI/local).
Console path: IAM → Users → Add user → Programmatic access. - Attach an inline policy that lets the user assume the role:
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::<acct_id>:role/AnchorReadOnlyRole" }] } - Anchor/Terraformer can now obtain temporary creds via:
aws sts assume-role \ --role-arn arn:aws:iam::<acct_id>:role/AnchorReadOnlyRole \ --role-session-name anchor
- Create user
-
Select purpose – when the console prompts for a reason choose "Command Line Interface (CLI)" or "Local code". Anchor runs locally.
-
Set environment variables
export SRC_AWS_ACCESS_KEY_ID=AKIA... export SRC_AWS_SECRET_ACCESS_KEY=XXX # If using STS, also export: AWS_SESSION_TOKEN
Repeat a similar process in Account 2 (destination). For the MVP you will eventually attach broader (write) permissions or simply use an AdministratorAccess policy when comfortable.
- Module Name Handling: Trailing spaces in Terraform module and directory names are now automatically stripped, preventing validation errors.
- Error Handling: The system now provides clear error messages for invalid AWS credentials and OpenAI API key issues. See Troubleshooting below.
- Constants and Configuration: All AWS services scanned by Terraformer, as well as other defaults (region, branch, log level, etc.), are now defined in
anchor/constants.pyfor maintainability and single-source-of-truth. - Enhanced Context: Workspace snapshots now include directory structure and main.tf content for better LLM decision making.
- Memory Management: Configurable memory buffer size for maintaining context between agent iterations.
- Invalid AWS Credentials: If you see errors like
InvalidClientTokenIdorInvalidAccessKeyId, check your.env.localor environment variables for correct AWS keys. - OpenAI API Key Error: If you see
Incorrect API key provided, ensure yourOPENAI_API_KEYis valid and not expired. - Module Directory Errors: If you see
Unreadable module directoryor similar, ensure your AWS credentials are valid and that the source account has resources in the selected region. - Memory Issues: If the agent seems to lose context between iterations, check the
DEFAULT_MEMORY_ITEMSsetting inconstants.py.
All default values are defined in anchor/constants.py:
| Setting | Default | Description |
|---|---|---|
DEFAULT_MAX_ITERATIONS |
20 | Maximum number of agent iterations |
DEFAULT_MODEL |
gpt-4 | OpenAI model to use |
DEFAULT_MEMORY_ITEMS |
100 | Number of observations to keep in memory |
DEFAULT_AGENT_SLEEP |
1 | Seconds between agent iterations |
DEFAULT_BRANCH |
anchor/infra | Default branch name |
DEFAULT_AWS_REGION |
us-east-1 | Default AWS region |
DEFAULT_LOG_LEVEL |
INFO | Default logging level |