/terraform-aws-ecr

A Terraform module to create an Elastic Container Registry (ECR) on Amazon Web Services (AWS). https://aws.amazon.com/ecr/

Primary LanguageHCLApache License 2.0Apache-2.0

Build Status GitHub tag (latest SemVer) Terraform Version AWS Provider Version Join Slack

terraform-aws-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.

Module Features

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

Getting Started

Most basic usage creating an ECR repository. To configure aws terraform provider credentials we recommend to set the environment variables AWS_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"
}

Access ECR with IAM principals

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 = ["*"]
    }
  ]
}

Module Argument Reference

See variables.tf and examples/ for details and use-cases.

Top-level Arguments

Module Configuration

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

Main Resource Configuration

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

Extended Resource configuration

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

Additional configuration

  • 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 [].

Module Outputs

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.

External Documentation

AWS Documentation IAM

Terraform AWS Provider Documentation

Module Versioning

This Module follows the principles of Semantic Versioning (SemVer).

Given a version number MAJOR.MINOR.PATCH, we increment the:

  1. MAJOR version when we make incompatible changes,
  2. MINOR version when we add functionality in a backwards compatible manner, and
  3. PATCH version when we make backwards compatible bug fixes.

Backwards compatibility in 0.0.z and 0.y.z version

  • Backwards compatibility in versions 0.0.z is not guaranteed when z is increased. (Initial development)
  • Backwards compatibility in versions 0.y.z is not guaranteed when y is increased. (Pre-release)

About Mineiros

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:

  • Terraform modules for all types of infrastructure such as VPCs, Docker clusters, databases, logging and monitoring, CI, etc.
  • Consulting & training on AWS, Terraform and DevOps

Reporting Issues

We use GitHub Issues to track community reported issues and missing features.

Contributing

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.

Makefile Targets

This repository comes with a handy Makefile. Run make help to see details on each available target.

License

license

This module is licensed under the Apache License Version 2.0, January 2004. Please see LICENSE for full details.

Copyright © 2020-2022 Mineiros GmbH