This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Amazon ECS

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.account value, 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 --> AE

Choose 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.

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

ArchitectureAgents to operateCross-account trustAnchore Enterprise accountsBest for
One agent per account-regionOne per account-regionNot requiredOne per agent, if desiredStrict isolation, per-team ownership, separate Anchore accounts
Centralized agentOneRequired for each target accountOne for all inventoryCentral ownership, fewest deployments to maintain
One agent per account, all regionsOne per accountNot requiredOne per account, if desiredA 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

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

RuleDetail
Config file onlyThe 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 entryEvery 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 entriesThe 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 optionalSet external-id only when the target role’s trust policy requires one.
Roles may repeatThe 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

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>

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>

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:

ApproachWhat it requiresChange the configuration without rebuilding the image
Copy the file from S3 with a setup containerAn S3 object, s3:GetObject on the task role, and a second container in the task definitionYes — upload the new object and redeploy the service
Mount an S3 Files volumeAn S3 file system with a mount target in the task’s VPCYes — update the object in the bucket
Build a derived imageA Dockerfile and a registry the task can pull fromNo — 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.

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: someSecretAccessKey
    
  • Provide it to the helm chart via the values file:

    ecsInventory:
        useExistingSecret: true
        existingSecretName: "ecs-inventory-secrets"
    

Configure Assume-Role on Kubernetes

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 a kubectl apply and 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 image in 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/telemetry will create a subscription that only watches this cluster
  • partial ClusterARN arn:aws:ecs:eu-west-2:988505687240 will result in a subscription that watches every cluster within the account 988505687240
  • All ECS clusters arn:aws:ecs effectively auto-subscribes all ECS runtime agents.

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