terraform-provider-anthropic-claude-managed-agents
⚠️ Not for production use — learning & prototyping only
This is an experimental, community-built project intended solely for learning, experimentation, and prototyping. It is NOT intended, tested, or supported for production use.
It is provided "AS IS", without warranty of any kind, express or implied. You use it entirely at your own risk. The author(s) and contributors accept no liability for any damage, data loss, downtime, cost, security incident, or other harm arising from its use. The "1.0.0" version number denotes API/schema stability under SemVer — it is not a statement of production-readiness or fitness for any purpose.
See the LICENSE (MPL 2.0, sections 6 & 7) for the full warranty disclaimer and limitation of liability.
A Terraform / OpenTofu provider for Anthropic Claude Managed Agents — declaratively manage agents (with tools, MCP servers, skills, and multiagent coordination), environments, vaults, custom skills, and memory stores from Terraform configurations.
Unofficial. This is a community project. It is not maintained by, endorsed by, or affiliated with Anthropic. Upstream API: Claude Managed Agents docs.
Anthropic Terraform provider — what this covers
A community-maintained Terraform / OpenTofu provider for the Anthropic Claude Managed Agents API. Resources and data sources:
- Agents — with nested HCL for
tools(agent_toolset_20260401,mcp_toolset,custom),mcp_servers,skills, andmultiagentcoordination - Environments — cloud and dedicated, with
apt/npm/pippackage install - Vaults and vault credentials — secrets handled via Terraform 1.11 write-only attributes (not persisted to state)
- Custom skills — multipart upload, content-hash drift detection, immutable versions
- Memory stores — persistent agent memory, attached at session time
The Managed Agents API is distinct from the standard Anthropic Messages API. This provider does not manage the Messages API or generic /v1/messages calls.
What this provider does
Claude Managed Agents is Anthropic's hosted runtime for long-running, tool-using agents. The platform exposes a REST API for creating and configuring those agents and their supporting resources (environments, vaults, memory stores).
This provider lets you put that configuration under Terraform so you can:
- Review changes in pull requests instead of via ad-hoc API calls.
- Version-control your agent definitions alongside the rest of your infra.
- Promote agents across workspaces with the same workflow you use for everything else.
Status / scope
For per-release change history (including deprecations and breaking changes), see CHANGELOG.md.
Quickstart
terraform {
required_version = ">= 1.11"
required_providers {
claude-managed-agents = {
source = "modus-agendi/anthropic-claude-managed-agents"
version = "~> 1.0"
}
}
}
Don't rename
claude-managed-agentsto something shorter. That string is the prefix on every resource type (claude-managed-agents_agent,claude-managed-agents_vault, …). If you alias it (e.g. toanthropic), every resource block must add an explicitprovider = claude-managed-agentsargument — noisier than keeping the literal name.
provider "claude-managed-agents" {
# api_key defaults to the ANTHROPIC_API_KEY environment variable.
}
resource "claude-managed-agents_agent" "coding_assistant" {
name = "Coding Assistant"
model = "claude-opus-4-7"
system = "You are a helpful coding agent."
description = "Pairs on Go and Terraform tasks."
metadata = {
team = "platform"
}
}
output "agent_id" {
value = claude-managed-agents_agent.coding_assistant.id
}
export ANTHROPIC_API_KEY="sk-ant-..."
terraform init
terraform apply
Authentication
The provider reads credentials from, in order of precedence:
- The
api_keyargument on theproviderblock. - The
ANTHROPIC_API_KEYenvironment variable.
api_key is marked Sensitive in the schema, so it is redacted from plan/apply output. Provider configuration is not written to Terraform state, so the key never lands in the state file regardless of how you supply it. The risk of hardcoding it in the provider block is that it then lives in your configuration files (and version control), and can surface in TF_LOG debug or crash logs — so prefer the ANTHROPIC_API_KEY environment variable in production and CI.
claude-managed-agents_vault_credential uses Terraform 1.11 write-only attributes for its secret fields (token, access_token, refresh_token, client_secret): these values are never persisted to state. Rotate by incrementing the matching *_wo_version integer.
provider "claude-managed-agents" {
api_key = var.anthropic_api_key # only set this if env var is impractical
base_url = "https://api.anthropic.com"
max_retries = 3
}
Resources and data sources
Guides
- Deployments: scheduling and running agents — scheduled vs manual runs, the
desired_status/statussplit, mounting resources, reading run history, and the caveats to know before relying on deployments. - State security and remote backends — what is and isn't in state, and encrypted/locked backends (S3+KMS, GCS, Terraform Cloud).
- Secrets management and rotation — write-only attributes and the rotation ceremony for vault credentials and deployment github tokens.
- Import and state recovery —
terraform importper resource, the composite vault-credential id, and re-supplying write-only fields after import. - Drift detection and remediation —
plan -refresh-only -detailed-exitcode, the provider's expected-drift patterns, andignore_changesguidance. - Upgrading and migration — version constraints, the registry slug/namespace history, and a safe upgrade procedure.
Lifecycle gotchas
- Agent destroy maps to archive. The upstream API has no
DELETE /v1/agents/{id}endpoint.terraform destroyissuesPOST /v1/agents/{id}/archive. Archived agents are read-only and cannot be unarchived. versionis server-managed. The provider passes it along on update for optimistic concurrency. If you see version conflicts in plans, refresh the state withterraform apply -refresh-only.metadatais key-level merged. The upstream API uses merge semantics: removing a key from your HCL causes the provider to send JSON null for that key, which the API treats as a delete. Applies to bothclaude-managed-agents_agent.metadataandclaude-managed-agents_vault.metadata.- Environments are immutable. The API has no environment update endpoint, so every attribute on
claude-managed-agents_environmentisForceNew. Any change triggers replacement. Destroy issuesDELETE /v1/environments/{id}and falls back to archive if the API returns 409 (active session reference). - Vault and memory_store destroy archives by default. Set
delete_on_destroy = trueon the resource to hard-delete instead. Vault archive cascades through credentials; memory_store hard-delete cascades through memories and memory versions. - Deployment pause/resume is driven by
desired_status, notstatus. Setdesired_statustoactiveorpaused; the provider reconciles via the pause/resume endpoints.desired_statusis your intent and is deliberately decoupled from the observedstatus: when the API auto-pauses a deployment on error,statusbecomespausedwhiledesired_statusstaysactive, and Terraform will not fight it (no resume flap). Inspectpaused_reason, fix the cause, then re-apply to resume. Editinginitial_eventsforces replacement (the API does not patch events in place). Destroy archives the deployment (one-way; no DELETE endpoint). The githubauthorization_tokeninresourcesis write-only — bumpauthorization_token_wo_versionto re-send it on rotation. - Vault-credential secrets are write-only. Secret fields are never read back from the API. Rotate by incrementing the corresponding
token_wo_version,access_token_wo_version,refresh_token_wo_version, orclient_secret_wo_versioninteger.auth.type,auth.mcp_server_url,auth.refresh.token_endpoint, andauth.refresh.client_idare immutable (RequiresReplace).
OpenTofu compatibility
The provider builds on protocol v6 and uses the Plugin Framework. It requires Terraform 1.11+ or OpenTofu 1.8+ — both engines support TF 1.11 write-only attributes, which the provider uses to handle secrets in claude-managed-agents_vault_credential.
Local development
Pre-requisites: Go 1.23+, Terraform 1.11+ (or OpenTofu 1.8+), golangci-lint.
git clone https://github.com/modus-agendi/terraform-provider-anthropic-claude-managed-agents
cd terraform-provider-anthropic-claude-managed-agents
go mod download
make test # unit tests
make testacc # acceptance tests, httptest fixture (free)
make testacc-live # acceptance tests against api.anthropic.com (requires ANTHROPIC_API_KEY)
# Behavioral scenarios (L5) — opens real sessions and grades them via an
# LLM-as-judge call. Bills real inference tokens; see
# internal/scenarios/README.md for cost notes.
TF_ACC_SCENARIOS=1 go test ./internal/scenarios/... -count=1 -timeout 10m -v
make lint
make docs # regenerate docs/ via tfplugindocs
make coverage-html # full coverage profile + HTML report
make coverage-split # mirrors CI: split unit + acceptance profiles
make pr # full local PR-check pipeline (mirrors CI)
make install # build + install into ~/.terraform.d/plugins/...
Once installed locally, pin the dev version in your test main.tf:
terraform {
required_providers {
claude-managed-agents = {
source = "modus-agendi/anthropic-claude-managed-agents"
version = "0.0.1-dev"
}
}
}
Gotcha —
make installshadows registry releases.make installcopies the binary into~/.terraform.d/plugins/registry.terraform.io/modus-agendi/anthropic-claude-managed-agents/, which Terraform treats as the authoritative version source. Any external config that pins a different version (e.g.version = "~> 0.2") will failterraform initwith "no available releases match the given constraints". Runrm -rf ~/.terraform.d/plugins/registry.terraform.io/modus-agendito drop back to registry-pulled releases.
Testing & quality
Testing runs in five layers so that cheap, deterministic checks gate every PR while the expensive, real-API checks run on a schedule. Full details (and the exact CI triggers) are in CONTRIBUTING.md.
L5 is the unusual one and worth calling out for transparency. It provisions
resources via Terraform, opens a real session, captures the full event
trajectory, asserts deterministic properties on it, then has a separate judge
model grade the final answer against a rubric. It bills real inference
tokens — roughly $0.05–$0.20 per scenario (the current catalog of six runs
at about $0.68 total). It is a hard gate on releases: a scenario FAIL
blocks goreleaser unless explicitly skipped. See
internal/scenarios/README.md for the scenario
format, the deployment/lifecycle scenario kinds, and a note on the undocumented
manual-run endpoint the harness relies on.
Coverage target is 85% (codecov gates at 70% project / 75% patch). Coverage
is treated as a gap-finder, not a goal — see CLAUDE.md.
Versioning
The provider follows Semantic Versioning. As of v1.0.0 the resource and data-source schema is stable: breaking changes happen only in a new major version (2.0.0), never in a minor or patch release. Pin version = "~> 1.0" to receive non-breaking 1.x updates automatically. Breaking changes, when a 2.0 eventually happens, will be called out in CHANGELOG.md with a migration note.
A breaking change is one of:
- Removing or renaming a schema attribute.
- Changing the type of a schema attribute.
- Changing the required/optional/computed status of an attribute in a way that affects existing configurations.
- Changing the default value of an attribute.
Roadmap
Under consideration for the next minor: an ephemeral resource for vault-credential validation, optional skill version retention attributes, and broadening the L5 behavioral scenario catalog. Sessions, dreams, memory contents/versions, and webhook endpoints are not currently on the roadmap. Open an issue if you'd like to discuss.
Contributing
See CONTRIBUTING.md.
Community
- SECURITY.md — how to report vulnerabilities privately.
- CODE_OF_CONDUCT.md — expected conduct for contributors and maintainers.
- Issue templates — structured bug reports and feature requests.
- Pull request template — checklist for opening a PR.
- CODEOWNERS — review routing.
License
Distributed under the Mozilla Public License 2.0. See LICENSE for the full text (add the file via the GitHub UI's license picker if it's missing from a fresh checkout).
Disclaimer
This is a community-maintained project. It is not affiliated with Anthropic. "Claude" is a trademark of Anthropic; usage here is descriptive, identifying the API this provider integrates with.