diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 2537f2f..6f64b5a 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -15,8 +15,8 @@
# Cloud Posse must review any changes to standard context definition,
# but some changes can be rubber-stamped.
-**/*.tf @cloudposse/engineering @cloudposse/approvers
-README.yaml @cloudposse/engineering @cloudposse/approvers
+**/*.tf @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers
+README.yaml @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers
README.md @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers
docs/*.md @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers
diff --git a/.github/auto-release.yml b/.github/auto-release.yml
index c78a4d8..b45efb7 100644
--- a/.github/auto-release.yml
+++ b/.github/auto-release.yml
@@ -17,6 +17,7 @@ version-resolver:
- 'bugfix'
- 'bug'
- 'hotfix'
+ - 'no-release'
default: 'minor'
categories:
@@ -46,7 +47,7 @@ template: |
replacers:
# Remove irrelevant information from Renovate bot
-- search: '/---\s+^#.*Renovate configuration(?:.|\n)*?This PR has been generated .*/gm'
+- search: '/(?<=---\s)\s*^#.*(Renovate configuration|Configuration)(?:.|\n)*?This PR has been generated .*/gm'
replace: ''
# Remove Renovate bot banner image
- search: '/\[!\[[^\]]*Renovate\][^\]]*\](\([^)]*\))?\s*\n+/gm'
diff --git a/.github/mergify.yml b/.github/mergify.yml
index b010656..ef15545 100644
--- a/.github/mergify.yml
+++ b/.github/mergify.yml
@@ -56,3 +56,10 @@ pull_request_rules:
changes_requested: true
approved: true
message: "This Pull Request has been updated, so we're dismissing all reviews."
+
+- name: "close Pull Requests without files changed"
+ conditions:
+ - "#files=0"
+ actions:
+ close:
+ message: "This pull request has been automatically closed by Mergify because there are no longer any changes."
diff --git a/.github/workflows/auto-context.yml b/.github/workflows/auto-context.yml
index ab979e0..665833a 100644
--- a/.github/workflows/auto-context.yml
+++ b/.github/workflows/auto-context.yml
@@ -35,7 +35,7 @@ jobs:
- name: Create Pull Request
if: steps.update.outputs.create_pull_request == 'true'
- uses: cloudposse/actions/github/create-pull-request@0.22.0
+ uses: cloudposse/actions/github/create-pull-request@0.30.0
with:
token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
committer: 'cloudpossebot <11232728+cloudpossebot@users.noreply.github.com>'
diff --git a/.github/workflows/auto-format.yml b/.github/workflows/auto-format.yml
index 990abed..c600d60 100644
--- a/.github/workflows/auto-format.yml
+++ b/.github/workflows/auto-format.yml
@@ -6,7 +6,7 @@ on:
jobs:
auto-format:
runs-on: ubuntu-latest
- container: cloudposse/build-harness:slim-latest
+ container: cloudposse/build-harness:latest
steps:
# Checkout the pull request branch
# "An action in a workflow run can’t trigger a new workflow run. For example, if an action pushes code using
@@ -29,6 +29,8 @@ jobs:
- name: Auto Format
if: github.event.pull_request.state == 'open'
shell: bash
+ env:
+ GITHUB_TOKEN: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}"
run: make BUILD_HARNESS_PATH=/build-harness PACKAGES_PREFER_HOST=true -f /build-harness/templates/Makefile.build-harness pr/auto-format/host
# Commit changes (if any) to the PR branch
@@ -60,7 +62,7 @@ jobs:
fi
- name: Auto Test
- uses: cloudposse/actions/github/repository-dispatch@0.22.0
+ uses: cloudposse/actions/github/repository-dispatch@0.30.0
# match users by ID because logins (user names) are inconsistent,
# for example in the REST API Renovate Bot is `renovate[bot]` but
# in GraphQL it is just `renovate`, plus there is a non-bot
diff --git a/.github/workflows/auto-readme.yml b/.github/workflows/auto-readme.yml
new file mode 100644
index 0000000..6f25b8d
--- /dev/null
+++ b/.github/workflows/auto-readme.yml
@@ -0,0 +1,71 @@
+name: "auto-readme"
+on:
+ workflow_dispatch:
+
+ schedule:
+ # Example of job definition:
+ # .---------------- minute (0 - 59)
+ # | .------------- hour (0 - 23)
+ # | | .---------- day of month (1 - 31)
+ # | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
+ # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
+ # | | | | |
+ # * * * * * user-name command to be executed
+
+ # Update README.md nightly at 4am UTC
+ - cron: '0 4 * * *'
+
+jobs:
+ update:
+ if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Find default branch name
+ id: defaultBranch
+ shell: bash
+ env:
+ GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+ run: |
+ default_branch=$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)
+ printf "::set-output name=defaultBranch::%s\n" "${default_branch}"
+ printf "defaultBranchRef.name=%s\n" "${default_branch}"
+
+ - name: Update readme
+ shell: bash
+ id: update
+ env:
+ GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+ DEF: "${{ steps.defaultBranch.outputs.defaultBranch }}"
+ run: |
+ make init
+ make readme/build
+ # Ignore changes if they are only whitespace
+ if ! git diff --quiet README.md && git diff --ignore-all-space --ignore-blank-lines --quiet README.md; then
+ git restore README.md
+ echo Ignoring whitespace-only changes in README
+ fi
+
+ - name: Create Pull Request
+ # This action will not create or change a pull request if there are no changes to make.
+ # If a PR of the auto-update/readme branch is open, this action will just update it, not create a new PR.
+ uses: cloudposse/actions/github/create-pull-request@0.30.0
+ with:
+ token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
+ commit-message: Update README.md and docs
+ title: Update README.md and docs
+ body: |-
+ ## what
+ This is an auto-generated PR that updates the README.md and docs
+
+ ## why
+ To have most recent changes of README.md and doc from origin templates
+
+ branch: auto-update/readme
+ base: ${{ steps.defaultBranch.outputs.defaultBranch }}
+ delete-branch: true
+ labels: |
+ auto-update
+ no-release
+ readme
diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml
index 3f48017..3a38fae 100644
--- a/.github/workflows/auto-release.yml
+++ b/.github/workflows/auto-release.yml
@@ -3,17 +3,24 @@ name: auto-release
on:
push:
branches:
- - master
+ - main
+ - master
+ - production
jobs:
publish:
runs-on: ubuntu-latest
steps:
- # Drafts your next Release notes as Pull Requests are merged into "master"
- - uses: release-drafter/release-drafter@v5
- with:
- publish: true
- prerelease: false
- config-name: auto-release.yml
- env:
- GITHUB_TOKEN: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
+ # Get PR from merged commit to master
+ - uses: actions-ecosystem/action-get-merged-pull-request@v1
+ id: get-merged-pull-request
+ with:
+ github_token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
+ # Drafts your next Release notes as Pull Requests are merged into "main"
+ - uses: release-drafter/release-drafter@v5
+ with:
+ publish: ${{ !contains(steps.get-merged-pull-request.outputs.labels, 'no-release') }}
+ prerelease: false
+ config-name: auto-release.yml
+ env:
+ GITHUB_TOKEN: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
diff --git a/.github/workflows/chatops.yml b/.github/workflows/chatops.yml
index 4ddc067..23f96d8 100644
--- a/.github/workflows/chatops.yml
+++ b/.github/workflows/chatops.yml
@@ -9,7 +9,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: "Handle common commands"
- uses: cloudposse/actions/github/slash-command-dispatch@0.22.0
+ uses: cloudposse/actions/github/slash-command-dispatch@0.30.0
with:
token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
reaction-token: ${{ secrets.GITHUB_TOKEN }}
@@ -24,7 +24,7 @@ jobs:
- name: "Checkout commit"
uses: actions/checkout@v2
- name: "Run tests"
- uses: cloudposse/actions/github/slash-command-dispatch@0.22.0
+ uses: cloudposse/actions/github/slash-command-dispatch@0.30.0
with:
token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
reaction-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/validate-codeowners.yml b/.github/workflows/validate-codeowners.yml
index 386eb28..70f829e 100644
--- a/.github/workflows/validate-codeowners.yml
+++ b/.github/workflows/validate-codeowners.yml
@@ -1,5 +1,7 @@
name: Validate Codeowners
on:
+ workflow_dispatch:
+
pull_request:
jobs:
@@ -8,7 +10,7 @@ jobs:
steps:
- name: "Checkout source code at current commit"
uses: actions/checkout@v2
- - uses: mszostok/codeowners-validator@v0.5.0
+ - uses: mszostok/codeowners-validator@v0.7.1
if: github.event.pull_request.head.repo.full_name == github.repository
name: "Full check of CODEOWNERS"
with:
@@ -16,10 +18,12 @@ jobs:
# files so we can use the same CODEOWNERS file for Terraform and non-Terraform repos
# checks: "files,syntax,owners,duppatterns"
checks: "syntax,owners,duppatterns"
+ owner_checker_allow_unowned_patterns: "false"
# GitHub access token is required only if the `owners` check is enabled
github_access_token: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}"
- - uses: mszostok/codeowners-validator@v0.5.0
+ - uses: mszostok/codeowners-validator@v0.7.1
if: github.event.pull_request.head.repo.full_name != github.repository
name: "Syntax check of CODEOWNERS"
with:
checks: "syntax,duppatterns"
+ owner_checker_allow_unowned_patterns: "false"
diff --git a/README.md b/README.md
index e033fe4..4f43a76 100644
--- a/README.md
+++ b/README.md
@@ -179,6 +179,7 @@ Available targets:
| [aws_iam_policy_document.resource](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.resource_full_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.resource_readonly_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
## Inputs
@@ -204,6 +205,7 @@ Available targets:
| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no |
| [principals\_full\_access](#input\_principals\_full\_access) | Principal ARNs to provide with full access to the ECR | `list(string)` | `[]` | no |
+| [principals\_lambda](#input\_principals\_lambda) | Principal account IDs of Lambdas allowed to consume ECR | `list(string)` | `[]` | no |
| [principals\_readonly\_access](#input\_principals\_readonly\_access) | Principal ARNs to provide with readonly access to the ECR | `list(string)` | `[]` | no |
| [protected\_tags](#input\_protected\_tags) | Name of image tags prefixes that should not be destroyed. Useful if you tag images with names like `dev`, `staging`, and `prod` | `set(string)` | `[]` | no |
| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
@@ -313,7 +315,7 @@ In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow.
## Copyright
-Copyright © 2017-2021 [Cloud Posse, LLC](https://cpco.io/copyright)
+Copyright © 2017-2022 [Cloud Posse, LLC](https://cpco.io/copyright)
diff --git a/docs/terraform.md b/docs/terraform.md
index 9b17c9f..d68fcf0 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -29,6 +29,7 @@
| [aws_iam_policy_document.resource](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.resource_full_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.resource_readonly_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
## Inputs
@@ -54,6 +55,7 @@
| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
| [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no |
| [principals\_full\_access](#input\_principals\_full\_access) | Principal ARNs to provide with full access to the ECR | `list(string)` | `[]` | no |
+| [principals\_lambda](#input\_principals\_lambda) | Principal account IDs of Lambdas allowed to consume ECR | `list(string)` | `[]` | no |
| [principals\_readonly\_access](#input\_principals\_readonly\_access) | Principal ARNs to provide with readonly access to the ECR | `list(string)` | `[]` | no |
| [protected\_tags](#input\_protected\_tags) | Name of image tags prefixes that should not be destroyed. Useful if you tag images with names like `dev`, `staging`, and `prod` | `set(string)` | `[]` | no |
| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
diff --git a/main.tf b/main.tf
index 88bddf3..9eac756 100755
--- a/main.tf
+++ b/main.tf
@@ -87,6 +87,8 @@ data "aws_iam_policy_document" "empty" {
count = module.this.enabled ? 1 : 0
}
+data "aws_partition" "current" {}
+
data "aws_iam_policy_document" "resource_readonly_access" {
count = module.this.enabled ? 1 : 0
@@ -114,6 +116,50 @@ data "aws_iam_policy_document" "resource_readonly_access" {
"ecr:ListTagsForResource",
]
}
+
+ dynamic "statement" {
+ for_each = length(var.principals_lambda) > 0 ? [1] : []
+
+ content {
+ sid = "LambdaECRImageCrossAccountRetrievalPolicy"
+ effect = "Allow"
+ actions = [
+ "ecr:BatchGetImage",
+ "ecr:GetDownloadUrlForLayer"
+ ]
+
+ principals {
+ type = "Service"
+ identifiers = ["lambda.amazonaws.com"]
+ }
+
+ condition {
+ test = "StringLike"
+ values = formatlist("arn:%s:lambda:*:%s:function:*", data.aws_partition.current.partition, var.principals_lambda)
+ variable = "aws:sourceArn"
+ }
+ }
+ }
+
+ dynamic "statement" {
+ for_each = length(var.principals_lambda) > 0 ? [1] : []
+ content {
+ sid = "CrossAccountPermission"
+ effect = "Allow"
+
+ principals {
+ type = "AWS"
+
+ identifiers = formatlist("arn:%s:iam::%s:root", data.aws_partition.current.partition, var.principals_lambda)
+ }
+
+ actions = [
+ "ecr:BatchGetImage",
+ "ecr:GetDownloadUrlForLayer"
+ ]
+ }
+ }
+
}
data "aws_iam_policy_document" "resource_full_access" {
@@ -131,6 +177,49 @@ data "aws_iam_policy_document" "resource_full_access" {
actions = ["ecr:*"]
}
+
+ dynamic "statement" {
+ for_each = length(var.principals_lambda) > 0 ? [1] : []
+
+ content {
+ sid = "LambdaECRImageCrossAccountRetrievalPolicy"
+ effect = "Allow"
+ actions = [
+ "ecr:BatchGetImage",
+ "ecr:GetDownloadUrlForLayer"
+ ]
+
+ principals {
+ type = "Service"
+ identifiers = ["lambda.amazonaws.com"]
+ }
+
+ condition {
+ test = "StringLike"
+ values = formatlist("arn:%s:lambda:*:%s:function:*", data.aws_partition.current.partition, var.principals_lambda)
+ variable = "aws:sourceArn"
+ }
+ }
+ }
+
+ dynamic "statement" {
+ for_each = length(var.principals_lambda) > 0 ? [1] : []
+ content {
+ sid = "CrossAccountPermission"
+ effect = "Allow"
+
+ principals {
+ type = "AWS"
+
+ identifiers = formatlist("arn:%s:iam::%s:root", data.aws_partition.current.partition, var.principals_lambda)
+ }
+
+ actions = [
+ "ecr:BatchGetImage",
+ "ecr:GetDownloadUrlForLayer"
+ ]
+ }
+ }
}
data "aws_iam_policy_document" "resource" {
diff --git a/variables.tf b/variables.tf
index 0189c3b..4287f47 100755
--- a/variables.tf
+++ b/variables.tf
@@ -16,6 +16,12 @@ variable "principals_readonly_access" {
default = []
}
+variable "principals_lambda" {
+ type = list(string)
+ description = "Principal account IDs of Lambdas allowed to consume ECR"
+ default = []
+}
+
variable "scan_images_on_push" {
type = bool
description = "Indicates whether images are scanned after being pushed to the repository (true) or not (false)"