How Do You Manage ECS Fargate Across Multiple AWS Accounts?
You already split prod, non-prod, and maybe per-region or per-customer into separate AWS accounts — for isolation, blast radius, and clean billing. Now you're paying the operating tax: logging in and out all day, re-deploying the same image to five accounts, and no single screen that shows what's running where. This is the operating model for an ECS fleet that already lives across accounts — plus the costs that never make the spreadsheet, and the case where splitting accounts isn't worth it.
- ·A multi-account AWS Org gives you isolation; it takes away a single pane of glass. AWS has no "Lens for ECS" — you stitch one together from IAM, the CLI, and pipelines.
- ·Five operating surfaces to solve: cross-account visibility, IAM access, image distribution (ECR), networking, and deploy.
- ·Going multi-account has a real bill: Transit Gateway alone is ~$36/mo per VPC attachment plus $0.02/GB, before any data transfer.
- ·The aws:PrincipalOrgID ECR shortcut opens your image repo to every account in the Org — convenient, and a security review waiting to happen.
- ·Below ~10 environments, don't split accounts to feel enterprise. The operating tax outweighs the isolation upside until you're at fleet scale.
Why managing ECS across accounts is hard
A multi-account AWS Org buys you isolation and clean billing — but AWS ships no single control plane for ECS. There's no "Lens for ECS", so you operate each account by hand.
This is not a hypothetical complaint. On AWS re:Post, a practitioner running "lots of AWS Accounts" asked the obvious question: is there a way to manage ECS clusters across them "without logging back and forth between the accounts" — ideally a tool like Lens, the Kubernetes IDE. The answer, from an AWS-side responder, was blunt:
"First of all, I don't think there is a tool quite like Lens, for ECS. That is, centrally manage and store credentials of various clusters and provide single plane of glass for cluster management."
— AWS re:Post, "How to manage ECS Clusters across accounts?"
The recommended path is exactly the manual stitching you'd expect: named CLI profiles per account, cross-account IAM roles, and a centralized CI/CD pipeline that assumes into each target account. None of that is wrong. But you — not AWS — are the integration layer. A "what's running in euw1-stag-main?" question becomes a context switch, an assume-role, and a fresh console tab.
This guide assumes you've already decided to go multi-account. If you're still working out how to structure those accounts in the first place — one account per environment group versus a single shared account — that decision comes first, and it's a different article. The short version: prod gets its own account for blast radius; non-prod usually shares one until Fargate quota or audit scope forces a split. Once that's settled, the question becomes operational: how do you run the fleet day to day?
Ready to use: a cross-account fleet-viewer role
Deploy one read-only IAM role to every member account, assumable from a single ops account. Now one set of credentials can list and describe ECS across the whole Org — no console hopping.
Drop this Terraform into each member account (via your account-baseline module or StackSets). The role trusts only your ops account and grants ECS read plus the cost and tag reads you need for a fleet view. From the ops account you then aws sts assume-role into each account and run aws ecs list-clusters against all of them with one identity.
# Deploy in EVERY member account. ops_account_id is your single
# operations/admin account that does the cross-account reading.
variable "ops_account_id" { type = string }
data "aws_iam_policy_document" "trust" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "AWS"
identifiers = ["arn:aws:iam::${var.ops_account_id}:root"]
}
# Require an external ID to block the confused-deputy problem.
condition {
test = "StringEquals"
variable = "sts:ExternalId"
values = ["fortem-fleet-viewer"]
}
}
}
data "aws_iam_policy_document" "read" {
statement {
sid = "EcsFleetRead"
effect = "Allow"
actions = [
"ecs:List*",
"ecs:Describe*",
"ce:GetCostAndUsage", # per-account cost for the fleet view
"tag:GetResources", # owner / env tags
"cloudwatch:GetMetricData", # task counts, CPU/mem
]
resources = ["*"]
}
}
resource "aws_iam_role" "fleet_viewer" {
name = "fortem-fleet-viewer"
assume_role_policy = data.aws_iam_policy_document.trust.json
}
resource "aws_iam_role_policy" "fleet_viewer" {
name = "fleet-read"
role = aws_iam_role.fleet_viewer.id
policy = data.aws_iam_policy_document.read.json
}sts:ExternalId condition stops a third party who happens to learn your ops account ID from assuming the role on your behalf. This is the same role shape a control plane like Fortem uses — least privilege, customer-revocable in two clicks.The five surfaces you have to operate
Operating ECS across accounts means solving five surfaces: fleet visibility, cross-account IAM access, image distribution, networking, and deploy. AWS gives you a primitive for each, not a system.
Each surface has a native AWS answer. The work — and the cost — is that none of them connect to each other, and you own the glue. Here's the map the rest of this guide follows:
Cross-account visibility and IAM access
Cross-account IAM has two halves: a read role for the fleet view, and a per-resource assume-role for tasks that reach into another account. The fleet-viewer role covers the first; an STS trust chain covers the second.
The visibility half is the fleet-viewer role above. The access half is different: it's when a running task in one account needs a resource that lives in another — an S3 bucket, a DynamoDB table, a secret. The pattern is a role in the resource's account whose trust policy names the task role's account, which the task assumes via STS at runtime.
The footgun here is registration, not runtime. ECS validates role ARNs when you register a task definition, and a malformed trust policy throws Role is not valid — a recurring re:Post complaint. The task role must trust ecs-tasks.amazonaws.com, the ARN must be in the right account, and whoever registers the task def needs iam:PassRole for it.
At five accounts, every "what's running where" question is five logins or five assume-role calls. The IAM mesh you build for visibility is the same mesh you build for access — design it once, deploy it to every account through your baseline module, and never wire it per-account by hand.
Distributing images: central ECR done right
Pick one: ECR cross-account replication (push once, pull locally) or a shared repo via repository policy. The aws:PrincipalOrgID shortcut works but exposes the repo to every account in the Org.
Most teams build once in a shared services or CI account, then need that image in every workload account. Two clean answers. Replication: ECR copies the image to a local repo in each destination account, so pulls are in-region, in-account, and cheap — best when you have many accounts. Shared repository: one repo with a repository policy granting pull to specific account IDs — simplest when you have a handful.
The tempting shortcut is to skip the account list and grant pull to your whole Organization with a single condition. It works. It's also exactly what a re:Post answer flagged:
"Beware: this allows all accounts in an Organization to access the ECR repository! Double check with your security team if this is allowed!"
— AWS re:Post, "Central ECR for ECS in multiple accounts"
For a regulated buyer — the kind tracking the fixed overhead every environment carriesdown to the dollar — "every account in the Org can pull this image" is the kind of finding an auditor circles in red. Name the accounts explicitly, or use replication.
Networking across accounts — and what it costs
AWS recommends Transit Gateway first for cross-account ECS traffic. It's the clean answer and a real line item: ~$36/mo per VPC attachment plus $0.02/GB — multiply by account count.
AWS's own guidance on networking ECS services across accounts says to consider Transit Gateway first, then VPC peering, shared VPC, or PrivateLink. The quick decision:
- ·Transit Gateway — hub-and-spoke for many accounts. Clean routing, but each VPC attachment bills hourly.
- ·VPC peering — one or two account pairs. No hourly fee, but a full mesh of N accounts is N²/2 peerings to manage.
- ·Shared VPC — one VPC, subnets shared into member accounts. Cheapest, but it softens the account boundary you split for.
- ·PrivateLink — expose one service, not full reachability. Per-service, not per-network.
The number nobody puts in the spreadsheet: Transit Gateway charges $0.05 per VPC attachment-hour — about $36.50/month per attachment ($0.05 × 730 hrs) — plus $0.02/GB processed. In a hub-and-spoke, you pay an attachment for the hub VPC and one per spoke:
That's before a single gigabyte crosses the gateway. Cross-account data processing at $0.02/GB adds up fast for chatty services. It's not a reason to avoid multi-account — it's a reason to know the bill before the architecture review, not after the invoice.
Deploying the same service to N accounts
One image, N accounts means one pipeline assuming a deploy role per target account. Parameterize the account ID and role ARN; never copy a pipeline per account — that's how environments drift.
The centralized model is the one AWS recommends and the one that scales: the pipeline lives in a single CI/CD account, and each stage assumes a deploy role in the target account to register the task definition and update the service. The image is built once and pulled from your central or replicated ECR. The task-definition template is one file; the account ID, role ARN, and environment-specific variables are inputs.
The anti-pattern is a copy of the pipeline per account. It feels faster on day one and it guarantees drift by month three — one account gets a CPU bump, another a new env var, a third a hotfix that never makes it back to the template. Multi-account already costs you a single pane of glass; don't also give up a single source of truth for what you deploy.
aws ecs describe-task-definition in each, assumed via the fleet-viewer role. If they differ in anything but account-specific values, your per-account pipelines have already drifted — and nothing was watching.When multi-account isn't worth it
Below ~10 environments, the operating tax — Transit Gateway cost, IAM sprawl, per-account deploys — usually outweighs the isolation upside. Split prod out for blast radius; keep non-prod together until it hurts.
Multi-account is the right call at scale and a self-inflicted wound at three environments. If you run a prod, a staging, and a dev, splitting them into five accounts to look enterprise buys you an IAM mesh, a Transit Gateway bill, and five places to deploy — to protect blast radius you could get from one account with disciplined tagging and SCPs.
The honest threshold: split prod into its own account early — that boundary is worth it for almost everyone. Hold non-prod in one shared account until something concrete forces a split: a regulated customer who needs hard isolation, a Fargate vCPU quota that dev load tests keep exhausting, or an audit scope you need to draw a clean line around. Add accounts because a requirement demands one, not because the org chart has room.
If you read this, you might also want to know
Can one ECS cluster span multiple AWS accounts?
No. An ECS cluster lives in exactly one account and one region. "Managing across accounts" always means N clusters in N accounts, coordinated from the outside — via cross-account IAM, a central pipeline, and a fleet view you assemble. There is no cluster object that straddles an account boundary.
How do I see total ECS cost across all my accounts in one place?
Enable Cost Explorer at the AWS Organization level from the management account, and tag every environment consistently so you can group by it. That gives you Org-wide cost but not per-environment ECS state. To tie cost to a running service and its owner across accounts, you need a tool that joins billing data with live ECS describe calls — which is what the fleet-viewer role's ce:GetCostAndUsage permission is for.
Should each customer get its own AWS account for ECS?
Only if isolation is a contractual or regulatory requirement. Per-customer accounts give the hardest blast-radius and data boundary, but they multiply every operating surface in this article by your customer count. Most B2B SaaS use shared accounts with per-tenant isolation inside the application until a specific customer's compliance posture forces a dedicated account.
Does AWS Organizations give me a single ECS dashboard?
No. Organizations handles account creation, consolidated billing, and service control policies — not a cross-account ECS view. AWS has no native single-pane-of-glass for ECS the way Lens works for Kubernetes; the cross-account visibility layer is something you build or buy.
FAQ
Every account. One screen.
No console hopping.
Fortem assumes a read role into every AWS account and gives you one live view — ECS services, cost, owner, and last deploy — across the whole fleet. Plus scheduling and per-environment RBAC. Book a 20-minute walkthrough.