diff --git a/README.md b/README.md index e16d31f9b..dbb15d0bb 100644 --- a/README.md +++ b/README.md @@ -496,6 +496,8 @@ The following inputs can be used as `step.with` keys | `aws_ecr_repo_policy_input` | String | The JSON policy to apply to the repository. If defined overrides the default policy' | | `aws_ecr_repo_read_arn` | String | The ARNs of the IAM users/roles that have read access to the repository. (Comma separated list)' | | `aws_ecr_repo_write_arn` | String | The ARNs of the IAM users/roles that have read/write access to the repository. (Comma separated list)' | +| `aws_ecr_repo_read_external_aws_account`| String | Comma separated list of AWS Accounts IDs that will be provided with read access to the registry. | +| `aws_ecr_repo_write_external_aws_account`| String | Comma separated list of AWS Accounts IDs that will be provided with write access to the registry. | | `aws_ecr_repo_read_arn_lambda` | String | The ARNs of the Lambda service roles that have read access to the repository. (Comma separated list)' | | `aws_ecr_lifecycle_policy_input` | JSON | The policy document. This is a JSON formatted string. See more details about [Policy Parameters](http://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html#lifecycle_policy_parameters) in the official AWS docs' | | `aws_ecr_public_repo_catalog` | String | Catalog data configuration for the repository. Defaults to `{}`.' | diff --git a/action.yaml b/action.yaml index 43a8ef145..7caf8b74d 100644 --- a/action.yaml +++ b/action.yaml @@ -987,6 +987,12 @@ inputs: aws_ecr_repo_write_arn: description: 'The ARNs of the IAM users/roles that have read/write access to the repository. (Comma separated list)' required: false + aws_ecr_repo_read_external_aws_account: + description: 'The ARNs of the external AWS accounts that have read access to the repository' + required: false + aws_ecr_repo_write_external_aws_account: + description: 'The ARNs of the external AWS accounts that have write access to the repository' + required: false aws_ecr_repo_read_arn_lambda: description: 'The ARNs of the Lambda service roles that have read access to the repository. (Comma separated list)' required: false @@ -1547,6 +1553,8 @@ runs: AWS_ECR_REPO_POLICY_INPUT: ${{ inputs.aws_ecr_repo_policy_input }} AWS_ECR_REPO_READ_ARN: ${{ inputs.aws_ecr_repo_read_arn }} AWS_ECR_REPO_WRITE_ARN: ${{ inputs.aws_ecr_repo_write_arn }} + AWS_ECR_REPO_READ_EXTERNAL_AWS_ACCOUNT: ${{ inputs.aws_ecr_repo_read_external_aws_account }} + AWS_ECR_REPO_WRITE_EXTERNAL_AWS_ACCOUNT: ${{ inputs.aws_ecr_repo_write_external_aws_account }} AWS_ECR_REPO_READ_ARN_LAMBDA: ${{ inputs.aws_ecr_repo_read_arn_lambda }} AWS_ECR_LIFECYCLE_POLICY_INPUT: ${{ inputs.aws_ecr_lifecycle_policy_input }} AWS_ECR_PUBLIC_REPO_CATALOG: ${{ inputs.aws_ecr_public_repo_catalog }} diff --git a/operations/_scripts/generate/generate_vars_terraform.sh b/operations/_scripts/generate/generate_vars_terraform.sh index 048907222..f36fd40e2 100644 --- a/operations/_scripts/generate/generate_vars_terraform.sh +++ b/operations/_scripts/generate/generate_vars_terraform.sh @@ -381,6 +381,8 @@ if [[ $(alpha_only "$AWS_ECR_REPO_CREATE") == true ]]; then aws_ecr_repo_policy_input=$(generate_var aws_ecr_repo_policy_input $AWS_ECR_REPO_POLICY_INPUT) aws_ecr_repo_read_arn=$(generate_var aws_ecr_repo_read_arn $AWS_ECR_REPO_READ_ARN) aws_ecr_repo_write_arn=$(generate_var aws_ecr_repo_write_arn $AWS_ECR_REPO_WRITE_ARN) + aws_ecr_repo_read_external_aws_account=$(generate_var aws_ecr_repo_read_external_aws_account $AWS_ECR_REPO_READ_EXTERNAL_AWS_ACCOUNT) + aws_ecr_repo_write_external_aws_account=$(generate_var aws_ecr_repo_write_external_aws_account $AWS_ECR_REPO_WRITE_EXTERNAL_AWS_ACCOUNT) aws_ecr_repo_read_arn_lambda=$(generate_var aws_ecr_repo_read_arn_lambda $AWS_ECR_REPO_READ_ARN_LAMBDA) aws_ecr_lifecycle_policy_input=$(generate_var aws_ecr_lifecycle_policy_input $AWS_ECR_LIFECYCLE_POLICY_INPUT) aws_ecr_public_repo_catalog=$(generate_var aws_ecr_public_repo_catalog $AWS_ECR_PUBLIC_REPO_CATALOG) @@ -743,6 +745,8 @@ $aws_ecr_repo_policy_create $aws_ecr_repo_policy_input $aws_ecr_repo_read_arn $aws_ecr_repo_write_arn +$aws_ecr_repo_read_external_aws_account +$aws_ecr_repo_write_external_aws_account $aws_ecr_repo_read_arn_lambda $aws_ecr_lifecycle_policy_input $aws_ecr_public_repo_catalog diff --git a/operations/deployment/terraform/aws/aws_variables.tf b/operations/deployment/terraform/aws/aws_variables.tf index adac2be2b..2071fbd43 100644 --- a/operations/deployment/terraform/aws/aws_variables.tf +++ b/operations/deployment/terraform/aws/aws_variables.tf @@ -1718,6 +1718,18 @@ variable "aws_ecr_lifecycle_policy_input" { default = "" } +variable "aws_ecr_repo_read_external_aws_account" { + description = "The ARNs of the external AWS accounts that have read access to the repository" + type = string + default = "" +} + +variable "aws_ecr_repo_write_external_aws_account" { + description = "The ARNs of the external AWS accounts that have write access to the repository" + type = string + default = "" +} + variable "aws_ecr_public_repo_catalog" { description = "Catalog data configuration for the repository" type = any diff --git a/operations/deployment/terraform/aws/bitovi_main.tf b/operations/deployment/terraform/aws/bitovi_main.tf index eceb99ff1..cfaa57986 100644 --- a/operations/deployment/terraform/aws/bitovi_main.tf +++ b/operations/deployment/terraform/aws/bitovi_main.tf @@ -600,6 +600,8 @@ module "aws_ecr" { aws_ecr_repo_policy_input = var.aws_ecr_repo_policy_input aws_ecr_repo_read_arn = var.aws_ecr_repo_read_arn aws_ecr_repo_write_arn = var.aws_ecr_repo_write_arn + aws_ecr_repo_read_external_aws_account = var.aws_ecr_repo_read_external_aws_account + aws_ecr_repo_write_external_aws_account = var.aws_ecr_repo_write_external_aws_account aws_ecr_repo_read_arn_lambda = var.aws_ecr_repo_read_arn_lambda aws_ecr_lifecycle_policy_input = var.aws_ecr_lifecycle_policy_input aws_ecr_public_repo_catalog = var.aws_ecr_public_repo_catalog diff --git a/operations/deployment/terraform/modules/aws/ecr/aws_ecr_policies.tf b/operations/deployment/terraform/modules/aws/ecr/aws_ecr_policies.tf index 44105d1f4..a11f557cb 100644 --- a/operations/deployment/terraform/modules/aws/ecr/aws_ecr_policies.tf +++ b/operations/deployment/terraform/modules/aws/ecr/aws_ecr_policies.tf @@ -5,6 +5,8 @@ locals { aws_ecr_repo_read_arn = var.aws_ecr_repo_read_arn != "" ? [for n in split(",", var.aws_ecr_repo_read_arn) : (n)] : [] aws_ecr_repo_write_arn = var.aws_ecr_repo_write_arn != "" ? [for n in split(",", var.aws_ecr_repo_write_arn) : (n)] : [] aws_ecr_repo_read_arn_lambda = var.aws_ecr_repo_read_arn_lambda != "" ? [for n in split(",", var.aws_ecr_repo_read_arn_lambda) : (n)] : [] + aws_ecr_repo_read_external_aws_account = var.aws_ecr_repo_read_external_aws_account != "" ? [for n in split(",", var.aws_ecr_repo_read_external_aws_account) : "arn:${data.aws_partition.current.partition}:iam::${n}:root"] : [] + aws_ecr_repo_write_external_aws_account = var.aws_ecr_repo_write_external_aws_account != "" ? [for n in split(",", var.aws_ecr_repo_write_external_aws_account) : "arn:${data.aws_partition.current.partition}:iam::${n}:root"] : [] } # Policy used by both private and public repositories @@ -129,4 +131,85 @@ data "aws_iam_policy_document" "repository" { ] } } + + dynamic "statement" { + for_each = length(local.aws_ecr_repo_write_arn) > 0 && var.aws_ecr_repo_type == "public" ? [local.aws_ecr_repo_write_arn] : [] + + content { + sid = "ReadWrite" + + principals { + type = "AWS" + identifiers = statement.value + } + + actions = [ + "ecr-public:BatchCheckLayerAvload", + "ecr-public:CompleteLayerUpload", + "ecr-public:InitiateLayerUpload", + "ecr-public:PutImage", + "ecr-public:UploadLayerPart", + ] + } + } + + dynamic "statement" { + for_each = length(local.aws_ecr_repo_read_external_aws_account) > 0 && var.aws_ecr_repo_type == "private" ? [local.aws_ecr_repo_read_external_aws_account] : [] + + content { + sid = "ExternalAccountReadOnly" + + principals { + type = "AWS" + identifiers = statement.value + } + + actions = [ + "ecr:GetAuthorizationToken", + "ecr:BatchCheckLayerAvailability", + "ecr:BatchGetImage", + "ecr:DescribeImageScanFindings", + "ecr:DescribeImages", + "ecr:DescribeRepositories", + "ecr:GetDownloadUrlForLayer", + "ecr:GetLifecyclePolicy", + "ecr:GetLifecyclePolicyPreview", + "ecr:GetRepositoryPolicy", + "ecr:ListImages", + "ecr:ListTagsForResource", + ] + } + } + + dynamic "statement" { + for_each = length(local.aws_ecr_repo_write_external_aws_account) > 0 && var.aws_ecr_repo_type == "private" ? [local.aws_ecr_repo_write_external_aws_account] : [] + + content { + sid = "ExternalAccountReadWrite" + + principals { + type = "AWS" + identifiers = statement.value + } + + actions = [ + "ecr:GetAuthorizationToken", + "ecr:BatchCheckLayerAvailability", + "ecr:BatchGetImage", + "ecr:DescribeImageScanFindings", + "ecr:DescribeImages", + "ecr:DescribeRepositories", + "ecr:GetDownloadUrlForLayer", + "ecr:GetLifecyclePolicy", + "ecr:GetLifecyclePolicyPreview", + "ecr:GetRepositoryPolicy", + "ecr:ListImages", + "ecr:ListTagsForResource", + "ecr:PutImage", + "ecr:InitiateLayerUpload", + "ecr:UploadLayerPart", + "ecr:CompleteLayerUpload", + ] + } + } } \ No newline at end of file diff --git a/operations/deployment/terraform/modules/aws/ecr/aws_ecr_vars.tf b/operations/deployment/terraform/modules/aws/ecr/aws_ecr_vars.tf index 100ed3fa5..33c24667d 100644 --- a/operations/deployment/terraform/modules/aws/ecr/aws_ecr_vars.tf +++ b/operations/deployment/terraform/modules/aws/ecr/aws_ecr_vars.tf @@ -15,6 +15,8 @@ variable "aws_ecr_repo_policy_create" {} variable "aws_ecr_repo_policy_input" {} variable "aws_ecr_repo_read_arn" {} variable "aws_ecr_repo_write_arn" {} +variable "aws_ecr_repo_read_external_aws_account" {} +variable "aws_ecr_repo_write_external_aws_account" {} variable "aws_ecr_repo_read_arn_lambda" {} variable "aws_ecr_lifecycle_policy_input" {} variable "aws_ecr_public_repo_catalog" {}