Skip to main content

Tarmac

PyPI version Python versions License

Tarmac sets up and maintains a multi-account AWS Organization from three YAML files: OUs, accounts, guardrail SCPs, an organization CloudTrail, security services and IAM Identity Center. Change the YAML, run tarmac deploy, and tarmac makes AWS match. Every run is safe to repeat.

Install

uv tool install tarmac-cli     # or: pip install tarmac-cli
tarmac --help

Quick start: a brand-new AWS account

Tarmac runs in the organization's management account. It can't run as the root user, because root can't reach member accounts, so you first create an IAM Identity Center login for yourself. AWS CloudShell is the easiest place to do this.

  1. Sign in as root, turn on MFA, and add a payment method.
  2. In the console, enable IAM Identity Center. Pick its Region carefully: moving it later means starting over. This also creates the organization.
  3. In CloudShell:
    pip install tarmac-cli
    tarmac init          # writes config/organization.yaml, accounts.yaml, identity.yaml
    
    Edit the files. Put yourself in admin_user in identity.yaml, and give every account in accounts.yaml a real, unique email (plus addresses such as aws+prod@example.com work if your mail provider supports them).
  4. Still in CloudShell, as root:
    tarmac bootstrap
    
    This creates your Identity Center user, gives it two permission sets on the management account (TarmacDeployment for tarmac, ManagementAdministrator for the console), and adds a tarmac profile to ~/.aws/config. It ends by printing the steps for your first sign-in.
  5. Follow those steps to sign in, then deploy:
    export AWS_PROFILE=tarmac
    tarmac preflight           # checks the account is ready
    tarmac deploy --dry-run    # shows what would change, changes nothing
    tarmac deploy
    

CloudShell tips: always use aws sso login --use-device-code, because the normal login can't call back to your browser. Re-run export AWS_PROFILE=tarmac after CloudShell restarts; without it, tarmac sees root and stops.

Using an existing organization

tarmac import reads your organization and writes matching config files. It changes nothing in AWS.

tarmac import --config-dir my-org
cd my-org
tarmac status --detail
tarmac deploy --dry-run

Read what it reports, and check the dry run before the first real deploy. Keep in mind:

  • Declare existing accounts with their real emails. If a name matches but the email doesn't, tarmac stops rather than guess.
  • Accounts you don't declare are left alone, except ones tarmac created earlier and you have since removed from accounts.yaml. Those are moved to the Suspended OU (quarantine_removed_accounts: false turns this off).
  • Never change organization.name after the first deploy. Every stack is named after it.
  • An existing organization trail isn't replaced. Tarmac adds its own; delete the old one once the new one is delivering logs.
  • Set delete_default_vpc: false for accounts that already run workloads.

What it deploys

tarmac deploy runs six phases in order. --phase N runs one, and --phase 4 --account NAME updates a single account.

Phase What it does
1 Organization settings, contacts, trusted services, root access management, cost tags
2 OUs and service control policies
3 Log archive buckets and the organization CloudTrail
4 Member accounts, their tags, budgets and default VPC cleanup
5 Terraform state backend, audit account, AWS Config, GuardDuty, Security Hub, root user alert
6 Identity Center permission sets, users, groups and assignments

Following AWS's guidance, the management account holds only what has to live there:

  • Management account: Organizations, SCPs, Identity Center, the trail's stack, and the AWS Config StackSet.
  • Audit account: delegated administrator for CloudTrail, AWS Config, GuardDuty, Security Hub and IAM root access management.
  • Log archive account: the CloudTrail and Config log buckets.

tarmac init starts you with the OUs AWS recommends: Security, Infrastructure, Workloads (Prod and Test), Deployments, Sandbox, Policy Staging and Suspended.

Everything comes from the CloudFormation templates and SCPs bundled with tarmac. tarmac init --with-templates copies them into your project; tarmac then uses your copies, so you can review and version them.

Tarmac itself runs with the least-privilege policy in tarmac-deployment.json. After upgrading tarmac, run tarmac bootstrap again to update it; tarmac preflight warns when it's out of date.

Commands

Command What it does
tarmac init Write starter config files
tarmac validate Check the config files, without AWS
tarmac bootstrap Once, as root: create your Identity Center login and the tarmac profile
tarmac preflight Check the management account is ready
tarmac deploy Apply the config (--dry-run to preview, --phase N for one phase)
tarmac status Compare AWS with the config (--detail lists every difference)
tarmac import Write config files from an existing organization
tarmac destroy Remove what tarmac deployed (see Tearing down)
tarmac info Show who you're signed in as (--strict fails if tarmac can't run)
tarmac account list List accounts in the organization
tarmac account suspend NAME Move an account to the Suspended OU (--close closes it)
tarmac logs FILE Summarize runs recorded with --log-file
tarmac inventory Show what tarmac has recorded creating

Options

All of these go in organization.yaml. Options with a real cost are off until you turn them on.

Log retention and locking. CloudTrail logs are kept forever unless you set a retention. Object Lock stops anyone deleting logs during the lock period. It's recommended, but S3 can never turn it off again, so tarmac asks you to decide (object_lock: null to say no).

cloudtrail:
  retention_days: 365
  object_lock: {mode: GOVERNANCE, retention_days: 365}   # COMPLIANCE can't be bypassed, even by root
  enable_kms: true   # encrypt logs with a KMS key (~$1/month); CIS and Security Hub ask for it

Security services.

security_services:
  delegated_account: audit
  guardduty:
    enabled: true
    features: {s3_data_events: true}   # optional paid protections stay off unless listed
  securityhub:
    enabled: true
    standards: [aws-foundational-security-best-practices]   # applied to every account
  config_recorder:
    enabled: true                    # AWS Config in every account; Security Hub needs it
    recording_frequency: CONTINUOUS  # usually cheaper than DAILY
  root_alert:
    enabled: true                    # emails contacts.security.email when root is used (on by default)

Terraform state. Phase 5 creates a state bucket in the deployment account. Its name is in the <org>-terraform-backend stack's BucketName output. Locking uses S3 (use_lockfile = true, Terraform 1.10+); set terraform_backend.enable_dynamodb: true if you need a DynamoDB lock table.

Example SCPs. examples/policies/scp has two optional policies, one restricting Regions and one stopping member accounts turning off GuardDuty or Security Hub. Keep their OrganizationAccountAccessRole exemption (tarmac works through that role), and test them on one OU before attaching them to the root.

Tearing down

tarmac destroy --dry-run
tarmac destroy

destroy removes the stacks, buckets, budgets, SCPs and permission sets tarmac deployed, so deploy can rebuild them. It keeps the organization, OUs and member accounts. It also refuses to touch anything tagged as production unless you pass --force, and skips anything tarmac didn't create.

  • --preserve-backend keeps the Terraform state.
  • --disable-security-services also turns off GuardDuty, Security Hub and Config. This deletes their findings.
  • --everything also removes the OUs, Identity Center users and groups, and organization settings tarmac created, plus the tarmac bootstrap permission sets (except the one you're signed in with). It never closes accounts.

Logging

Add -v to see each change as it happens, or --log-file run.jsonl (or set TARMAC_LOG_FILE) to record a run. Both go before the command. Inspect the results with tarmac logs:

tarmac -v --log-file run.jsonl deploy
tarmac logs run.jsonl --run latest            # what the last run did, and what failed
tarmac logs run.jsonl --outcome failed

Development

uv sync --locked
uv run pytest
uv run ruff check . && uv run ruff format --check . && uv run basedpyright
uv run cfn-lint src/tarmac/templates/cloudformation/*.yaml
uv run tarmac validate --config-dir examples/config

License

Apache License 2.0

Metadata

Release files for tarmac-cli 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tarmac-cli 0.3.1
File Size Uploaded Provenance
tarmac_cli-0.3.1.tar.gz 300.3 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for tarmac-cli 0.3.1
File Interpreter ABI Platform
tarmac_cli-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 514.9 kB

Release files / tarmac_cli-0.3.1.tar.gz

Download URL tarmac_cli-0.3.1.tar.gz
Size 300.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6e73ebc3f3c9defbe642c1909d694265ff67d0a175ea69b9a13a5782b07c0ca4
BLAKE2b-256 checksum
How to use checksums
ad7765f48753713f7513ac3ff98a12f4621810bbb5b13467f69fbc65a41b5c40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / tarmac_cli-0.3.1-py3-none-any.whl

Download URL tarmac_cli-0.3.1-py3-none-any.whl
Size 214.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
82b9fd6dfae70ce2d66b53a9ef2771f88c147db0a47c365635325f3c13c3d7b1
BLAKE2b-256 checksum
How to use checksums
62ce599ce64a846fb3da0c3df92e04edda0e19712b7816fbb34d73a17fbb23c4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Security for tarmac-cli 0.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for tarmac_cli-0.3.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page