Anchore uses a go binary called anchore-ecs-inventory that leverages the AWS Go SDK to gather an inventory of containers and their images running on Amazon ECS and report back to Anchore Enterprise.
The Amazon ECS Inventory Agent can be deployed as an ECS Service on AWS Fargate or, where you already run Kubernetes, installed via Helm chart. A single agent can inventory the AWS account-region it runs in, or inventory several AWS account-regions by assuming an IAM role in each one.
Plan Your Deployment Architecture
The agent polls the Amazon ECS APIs one region at a time. Each region it covers is an inventory pass: the agent lists the clusters, services, and tasks in that region and reports the images it finds to Anchore Enterprise. By default the agent runs a single pass against its own account and region using whatever AWS credentials it starts with.
From ECS Inventory v1.5.0 onward, an agent can instead run a pass for each IAM role you configure, up to 20 roles. Because a role can live in any AWS account whose trust policy allows the agent to assume it, you are free to decide how many agents you run and which account-regions each one covers.
Requirements Shared by Every Architecture
No matter which architecture you choose, all of the following must hold:
- The agent needs network access to the Anchore Enterprise API. The agent only makes outbound connections, so no inbound rules are required, but the subnets and security groups it runs in must be able to reach your Anchore Enterprise deployment. Give the agent a dedicated Anchore Enterprise user rather than reusing an administrator account.
- Anchore Enterprise needs to be able to analyze the images the agent reports. The agent reports image references, not image content. If an image is not already analyzed, Anchore Enterprise pulls and analyzes it itself, which means the deployment needs network access to the registry holding that image and registry credentials for it — for example ECR credentials for images stored in Amazon ECR. Without this, images still appear in the inventory but never gain vulnerability or policy results.
- All inventory from one agent lands in one Anchore Enterprise account. An agent has a single set of Anchore Enterprise credentials and a single
anchore.accountvalue, which applies to every pass it runs. If inventory from different AWS accounts must be separated into different Anchore Enterprise accounts, run a separate agent for each.
Deploy One Agent per AWS Account-Region
Run an independent agent in each AWS account-region you want to inventory, each using its own task role or service account. This is the pre-v1.5.0 model and remains the simplest option: no cross-account trust relationships, and a fault in one account cannot affect inventory collection in another.
flowchart LR
subgraph ACC1["AWS account 123456789012"]
AG1["ecs-inventory agent<br/>us-east-1"] --> E1["ECS clusters<br/>us-east-1"]
end
subgraph ACC2["AWS account 999999999999"]
AG2["ecs-inventory agent<br/>eu-west-1"] --> E2["ECS clusters<br/>eu-west-1"]
end
AG1 --> AE["Anchore Enterprise API"]
AG2 --> AEChoose this when you want strict isolation between accounts, when different teams own each account, or when each AWS account’s inventory needs to report into a different Anchore Enterprise account.
Centralize Agents in One AWS Account
Run one agent in a central account and give it an assume-role entry for each account-region you want to inventory. The agent assumes a role in every target account and reports all of the resulting inventory to Anchore Enterprise.
flowchart LR
subgraph HUB["AWS account 111111111111 — agent account"]
AG["ecs-inventory agent<br/>AnchoreECSInventoryTaskRole"]
end
subgraph ACC1["AWS account 123456789012"]
R1["anchore-ecs-inventory role"] --> E1["ECS clusters<br/>us-east-1"]
end
subgraph ACC2["AWS account 999999999999"]
R2["anchore-ecs-inventory role"] --> E2["ECS clusters<br/>eu-west-1"]
end
AG -->|"sts:AssumeRole"| R1
AG -->|"sts:AssumeRole"| R2
AG --> AE["Anchore Enterprise API"]Choose this when you want a single deployment to operate, patch, and monitor, and when one team owns runtime inventory across the organization. Only the central account needs network access to Anchore Enterprise.
assume-role entries are configured, the agent no longer inventories its own account. To include the account the agent runs in, add an explicit entry for a role in that account.Inventory Every Region of an Account from One Agent
A single agent can also cover several regions within one AWS account. Add one assume-role entry per region, all pointing at the same role ARN — each entry is an independent pass, so repeating a role ARN with a different region is expected.
flowchart LR
subgraph ACC["AWS account 123456789012"]
AG["ecs-inventory agent"] -->|"sts:AssumeRole"| R["anchore-ecs-inventory role"]
R --> E1["ECS clusters<br/>us-east-1"]
R --> E2["ECS clusters<br/>us-west-2"]
R --> E3["ECS clusters<br/>eu-west-1"]
end
AG --> AE["Anchore Enterprise API"]Choose this when a single account runs workloads in several regions. Because the role lives in the same account as the agent, no cross-account trust is involved.
Compare the Architectures
| Architecture | Agents to operate | Cross-account trust | Anchore Enterprise accounts | Best for |
|---|---|---|---|---|
| One agent per account-region | One per account-region | Not required | One per agent, if desired | Strict isolation, per-team ownership, separate Anchore accounts |
| Centralized agent | One | Required for each target account | One for all inventory | Central ownership, fewest deployments to maintain |
| One agent per account, all regions | One per account | Not required | One per account, if desired | A single account running workloads in several regions |
These patterns combine. A common middle ground is one agent per organizational unit, each assuming roles into the accounts that unit owns, which keeps the number of deployments low without concentrating every account’s trust in one place.
Inventory Multiple AWS Account-Regions from a Single Agent
assume-role list requires ECS Inventory v1.5.0 or later. Earlier versions inventory only the agent’s own account-region.Add an assume-role list to the agent’s configuration file, giving each entry a role ARN, the region to inventory with those credentials, and an external ID where the target role’s trust policy requires one:
assume-role:
- role-arn: arn:aws:iam::123456789012:role/anchore-ecs-inventory
region: us-east-1
- role-arn: arn:aws:iam::999999999999:role/anchore-ecs-inventory
region: eu-west-1
external-id: <external-id>
Each entry runs as an independent inventory pass on every polling cycle, up to 20 entries. Assumed credentials refresh automatically as they expire, so a long-running agent keeps working without intervention.
An empty assume-role list is the default and preserves the behavior of inventorying the agent’s own account using the top-level region.
Configuration Rules and Limits
| Rule | Detail |
|---|---|
| Config file only | The assume-role list can only be set in a configuration file. Setting ANCHORE_ECS_INVENTORY_ASSUME_ROLE is rejected at startup with an explicit error. |
| Region is required per entry | Every entry must name its own region. The top-level region, the --region flag, and ANCHORE_ECS_INVENTORY_REGION are all ignored when entries are configured, and the agent logs a warning if one is set. |
| Maximum of 20 entries | The agent refuses to start if more than 20 entries are configured. This bounds the number of ECS and STS calls made per polling cycle. |
| External ID is optional | Set external-id only when the target role’s trust policy requires one. |
| Roles may repeat | The same role-arn can appear in several entries with different regions, which is how one role covers multiple regions. |
Startup Validation and Failure Handling
Every configured role is checked at startup and the agent exits if one cannot be assumed, so a misconfigured role surfaces immediately instead of as quietly missing inventory. Once the polling loop is running, a role that fails on one cycle is logged and retried on the next, and the remaining passes continue to report.
Passes run serially within a cycle, so a slow account or a long list of roles can push a cycle past polling-interval-seconds. When that happens the agent logs a warning and the next cycle starts immediately. If you see this warning, raise polling-interval-seconds or split the roles across more agents.
Rotating the static base credentials the agent uses to call STS requires a restart. In the no-role case the agent rebuilds its AWS configuration each cycle, so rotated static credentials are picked up on the next poll.
IAM Role Configuration
Grant ECS Read Permissions
The identity that queries Amazon ECS — the task role, the service account role, the static credentials, or an assumed role — needs read and list access to ECS. The following policy grants exactly the API actions the agent calls:
cat <<EOF > ecs-read-only-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AnchoreEcsInventoryRead",
"Effect": "Allow",
"Action": [
"ecs:ListClusters",
"ecs:ListServices",
"ecs:ListTasks",
"ecs:DescribeServices",
"ecs:DescribeTasks",
"ecs:ListTagsForResource"
],
"Resource": "*"
}
]
}
EOF
aws iam create-policy \
--policy-name ECSReadOnly \
--policy-document file://ecs-read-only-policy.json
ecs:Describe* and ecs:List* wildcards. Those still work; the action list above is the least-privilege equivalent.When the agent inventories multiple account-regions, this policy belongs on the role named by each assume-role entry, in the account being inventoried — not on the agent’s own identity.
Allow the Agent to Assume a Role
Assuming a role requires permissions on both sides of the trust relationship. In the examples below, 111111111111 is the account the agent runs in and 123456789012 is an account being inventoried.
First, the agent’s base identity — the ECS task role, the Kubernetes service account role, or the static credentials the agent starts with — must be allowed to assume each target role:
cat <<EOF > assume-role-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AnchoreEcsInventoryAssumeRole",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::123456789012:role/anchore-ecs-inventory",
"arn:aws:iam::999999999999:role/anchore-ecs-inventory"
]
}
]
}
EOF
aws iam put-role-policy \
--role-name AnchoreECSInventoryTaskRole \
--policy-name AnchoreECSInventoryAssumeRole \
--policy-document file://assume-role-policy.json
Second, each target role must trust the agent’s base identity. Create the role in the account being inventoried with a trust policy naming the agent’s role as the principal, then attach the ECS read policy to it:
cat <<EOF > trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/AnchoreECSInventoryTaskRole"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
aws iam create-role \
--role-name anchore-ecs-inventory \
--assume-role-policy-document file://trust-policy.json
aws iam attach-role-policy \
--role-name anchore-ecs-inventory \
--policy-arn arn:aws:iam::123456789012:policy/ECSReadOnly
For a role in the same account as the agent, the trust policy is identical — the principal simply references a role in the same account.
Require an External ID
An external ID is a shared secret that the agent must present when assuming a role. It protects against the confused deputy problem, where a third party who can persuade your agent to assume a role gains access it was never meant to have. Use one when the account being inventoried is operated by a different team or organization from the account running the agent.
Add the sts:ExternalId condition to the target role’s trust policy:
cat <<EOF > trust-policy-external-id.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/AnchoreECSInventoryTaskRole"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "<external-id>"
}
}
}
]
}
EOF
aws iam create-role \
--role-name anchore-ecs-inventory \
--assume-role-policy-document file://trust-policy-external-id.json
Then set the matching value on the corresponding assume-role entry in the agent’s configuration file:
assume-role:
- role-arn: arn:aws:iam::123456789012:role/anchore-ecs-inventory
region: us-east-1
external-id: <external-id>
sts:ExternalId condition only when you also set external-id in the agent configuration, and set external-id only when the trust policy requires it. A mismatch in either direction causes the role assumption to fail, and the agent exits at startup.Deploying as an ECS Service on AWS Fargate
You can deploy the ecs-inventory container as an ECS Service on AWS ECS/Fargate. Running the agent as a service ensures that ECS automatically restarts the task if it stops, maintaining continuous inventory reporting to Anchore Enterprise.
Set Environment Variables
Set the following environment variables before running the commands below. Replace the placeholder values with your own.
export aws_account_id=$(aws sts get-caller-identity --query Account --output text)
export AWS_DEFAULT_REGION=<your_aws_region>
# VPC and networking
export vpc_id=<your_vpc_id>
export subnet_ids=<your_subnet_id_1>,<your_subnet_id_2>
export security_group_id=<your_security_group_id>
# Anchore Enterprise connection details
export ANCHORE_URL=<your_anchore_enterprise_url>
export ANCHORE_ACCOUNT=<your_anchore_account>
export ANCHORE_USERNAME=<your_anchore_username>
export ANCHORE_PASSWORD=<your_anchore_password>
Create IAM Roles and Policies
Create the IAM policy, roles, and permissions required by the ECS task.
aws iam create-policy \
--policy-name ECSReadOnly \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AnchoreEcsInventoryRead",
"Action": [
"ecs:ListClusters",
"ecs:ListServices",
"ecs:ListTasks",
"ecs:DescribeServices",
"ecs:DescribeTasks",
"ecs:ListTagsForResource"
],
"Effect": "Allow",
"Resource": "*"
}
]
}'
aws iam create-role \
--role-name AnchoreECSInventoryTaskRole \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}'
aws iam create-role \
--role-name AnchoreECSInventoryExecutionRole \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}'
aws iam attach-role-policy \
--role-name AnchoreECSInventoryExecutionRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
aws iam attach-role-policy \
--role-name AnchoreECSInventoryTaskRole \
--policy-arn arn:aws:iam::${aws_account_id}:policy/ECSReadOnly
Store the Anchore Enterprise Password in AWS Systems Manager Parameter Store
aws ssm put-parameter \
--name "/ANCHORE_ECS_INVENTORY_ANCHORE_PASSWORD" \
--type "SecureString" \
--value "${ANCHORE_PASSWORD}" \
--overwrite
aws iam put-role-policy \
--role-name AnchoreECSInventoryExecutionRole \
--policy-name ECSInventorySSMAccess \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetParameters",
"ssm:GetParameter"
],
"Resource": "arn:aws:ssm:'${AWS_DEFAULT_REGION}':'${aws_account_id}':parameter/ANCHORE_ECS_INVENTORY_ANCHORE_PASSWORD"
}
]
}'
Create the CloudWatch Log Group
aws logs create-log-group \
--log-group-name /anchore/ecs-inventory \
--region ${AWS_DEFAULT_REGION}
Register the Task Definition
cat << EOF > task-definition.json
{
"family": "anchore-ecs-inventory",
"cpu": "512",
"memory": "1024",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"executionRoleArn": "arn:aws:iam::${aws_account_id}:role/AnchoreECSInventoryExecutionRole",
"taskRoleArn": "arn:aws:iam::${aws_account_id}:role/AnchoreECSInventoryTaskRole",
"containerDefinitions": [
{
"name": "ecs-inventory",
"image": "docker.io/anchore/ecs-inventory:latest",
"cpu": 0,
"essential": true,
"user": "1000",
"readonlyRootFilesystem": true,
"linuxParameters": {
"capabilities": {
"drop": ["ALL"]
}
},
"environment": [
{
"name": "ANCHORE_ECS_INVENTORY_ANCHORE_URL",
"value": "${ANCHORE_URL}"
},
{
"name": "ANCHORE_ECS_INVENTORY_ANCHORE_USER",
"value": "${ANCHORE_USERNAME}"
},
{
"name": "ANCHORE_ECS_INVENTORY_ANCHORE_ACCOUNT",
"value": "${ANCHORE_ACCOUNT}"
},
{
"name": "ANCHORE_ECS_INVENTORY_REGION",
"value": "${AWS_DEFAULT_REGION}"
}
],
"secrets": [
{
"name": "ANCHORE_ECS_INVENTORY_ANCHORE_PASSWORD",
"valueFrom": "arn:aws:ssm:${AWS_DEFAULT_REGION}:${aws_account_id}:parameter/ANCHORE_ECS_INVENTORY_ANCHORE_PASSWORD"
}
],
"healthCheck": {
"command": ["CMD", "/anchore-ecs-inventory", "version"],
"interval": 30,
"timeout": 5,
"retries": 3,
"startPeriod": 10
},
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group": "true",
"awslogs-group": "/anchore/ecs-inventory",
"awslogs-region": "${AWS_DEFAULT_REGION}",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}
EOF
aws ecs register-task-definition \
--cli-input-json file://task-definition.json
Create the ECS Cluster and Service
Create the ECS cluster and deploy the agent as a Fargate service with a desired count of 1.
aws ecs create-cluster \
--cluster-name anchore-ecs-inventory-cluster
aws ecs create-service \
--cluster anchore-ecs-inventory-cluster \
--service-name anchore-ecs-inventory \
--task-definition anchore-ecs-inventory \
--desired-count 1 \
--launch-type FARGATE \
--scheduling-strategy REPLICA \
--network-configuration "awsvpcConfiguration={
subnets=[${subnet_ids}],
securityGroups=[${security_group_id}],
assignPublicIp=ENABLED
}"
Inventory Multiple Account-Regions from the Fargate Service
The walkthrough above deploys an agent that inventories its own account and region. To have the same service inventory several account-regions, grant the task role permission to assume the target roles and give the agent a configuration file containing an assume-role list.
Grant the Task Role Permission to Assume the Target Roles
Create the target roles in each account being inventoried, following Allow the Agent to Assume a Role, then attach the assume-role policy to AnchoreECSInventoryTaskRole:
aws iam put-role-policy \
--role-name AnchoreECSInventoryTaskRole \
--policy-name AnchoreECSInventoryAssumeRole \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AnchoreEcsInventoryAssumeRole",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::123456789012:role/anchore-ecs-inventory",
"arn:aws:iam::999999999999:role/anchore-ecs-inventory"
]
}
]
}'
The task role no longer needs the ECSReadOnly policy in the agent’s own account, because the ECS calls are made with the assumed credentials instead. Keep it only if you also add an assume-role entry for a role in the agent’s account.
Write the Configuration File
Create the configuration file, including the assume-role list:
log:
level: "info"
file: ""
anchore:
url: $ANCHORE_ECS_INVENTORY_ANCHORE_URL
user: $ANCHORE_ECS_INVENTORY_ANCHORE_USER
password: $ANCHORE_ECS_INVENTORY_ANCHORE_PASSWORD
account: $ANCHORE_ECS_INVENTORY_ANCHORE_ACCOUNT
http:
insecure: false
timeout-seconds: 10
polling-interval-seconds: 300
quiet: false
assume-role:
- role-arn: arn:aws:iam::123456789012:role/anchore-ecs-inventory
region: us-east-1
- role-arn: arn:aws:iam::999999999999:role/anchore-ecs-inventory
region: eu-west-1
external-id: <external-id>
anchore keys in the file even though their values are supplied at runtime. The $ANCHORE_ECS_INVENTORY_* placeholders are overridden by the matching environment variables and task definition secrets, but the keys must be present in the file for those values to be applied. Omit the top-level region key, which is ignored when assume-role entries are configured.Choose How to Supply the Configuration File
Amazon ECS has no direct equivalent of a Kubernetes ConfigMap. The secrets parameter (Systems Manager Parameter Store and Secrets Manager) and the environmentFiles parameter (a .env object in Amazon S3) both inject values as environment variables, and the assume-role list cannot be set that way — it is read only from a configuration file. The file therefore has to reach the container’s filesystem, and three approaches do that on Fargate:
| Approach | What it requires | Change the configuration without rebuilding the image |
|---|---|---|
| Copy the file from S3 with a setup container | An S3 object, s3:GetObject on the task role, and a second container in the task definition | Yes — upload the new object and redeploy the service |
| Mount an S3 Files volume | An S3 file system with a mount target in the task’s VPC | Yes — update the object in the bucket |
| Build a derived image | A Dockerfile and a registry the task can pull from | No — rebuild and push the image for every change |
The agent reads its configuration from /etc/xdg/anchore-ecs-inventory/config.yaml inside the container, so each approach places the file at that path. Copying the file from S3 is the closest equivalent to a ConfigMap and is the approach to reach for first: it adds no new infrastructure and keeps the released Anchore image unmodified.
Copy the Configuration File from S3
Upload the configuration file to a bucket the task can read:
aws s3 cp config.yaml s3://<your_config_bucket>/anchore-ecs-inventory/config.yaml
Allow the task role to read it:
aws iam put-role-policy \
--role-name AnchoreECSInventoryTaskRole \
--policy-name AnchoreECSInventoryConfigRead \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AnchoreEcsInventoryConfigRead",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<your_config_bucket>/anchore-ecs-inventory/config.yaml"
}
]
}'
Then add a shared volume and a setup container to the task definition. The setup container copies the file from S3 into the volume and exits; the dependsOn condition holds the agent back until that copy has succeeded:
"volumes": [
{
"name": "agent-config"
}
],
"containerDefinitions": [
{
"name": "config-init",
"image": "public.ecr.aws/aws-cli/aws-cli:latest",
"essential": false,
"command": [
"s3",
"cp",
"s3://<your_config_bucket>/anchore-ecs-inventory/config.yaml",
"/config/config.yaml"
],
"mountPoints": [
{
"sourceVolume": "agent-config",
"containerPath": "/config"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/anchore/ecs-inventory",
"awslogs-region": "<region>",
"awslogs-stream-prefix": "config-init"
}
}
},
{
"name": "ecs-inventory",
"image": "docker.io/anchore/ecs-inventory:v1.5.0",
"essential": true,
"dependsOn": [
{
"containerName": "config-init",
"condition": "SUCCESS"
}
],
"mountPoints": [
{
"sourceVolume": "agent-config",
"containerPath": "/etc/xdg/anchore-ecs-inventory",
"readOnly": true
}
]
}
]
The remaining keys on the ecs-inventory container — environment, secrets, healthCheck, logConfiguration, and the security settings — stay as they are in Register the Task Definition, except that ANCHORE_ECS_INVENTORY_REGION should be removed because it is ignored when assume-role entries are configured.
/etc/xdg/anchore-ecs-inventory replaces the default configuration file that ships in the image, which is the intent. The setup container needs network access to Amazon S3, either through the task’s public IP or through a VPC endpoint for S3.To roll out a configuration change, upload the new object and run aws ecs update-service --force-new-deployment. The setup container fetches the current object each time a task starts.
Mount an S3 Files Volume
Amazon ECS can also mount an S3 file system directly as a volume, which keeps the file in S3 and synchronizes changes without a setup container. This requires an S3 file system with a mount target reachable from the task’s VPC, so it suits deployments that already use S3 Files; if you are adding it only to deliver this one file, the setup container above is lighter.
"volumes": [
{
"name": "agent-config",
"s3filesVolumeConfiguration": {
"fileSystemArn": "arn:aws:s3files:<region>:<aws_account_id>:file-system/<file-system-id>",
"rootDirectory": "/anchore-ecs-inventory"
}
}
]
Mount it on the agent container at /etc/xdg/anchore-ecs-inventory with "readOnly": true, exactly as in the setup container example above, and drop the config-init container and its dependsOn entry. Transit encryption and a task IAM role are mandatory for S3 Files volumes and are enforced automatically; the task role also needs permission to connect to the file system. S3 Files volumes are supported on Fargate and Amazon ECS Managed Instances, but not on the EC2 launch type. See Configuring S3 Files for Amazon ECS for the file system prerequisites and IAM policies.
Build a Derived Image with the Configuration File
Where a rebuild per configuration change is acceptable — for example when the role list is managed in version control and rolled out through a pipeline — bake the file into an image built from the released one:
FROM docker.io/anchore/ecs-inventory:v1.5.0
COPY config.yaml /etc/xdg/anchore-ecs-inventory/config.yaml
Then build the image and push it to a registry your ECS tasks can pull from, such as Amazon ECR:
docker build -t ${aws_account_id}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/anchore-ecs-inventory:v1.5.0 .
aws ecr get-login-password --region ${AWS_DEFAULT_REGION} \
| docker login --username AWS --password-stdin \
${aws_account_id}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com
docker push ${aws_account_id}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/anchore-ecs-inventory:v1.5.0
Point image in the task definition at the derived image, and remove the ANCHORE_ECS_INVENTORY_REGION environment variable because it is ignored when assume-role entries are configured.
Deploy the Updated Service
Register the new task definition revision and update the service to use it:
aws ecs register-task-definition \
--cli-input-json file://task-definition.json
aws ecs update-service \
--cluster anchore-ecs-inventory-cluster \
--service anchore-ecs-inventory \
--task-definition anchore-ecs-inventory \
--force-new-deployment
Check the service’s CloudWatch logs after the deployment. The agent logs Startup validation passed with the number of passes it will run, and exits if any configured role cannot be assumed.
Deploying via Helm on Kubernetes
You can install the chart via the Anchore Enterprise repository:
helm repo add anchore https://charts.anchore.io
helm install <release-name> -f <values.yaml> anchore/ecs-inventory
A basic values file can be found here.
Assign the IAM Role to the Agent
Create the ECS read policy and attach it to an IAM role, then follow the AWS instructions found here to assign that role to a Kubernetes service account in the cluster where the Anchore ECS Inventory Agent will be running. Then configure the following in your values.yaml to ensure the agent has access to the ECS service API:
serviceAccountName: "service_account_name"
Using existing secrets
For those users unable to use IAM roles (e.g. the ECS Inventory Agent is not running on Kubernetes or ECS), the (ecsInventory.useExistingSecret and ecsInventory.existingSecretName) or ecsInventory.injectSecretsViaEnv keys allows you to create your own secret and provide it in the values file or place the required secret into the pod via different means such as injecting the secrets into the pod using hashicorp vault. For example:
Create a secret in kubernetes:
apiVersion: v1 kind: Secret metadata: name: ecs-inventory-secrets type: Opaque stringData: ANCHORE_ECS_INVENTORY_ANCHORE_PASSWORD: foobar AWS_ACCESS_KEY_ID: someKeyId AWS_SECRET_ACCESS_KEY: someSecretAccessKeyProvide it to the helm chart via the values file:
ecsInventory: useExistingSecret: true existingSecretName: "ecs-inventory-secrets"
Configure Assume-Role on Kubernetes
ecs-inventory Helm chart generates the agent’s configuration file from its own values and does not yet expose the assume-role list. As of chart v0.0.18 there is no chart value that sets it, and the list cannot be supplied through environment variables. To inventory multiple account-regions from an agent running on Kubernetes, supply the configuration file yourself using one of the approaches below.The agent reads its configuration file from /etc/xdg/anchore-ecs-inventory/config.yaml in the container image. Write the file as shown in Write the Configuration File, then place it at that path using either approach below:
- Mount your own ConfigMap. Deploy the agent with your own manifests rather than the chart, mounting a ConfigMap that holds the complete configuration file at
/etc/xdg/anchore-ecs-inventory/config.yaml. This keeps configuration changes to akubectl applyand a pod restart. - Bake the configuration into a derived image. Build an image from the released one with your configuration file copied over the default, as described in Build a Derived Image with the Configuration File, then set
imagein your values file to the derived image. The chart deploys this image unmodified, so no custom manifests are needed.
The service account attached to the agent still needs permission to assume each target role; it does not need ECS read permissions in its own account unless you also add an assume-role entry for a role there.
Usage
To verify that you are tracking Amazon ECS inventory in your Anchore Enterprise deployment you can access inventory results with the command anchorectl inventory list and look for results where the TYPE is ecs.
Auto analyze new inventory
It is possible to create a subscription to watch for new Amazon ECS inventory that is reported to Anchore Enterprise and automatically schedule those images for analysis. The subscription_key can be set to any part of an Amazon ECS ClusterARN. For example setting the subscription_key to the:
- full ClusterARN
arn:aws:ecs:us-east-1:012345678910:cluster/telemetrywill create a subscription that only watches this cluster - partial ClusterARN
arn:aws:ecs:eu-west-2:988505687240will result in a subscription that watches every cluster within the account988505687240 - All ECS clusters
arn:aws:ecseffectively auto-subscribes all ECS runtime agents.
aws-us-gov instead of aws. For example, use arn:aws-us-gov:ecs to subscribe to all GovCloud ECS clusters, or arn:aws-us-gov:ecs:us-gov-west-1:012345678910:cluster/telemetry for a specific cluster.anchorectl inventory watch activate <SUBSCRIPTION_KEY>
The least-privilege role with permission to add a subscription is image-analyzer.
UI
The UI will visually indicate when images are actively found in ECS Runtime Inventory.

ECS Runtime linkage via UI
General Runtime Management
See Data Management