A Terraform module to create an Elastic Container Registry (ECR) on Amazon Web Services (AWS). https://aws.amazon.com/ecr/
A Terraform base module for creating an
Amazon Elastic Container Registry Repository (ECR) on
Amazon Web Services (AWS).
This module supports Terraform v1.x, v0.15, v0.14, v0.13 as well as v0.12.20 and above
and is compatible with the Terraform AWS provider v3 as well as v2.45 and above.
In contrast to the plain aws_ecr_repository
resource this module enables you to easily
grant cross account pull or push access to the repository.
Default Security Settings:
Image Scanning is enabled by default and you need to opt-out to disable it by setting scan_on_push = false
.
Least needed privileges are applied for managed pull and push identities.
Standard Module Features:
Create an ECR repository
Extended Module Features:
Attach a repository policy,
Attach a lifecycle policy
Additional Features:
Grant pull access to AWS identities (cross account),
Grant pull&push access to AWS identities (crosss account)
Features not yet implemented:
Easy lifecycle rule setup
Most basic usage creating an ECR repository.
To configure aws terraform provider credentials we recommend to set the environment variablesAWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
and not configure them inside .tf
-files
or using terraform variables (.tfvars
files) as those values might end up in terraforms state file
or in github commits.
module "resource" {
source = "mineiros-io/ecr/aws"
version = "~> 0.6.0"
name = "example"
}
If you’d like to pull and push images from and to the registry with IAM
principals such as an IAM user, you will need to request an authorization token
that is used to access any Amazon ECR registry that your IAM principal has
access to and is valid for 12 hours. To obtain an authorization token, you
must use the GetAuthorizationToken API operation to retrieve a base64-encoded
authorization token containing the username AWS and an encoded password.
Since ecr:GetAuthorizationToken
does not support resource-level permissions,
you’ll need to grant "Resource": "*"
to the ecr:GetAuthorizationToken
action
for every principal that should have access.
Please note, that since this module does not handle the ecr:GetAuthorizationToken
permission for you, it needs to be granted for principals on an individual basis.
Please consider the following example to grant pull and push permissions to an
IAM user.
module "ecr" {
source = "mineiros-io/ecr/aws"
version = "~> 0.6.0"
name = "sample-repository"
immutable = true
scan_on_push = true
pull_identities = [module.ci-user.users["ci.github-actions-ecr"].arn]
push_identities = [module.ci-user.users["ci.github-actions-ecr"].arn]
}
module "ci-user" {
source = "mineiros-io/iam-user/aws"
version = "~> 0.6.0"
names = ["ci.github-actions-ecr"]
policy_statements = [
{
sid = "GetAuthorizationToken"
effect = "Allow"
actions = ["ecr:GetAuthorizationToken"]
resources = ["*"]
}
]
}
See variables.tf and examples/ for details and use-cases.
module_enabled
: (Optional bool
)
Specifies whether resources in the module will be created.
Default is true
.
module_tags
: (Optional map(string)
)
A map of tags that will be applied to all created resources that accept tags. Tags defined with module_tags
can be overwritten by resource-specific tags.
Default is {}
.
module_depends_on
: (Optional list(dependency)
)
A list of dependencies. Any object can be assigned to this list to define a hidden external dependency.
name
: (Required string
)
The name of the repository. Forces new resource.
immutable
: (Optional string
)
You can configure a repository to be immutable to prevent image tags from being overwritten.
Default is "false"
.
tags
: (Optional map(string)
)
A mapping of tags to assign to the aws_ecr_repository
resources.
Default is {}
.
scan_on_push
: (Optional map(string)
)
Indicates whether images are scanned after being pushed to the repository (true) or not scanned (false).
Default is true
.
repository_policy_statements
: (Optional list(policy_statement)
)
List of statements of the repository policy.
Default is []
.
Each policy_statement
object in the list accepts the following attributes:
sid
: (Optional string
)
An ID for the policy statement.
effect
: (Optional string
)
Either “Allow” or “Deny”, to specify whether this statement allows or denies the given actions.
Default is "Allow"
.
actions
: (Optional list(string)
)
A list of actions that this statement either allows or denies.
not_actions
: (Optional list(string)
)
A list of actions that this statement does not apply to.
Used to apply a policy statement to all actions except those listed.
principals
: (Optional list(principal)
)
A nested configuration block (described below) specifying a resource (or resource pattern) to which this statement applies.
Each principal
object in the list accepts the following attributes:
type
: (Optional string
)
The type of principal. For AWS ARNs this is “AWS”. For AWS services (e.g. Lambda), this is “Service”.
Default is "AWS"
.
identifiers
: (Required list(string)
)
List of identifiers for principals.
When type is “AWS”, these are IAM user or role ARNs.
When type is “Service”, these are AWS Service roles e.g. lambda.amazonaws.com
.
not_principals
: (Optional list(principal)
)
Like principals except gives resources that the statement does not apply to.
lifecycle_policy_rules
: (Optional list(lifecycle_policy_rule)
)
List of lifecycle policy rules.
Default is []
.
Each lifecycle_policy_rule
object in the list accepts the following attributes:
rulePriority
: (Optional number
)
Sets the order in which rules are evaluated, lowest to highest.
A lifecycle policy rule with a priority of 1
will be acted upon first,
a rule with priority of 2
will be next, and so on.
When you add rules to a lifecycle policy,
you must give them each a unique value for rulePriority
.
Values do not need to be sequential across rules in a policy.
A rule with a tagStatus
value of any must have the highest value for rulePriority
and be evaluated last.
Note: The AWS ECR API seems to reorder rules based on rulePriority
.
If you define multiple rules that are not sorted in ascending rulePriority
order in the Terraform code,
the resource will be flagged for recreation every terraform plan.
description
: (Optional string
)
Describes the purpose of a rule within a lifecycle policy.
selection
: (Optional object(selection)
)
A selection
object.
The selection
object accepts the following attributes:
tagStatus
: (Required string
)
Determines whether the lifecycle policy rule that you are adding specifies a tag for an image.
Acceptable options are tagged, untagged, or any.
If you specify "any"
, then all images have the rule applied to them.
If you specify "tagged"
, then you must also specify a tagPrefixList
value.
If you specify "untagged"
, then you must omit tagPrefixList
.
tagPrefixList
: (Required list(string)
)
Only used if you specified tagStatus
: "tagged"
.
You must specify a comma-separated list of image tag prefixes on which to take action with your lifecycle policy.
For example, if your images are tagged as prod
, prod1
, prod2
, and so on,
you would use the tag prefix prod
to specify all of them.
If you specify multiple tags, only the images with all specified tags are selected.
countType
: (Required string
)
Specify a count type to apply to the images.
If countType
is set to "imageCountMoreThan"
,
you also specify countNumber
to create a rule that sets a limit on
the number of images that exist in your repository.
If countType
is set to "sinceImagePushed"
,
you also specify countUnit
and countNumber
to specify a time limit on
the images that exist in your repository.
countUnit
: (Required string
)
Specify a count unit of days to indicate that as the unit of time, in addition to countNumber
, which is the number of days.
This should only be specified when countType
is "sinceImagePushed"
;
an error will occur if you specify a count unit when countType
is any other value.
countNumber
: (Required number
)
Specify a count number.
Acceptable values are positive integers (0 is not an accepted value).
If the countType
used is "imageCountMoreThan"
,
then the value is the maximum number of images that you want to retain in your repository.
If the countType
used is "sinceImagePushed"
,
then the value is the maximum age limit for your images.
action
: (Optional object(action)
)
An action
object.
The action
object accepts the following attributes:
type
: (Required string
)
Specify an action type. The supported value is expire.
pull_identities
: (Optional list(string)
)
List of AWS identity identifiers to grant cross account pull access to.
Default is []
.
push_identities
: (Optional list(string)
)
List of AWS identity identifiers to grant cross account push access to.
Default is []
.
The following attributes are exported by the module:
repository
: (object(repository)
)
The aws_ecr_repository
resource.
repository_policy
: (object(repository_policy)
)
The aws_ecr_repository_policy
resource.
lifecycle_policy
: (list(lifecycle_policy)
)
The aws_ecr_lifecycle_policy
resource.
This Module follows the principles of Semantic Versioning (SemVer).
Given a version number MAJOR.MINOR.PATCH
, we increment the:
MAJOR
version when we make incompatible changes,MINOR
version when we add functionality in a backwards compatible manner, andPATCH
version when we make backwards compatible bug fixes.0.0.z
and 0.y.z
version0.0.z
is not guaranteed when z
is increased. (Initial development)0.y.z
is not guaranteed when y
is increased. (Pre-release)Mineiros is a DevOps as a Service company based in Berlin, Germany.
We offer commercial support for all of our projects and encourage you to reach out
if you have any questions or need help. Feel free to send us an email at hello@mineiros.io or join our Community Slack channel.
We can also help you with:
We use GitHub Issues to track community reported issues and missing features.
Contributions are always encouraged and welcome! For the process of accepting changes, we use
Pull Requests. If you’d like more information, please see our Contribution Guidelines.
This repository comes with a handy Makefile.
Run make help
to see details on each available target.
This module is licensed under the Apache License Version 2.0, January 2004.
Please see LICENSE for full details.
Copyright © 2020-2022 Mineiros GmbH