ECR secrets provide credentials for pulling container images from AWS Elastic Container Registry. Unlike generic Docker secrets, ECR secrets handle AWS’s token-based authentication automatically, including cross-account access via IAM role assumption.
Use Cases
- Private ECR Repositories: Pull images from your AWS ECR repositories
- Cross-Account Access: Access ECR in different AWS accounts
- Multi-Region Deployments: Pull images from ECR across AWS regions
- CI/CD Pipelines: Authenticate build systems with ECR
Use ECR secrets instead of Docker secrets for AWS ECR. They handle AWS token refresh automatically and support IAM role assumption for cross-account access.
Configuration Options
| Field | Description | Required |
|---|
accessKey | AWS Access Key ID | Yes |
secretKey | AWS Secret Access Key | Yes |
repos | List of ECR repository URIs to access | Yes |
roleArn | IAM Role ARN for cross-account access | No |
externalId | External ID for role assumption | No |
Create an ECR Secret
Console UI
CLI
Terraform
Pulumi
Navigate to Secrets
In the Console, navigate to Secrets and click New, or use the Create dropdown in the top-right corner and select Secret.
Enter basic information
Enter a Name and optional Description.
Select secret type
Select ECR as the secret type.
Configure credentials
Click Data in the left pane. Enter the Access Key and Secret Key. Click Add under Repos to add repository URIs. Optionally enter a Role ARN and External ID for cross-account access.
Create the secret
Click Create.
cpln secret create-ecr \
--name ecr-pull-secret \
--access-key AKIAIOSFODNN7EXAMPLE \
--secret-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \
--repo 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app \
--repo 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-api \
--org my-org
With cross-account role assumption:cpln secret create-ecr \
--name ecr-cross-account \
--access-key AKIAIOSFODNN7EXAMPLE \
--secret-key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \
--repo 987654321098.dkr.ecr.us-west-2.amazonaws.com/shared-images \
--role-arn arn:aws:iam::987654321098:role/ECRPullRole \
--external-id my-external-id \
--org my-org
resource "cpln_secret" "ecr" {
name = "ecr-pull-secret"
description = "ECR repository access"
ecr {
access_key = "AKIAIOSFODNN7EXAMPLE"
secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
repos = [
"123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app",
"123456789012.dkr.ecr.us-east-1.amazonaws.com/my-api"
]
}
}
Cross-account access:resource "cpln_secret" "ecr_cross_account" {
name = "ecr-cross-account"
description = "Cross-account ECR access"
ecr {
access_key = "AKIAIOSFODNN7EXAMPLE"
secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
repos = ["987654321098.dkr.ecr.us-west-2.amazonaws.com/shared-images"]
role_arn = "arn:aws:iam::987654321098:role/ECRPullRole"
external_id = "my-external-id"
}
}
This example uses hardcoded credentials for testing. In production, use Terraform variables or a secrets manager.
import * as cpln from "@pulumiverse/cpln";
const ecrSecret = new cpln.Secret("ecr-pull-secret", {
name: "ecr-pull-secret",
description: "ECR repository access",
ecr: {
accessKey: "AKIAIOSFODNN7EXAMPLE",
secretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
repos: [
"123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app",
"123456789012.dkr.ecr.us-east-1.amazonaws.com/my-api",
],
},
});
import pulumiverse_cpln as cpln
ecr_secret = cpln.Secret("ecr-pull-secret",
name="ecr-pull-secret",
description="ECR repository access",
ecr={
"access_key": "AKIAIOSFODNN7EXAMPLE",
"secret_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"repos": [
"123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app",
"123456789012.dkr.ecr.us-east-1.amazonaws.com/my-api",
],
})
package main
import (
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/pulumiverse/pulumi-cpln/sdk/go/cpln"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := cpln.NewSecret(ctx, "ecr-pull-secret", &cpln.SecretArgs{
Name: pulumi.String("ecr-pull-secret"),
Description: pulumi.String("ECR repository access"),
Ecr: &cpln.SecretEcrArgs{
AccessKey: pulumi.String("AKIAIOSFODNN7EXAMPLE"),
SecretKey: pulumi.String("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"),
Repos: pulumi.StringArray{
pulumi.String("123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app"),
pulumi.String("123456789012.dkr.ecr.us-east-1.amazonaws.com/my-api"),
},
},
})
return err
})
}
using Pulumi;
using Pulumiverse.Cpln;
using Pulumiverse.Cpln.Inputs;
return await Deployment.RunAsync(() =>
{
var ecrSecret = new Secret("ecr-pull-secret", new SecretArgs
{
Name = "ecr-pull-secret",
Description = "ECR repository access",
Ecr = new SecretEcrArgs
{
AccessKey = "AKIAIOSFODNN7EXAMPLE",
SecretKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
Repos =
{
"123456789012.dkr.ecr.us-east-1.amazonaws.com/my-app",
"123456789012.dkr.ecr.us-east-1.amazonaws.com/my-api",
},
},
});
});
ECR repository URLs follow this pattern:
<account-id>.dkr.ecr.<region>.amazonaws.com/<repository-name>
Example:
123456789012.dkr.ecr.us-east-1.amazonaws.com/my-application
Include the full repository path, not just the registry URL. Each repository you need to access should be listed separately.
Using the Secret
After creating the ECR secret, add it as a pull secret to your GVC:
Console UI
CLI
Terraform
Pulumi
Navigate to your GVC
Open your GVC in the Console.
Open Pull Secrets
Click Pull Secrets in the left pane.
Add the secret
Click Add and select your ECR secret.
cpln gvc update my-gvc \
--set spec.pullSecretLinks+="ecr-pull-secret" \
--org my-org
resource "cpln_gvc" "my_gvc" {
name = "my-gvc"
pull_secrets = [
cpln_secret.ecr.name
]
}
import * as cpln from "@pulumiverse/cpln";
const gvc = new cpln.Gvc("my-gvc", {
name: "my-gvc",
pullSecrets: [ecrSecret.name],
});
import pulumiverse_cpln as cpln
gvc = cpln.Gvc("my-gvc",
name="my-gvc",
pull_secrets=[ecr_secret.name])
gvc, err := cpln.NewGvc(ctx, "my-gvc", &cpln.GvcArgs{
Name: pulumi.String("my-gvc"),
PullSecrets: pulumi.StringArray{ecrSecret.Name},
})
var gvc = new Gvc("my-gvc", new GvcArgs
{
Name = "my-gvc",
PullSecrets = new[] { ecrSecret.Name },
});
Next Steps