diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c17562c..3cefc06 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - - repo: git://github.com/antonbabenko/pre-commit-terraform - rev: v1.58.0 + - repo: https://github.com/antonbabenko/pre-commit-terraform + rev: v1.62.3 hooks: - id: terraform_fmt - id: terraform_validate @@ -21,7 +21,7 @@ repos: - '--args=--only=terraform_required_providers' - '--args=--only=terraform_standard_module_structure' - '--args=--only=terraform_workspace_remote' - - repo: git://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.1.0 hooks: - id: check-merge-conflict diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index b188f77..ad2d5f3 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -1,42 +1,22 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. -provider "registry.terraform.io/hashicorp/external" { - version = "2.1.0" - constraints = ">= 2.1.0" - hashes = [ - "h1:LTl5CGW8wiIEe16AC4MtXN/95xWWNDbap70zJsBTk0w=", - "h1:wbtDfLeawmv6xVT1W0w0fctRCb4ABlaD3JTxwb1jXag=", - "zh:0d83ffb72fbd08986378204a7373d8c43b127049096eaf2765bfdd6b00ad9853", - "zh:7577d6edc67b1e8c2cf62fe6501192df1231d74125d90e51d570d586d95269c5", - "zh:9c669ded5d5affa4b2544952c4b6588dfed55260147d24ced02dca3a2829f328", - "zh:a404d46f2831f90633947ab5d57e19dbfe35b3704104ba6ec80bcf50b058acfd", - "zh:ae1caea1c936d459ceadf287bb5c5bd67b5e2a7819df6f5c4114b7305df7f822", - "zh:afb4f805477694a4b9dde86b268d2c0821711c8aab1c6088f5f992228c4c06fb", - "zh:b993b4a1de8a462643e78f4786789e44ce5064b332fee1cb0d6250ed085561b8", - "zh:c84b2c13fa3ea2c0aa7291243006d560ce480a5591294b9001ce3742fc9c5791", - "zh:c8966f69b7eccccb771704fd5335923692eccc9e0e90cb95d14538fe2e92a3b8", - "zh:d5fe68850d449b811e633a300b114d0617df6d450305e8251643b4d143dc855b", - "zh:ddebfd1e674ba336df09b1f27bbaa0e036c25b7a7087dc8081443f6e5954028b", - ] -} - provider "registry.terraform.io/hashicorp/google" { - version = "4.1.0" + version = "4.6.0" constraints = ">= 4.1.0" hashes = [ - "h1:eqp/ZZ0N2tF0ZSaAUdS6b5TLSZKPegmFLqEFid89V9k=", - "h1:oXcSMwbjSCr0PO2PyZbKPbPXnd4EhxdJGZQwtzQqwrM=", - "zh:3477415ef4ef02d7c065a08fb24b7011ddd77f76b2a011db25e0b73c767acaae", - "zh:43be16d0bbb56d29c090c1abe49e877e4f3ca66bb372a661a2cd0a377cd61e8f", - "zh:6bb202a40055ed302f9dd05e2f3f87aa13080e580a9ac7b0241d634b78b68a2a", - "zh:7179303f628c5fc58129013ef4a4e754e225e266e68af4a7167a06a64d9d97db", - "zh:837cdcf1bafd4c936f15a4a22353efeec96ca23727f8d8ff22e9d53414d87084", - "zh:a853f1a1e9f5ac261fd9a02d869ce7da16917fdd16464dabf2200e2ccd04fba9", - "zh:aba631b9db47cc34857c25459475f17d939a46022f886e396a8254588f720c58", - "zh:ac461358984ba480b4fef1d2be3538d9714aa8814a6f420e1e954227054a14a4", - "zh:ade64689485fc28b6aa0c36861c6c9c66b5d7a8e7282739ecf97c7791b973312", - "zh:c3fbbfe7f6e870e19bb552a2ad84ea38c9ddf3e25e0b7e996ecb2fc7ce336b03", - "zh:d1419f4fe9c07f136ee9015a299cd6acf25a13bea0afa0f69727a576058603d3", + "h1:QbO4yjDrnoSpiYKSHrICNL1ZuWsl5J2rVRFj2kNg7xA=", + "h1:uGcZfOySgiqtYDw0eQXgmdzMDZrsuRXhmzNJYxJbgcc=", + "zh:005a28a2c79f6b29680b0f57260c69c85d8a992688007b6e5645149bd379951f", + "zh:2604d825de72cf99b4899d7880837adeb19d371f48e419666e32c4c3cf6a72e9", + "zh:290da4eb18e44469480cf299bebce89f54e4d301f856cdffe2837b498878c7ec", + "zh:3e5ba1a55d38fa17533a18fc14a612e781ded76c6309734d3dc0a937be27eec1", + "zh:4a85de3cdb33c092d8ccfced3d7302934de0dd4f72bbcebd79d45afe0a0b6f85", + "zh:5fb1a79800833ae922aaba594a8b2bc83be1d254052e12e0ce8330ca0d8933d9", + "zh:679b9f50c6fe0476e74d37935f7598d46d6e9612f75b26a8ef1ca3c13144d06a", + "zh:893216e32378839668c51ef135af1676cd887d63e2edb6625cf9adad7bfa346f", + "zh:ad8f2fd19adbe4c10281ba9b3c8d5100877a9c541d3580bbbe9357714aa77619", + "zh:bff5d6fd15e98c12ee9ed98b0338761dc4a9ba671a37834926daeabf73c71783", + "zh:debdf15fbed8d63e397cd004bf65586bd2b93ce04e47ca51a7c70c1fe9168b87", ] } diff --git a/README.md b/README.md index 694ae97..df26c25 100644 --- a/README.md +++ b/README.md @@ -71,23 +71,10 @@ module "gcr_cleaner" { project_id = "yet-another-project-id" clean_all = true parameters = { - allow_tagged = true - keep = 5 - grace = "120h" - tag_filter = "^beta.+$" + keep = 5 + grace = "120h" + tag_filter_all = "^beta.+$" } - }, - { - project_id = "automation-project-id" - repositories = [ - { - # in `test/tools/ci` repository and all its child repositories, keep only 5 tags - name = "test/tools/ci" - allow_tagged = true - keep = 5 - recursive = true - } - ] } ] } @@ -110,7 +97,7 @@ module "gcr_cleaner" { | Name | Version | |------|---------| -| [google](#provider\_google) | 4.1.0 | +| [google](#provider\_google) | 4.6.0 | ## Modules @@ -152,7 +139,7 @@ No modules. | [disable\_dependent\_services](#input\_disable\_dependent\_services) | If `true`, services that are enabled and which depend on this service should also be disabled when this service is destroyed. If `false` or unset, an error will be generated if any enabled services depend on this service when destroying it. | `bool` | `false` | no | | [disable\_on\_destroy](#input\_disable\_on\_destroy) | If `true`, disable the service when the terraform resource is destroyed. May be useful in the event that a project is long-lived but the infrastructure running in that project changes frequently. | `bool` | `false` | no | | [gcr\_cleaner\_image](#input\_gcr\_cleaner\_image) | The docker image of the gcr cleaner to deploy to Cloud Run. | `string` | `"gcr.io/gcr-cleaner/gcr-cleaner:latest"` | no | -| [gcr\_repositories](#input\_gcr\_repositories) | List of Google Container Registries objects to create:
list(object({
project_id = Value of the Google project id, if ommited, it will be assigned `google_project_id` variable value (optional(string))
storage_region = Location of the storage bucket (optional(string))
repositories = Docker image repositories to clean (optional(list(object({
name = Name of the repository (string)
grace = Relative duration in which to ignore references. This value is specified as a time duration value like "5s" or "3h". If set, refs newer than the duration will not be deleted. If unspecified, the default is no grace period (all untagged image refs are deleted) (optional(string))
allow_tagged = If set to true, will check all images including tagged. If unspecified, the default will only delete untagged images (optional(bool))
keep = If an integer is provided, it will always keep that minimum number of images. Note that it will not consider images inside the `grace` duration (optional(string))
tag_filter = Used for tags regexp definition to define pattern to clean, requires `allow_tagged` must be true. For example: use `"^dev.+$"` to limit cleaning only on the tags with beginning with is `dev`. The default is no filtering (optional(string))
recursive = If set to true, will recursively search all child repositories (optional(bool))
}))))
clean_all = Set to `true` to clean all project's repositories (optional(bool))
parameters = Map of parameters to apply to all repositories when `clean_all` is set to `true` (optional(object({
grace = Relative duration in which to ignore references. This value is specified as a time duration value like "5s" or "3h". If set, refs newer than the duration will not be deleted. If unspecified, the default is no grace period (all untagged image refs are deleted) (optional(string))
allow_tagged = If set to true, will check all images including tagged. If unspecified, the default will only delete untagged images (optional(bool))
keep = If an integer is provided, it will always keep that minimum number of images. Note that it will not consider images inside the `grace` duration (optional(string))
tag_filter = Used for tags regexp definition to define pattern to clean, requires `allow_tagged` must be true. For example: use `"^dev.+$"` to limit cleaning only on the tags with beginning with is `dev`. The default is no filtering (optional(string))
})))
}))
|
list(object({
project_id = optional(string)
storage_region = optional(string)
repositories = optional(list(object({
name = string
grace = optional(string)
allow_tagged = optional(bool)
keep = optional(string)
tag_filter = optional(string)
recursive = optional(bool)
})))
clean_all = optional(bool)
parameters = optional(object({
grace = optional(string)
allow_tagged = optional(bool)
keep = optional(string)
tag_filter = optional(string)
}))
}))
| `[]` | no | +| [gcr\_repositories](#input\_gcr\_repositories) | List of Google Container Registries objects to create:
list(object({
project_id = Value of the Google project id, if ommited, it will be assigned `google_project_id` variable value (optional(string))
storage_region = Location of the storage bucket (optional(string))
repositories = Docker image repositories to clean (optional(list(object({
name = Name of the repository (string)
grace = Relative duration in which to ignore references. This value is specified as a time duration value like "5s" or "3h". If set, refs newer than the duration will not be deleted. If unspecified, the default is no grace period (all untagged image refs are deleted) (optional(string))
keep = If an integer is provided, it will always keep that minimum number of images. Note that it will not consider images inside the `grace` duration (optional(string))
tag_filter = (Deprecated) If specified, any image where the first tag matches this given regular expression will be deleted. The image will not be deleted if other tags match the regular expression (optional(string))
tag_filter_any = If specified, any image with at least one tag that matches this given regular expression will be deleted. The image will be deleted even if it has other tags that do not match the given regular expression (optional(string))
tag_filter_all = If specified, any image where all tags match this given regular expression will be deleted. The image will not be delete if it has other tags that do not match the given regular expression (optional(string))
recursive = If set to true, will recursively search all child repositories (optional(bool))
}))))
clean_all = Set to `true` to clean all project's repositories (optional(bool))
parameters = Map of parameters to apply to all repositories when `clean_all` is set to `true` (optional(object({
grace = Relative duration in which to ignore references. This value is specified as a time duration value like "5s" or "3h". If set, refs newer than the duration will not be deleted. If unspecified, the default is no grace period (all untagged image refs are deleted) (optional(string))
keep = If an integer is provided, it will always keep that minimum number of images. Note that it will not consider images inside the `grace` duration (optional(string))
tag_filter = (Deprecated) If specified, any image where the first tag matches this given regular expression will be deleted. The image will not be deleted if other tags match the regular expression (optional(string))
tag_filter_any = If specified, any image with at least one tag that matches this given regular expression will be deleted. The image will be deleted even if it has other tags that do not match the given regular expression (optional(string))
tag_filter_all = If specified, any image where all tags match this given regular expression will be deleted. The image will not be delete if it has other tags that do not match the given regular expression (optional(string))
})))
}))
|
list(object({
project_id = optional(string)
storage_region = optional(string)
repositories = optional(list(object({
name = string
grace = optional(string)
keep = optional(string)
tag_filter = optional(string)
tag_filter_any = optional(string)
tag_filter_all = optional(string)
recursive = optional(bool)
})))
clean_all = optional(bool)
parameters = optional(object({
grace = optional(string)
keep = optional(string)
tag_filter = optional(string)
tag_filter_any = optional(string)
tag_filter_all = optional(string)
}))
}))
| `[]` | no | ## Outputs diff --git a/examples/complete/.terraform.lock.hcl b/examples/complete/.terraform.lock.hcl index b188f77..ad2d5f3 100644 --- a/examples/complete/.terraform.lock.hcl +++ b/examples/complete/.terraform.lock.hcl @@ -1,42 +1,22 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. -provider "registry.terraform.io/hashicorp/external" { - version = "2.1.0" - constraints = ">= 2.1.0" - hashes = [ - "h1:LTl5CGW8wiIEe16AC4MtXN/95xWWNDbap70zJsBTk0w=", - "h1:wbtDfLeawmv6xVT1W0w0fctRCb4ABlaD3JTxwb1jXag=", - "zh:0d83ffb72fbd08986378204a7373d8c43b127049096eaf2765bfdd6b00ad9853", - "zh:7577d6edc67b1e8c2cf62fe6501192df1231d74125d90e51d570d586d95269c5", - "zh:9c669ded5d5affa4b2544952c4b6588dfed55260147d24ced02dca3a2829f328", - "zh:a404d46f2831f90633947ab5d57e19dbfe35b3704104ba6ec80bcf50b058acfd", - "zh:ae1caea1c936d459ceadf287bb5c5bd67b5e2a7819df6f5c4114b7305df7f822", - "zh:afb4f805477694a4b9dde86b268d2c0821711c8aab1c6088f5f992228c4c06fb", - "zh:b993b4a1de8a462643e78f4786789e44ce5064b332fee1cb0d6250ed085561b8", - "zh:c84b2c13fa3ea2c0aa7291243006d560ce480a5591294b9001ce3742fc9c5791", - "zh:c8966f69b7eccccb771704fd5335923692eccc9e0e90cb95d14538fe2e92a3b8", - "zh:d5fe68850d449b811e633a300b114d0617df6d450305e8251643b4d143dc855b", - "zh:ddebfd1e674ba336df09b1f27bbaa0e036c25b7a7087dc8081443f6e5954028b", - ] -} - provider "registry.terraform.io/hashicorp/google" { - version = "4.1.0" + version = "4.6.0" constraints = ">= 4.1.0" hashes = [ - "h1:eqp/ZZ0N2tF0ZSaAUdS6b5TLSZKPegmFLqEFid89V9k=", - "h1:oXcSMwbjSCr0PO2PyZbKPbPXnd4EhxdJGZQwtzQqwrM=", - "zh:3477415ef4ef02d7c065a08fb24b7011ddd77f76b2a011db25e0b73c767acaae", - "zh:43be16d0bbb56d29c090c1abe49e877e4f3ca66bb372a661a2cd0a377cd61e8f", - "zh:6bb202a40055ed302f9dd05e2f3f87aa13080e580a9ac7b0241d634b78b68a2a", - "zh:7179303f628c5fc58129013ef4a4e754e225e266e68af4a7167a06a64d9d97db", - "zh:837cdcf1bafd4c936f15a4a22353efeec96ca23727f8d8ff22e9d53414d87084", - "zh:a853f1a1e9f5ac261fd9a02d869ce7da16917fdd16464dabf2200e2ccd04fba9", - "zh:aba631b9db47cc34857c25459475f17d939a46022f886e396a8254588f720c58", - "zh:ac461358984ba480b4fef1d2be3538d9714aa8814a6f420e1e954227054a14a4", - "zh:ade64689485fc28b6aa0c36861c6c9c66b5d7a8e7282739ecf97c7791b973312", - "zh:c3fbbfe7f6e870e19bb552a2ad84ea38c9ddf3e25e0b7e996ecb2fc7ce336b03", - "zh:d1419f4fe9c07f136ee9015a299cd6acf25a13bea0afa0f69727a576058603d3", + "h1:QbO4yjDrnoSpiYKSHrICNL1ZuWsl5J2rVRFj2kNg7xA=", + "h1:uGcZfOySgiqtYDw0eQXgmdzMDZrsuRXhmzNJYxJbgcc=", + "zh:005a28a2c79f6b29680b0f57260c69c85d8a992688007b6e5645149bd379951f", + "zh:2604d825de72cf99b4899d7880837adeb19d371f48e419666e32c4c3cf6a72e9", + "zh:290da4eb18e44469480cf299bebce89f54e4d301f856cdffe2837b498878c7ec", + "zh:3e5ba1a55d38fa17533a18fc14a612e781ded76c6309734d3dc0a937be27eec1", + "zh:4a85de3cdb33c092d8ccfced3d7302934de0dd4f72bbcebd79d45afe0a0b6f85", + "zh:5fb1a79800833ae922aaba594a8b2bc83be1d254052e12e0ce8330ca0d8933d9", + "zh:679b9f50c6fe0476e74d37935f7598d46d6e9612f75b26a8ef1ca3c13144d06a", + "zh:893216e32378839668c51ef135af1676cd887d63e2edb6625cf9adad7bfa346f", + "zh:ad8f2fd19adbe4c10281ba9b3c8d5100877a9c541d3580bbbe9357714aa77619", + "zh:bff5d6fd15e98c12ee9ed98b0338761dc4a9ba671a37834926daeabf73c71783", + "zh:debdf15fbed8d63e397cd004bf65586bd2b93ce04e47ca51a7c70c1fe9168b87", ] } diff --git a/examples/complete/main.tf b/examples/complete/main.tf index c5bf624..f0af566 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -22,24 +22,28 @@ module "gcr_cleaner" { { storage_region = "eu" repositories = [ + { + # in `test/nginx` repository, delete all `beta` tags + name = "test/nginx" + tag_filter_all = "^beta.+$" + }, { # in `test/nginx` repository, delete all images older than 30 days (720h) name = "test/nginx" grace = "720h" }, { - # in `test/python` repository, keep 3 `alpha` tags - name = "test/python" - allow_tagged = true - keep = 3 - tag_filter = "^alpha.+$" + # in `test/python` repository, if there is at least one `alpha` tag, + # delete all and keep only 3 tags + name = "test/python" + keep = 3 + tag_filter_any = "^alpha.+$" }, { - # in `test/tools/ci` repository and all its child repositories, keep only 5 tags - name = "test/tools/ci" - allow_tagged = true - keep = 5 - recursive = true + # in `test/tools/ci` repository and all its child repositories, keep only 5 images + name = "test/tools/ci" + keep = 5 + recursive = true } ] }, @@ -53,21 +57,9 @@ module "gcr_cleaner" { clean_all = true storage_region = "eu" parameters = { - allow_tagged = true - keep = 5 - grace = "120h" - tag_filter = "^beta.+$" - } - }, - { - # in all repositories, keep 10 `live` tags, ignore anything newer than 15 days - clean_all = true - storage_region = "eu" - parameters = { - allow_tagged = true - keep = 10 - grace = "360h" - tag_filter = "^live.+$" + keep = 5 + grace = "120h" + tag_filter_all = "^beta.+$" } } ] diff --git a/examples/minimal/.terraform.lock.hcl b/examples/minimal/.terraform.lock.hcl index b188f77..ad2d5f3 100644 --- a/examples/minimal/.terraform.lock.hcl +++ b/examples/minimal/.terraform.lock.hcl @@ -1,42 +1,22 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. -provider "registry.terraform.io/hashicorp/external" { - version = "2.1.0" - constraints = ">= 2.1.0" - hashes = [ - "h1:LTl5CGW8wiIEe16AC4MtXN/95xWWNDbap70zJsBTk0w=", - "h1:wbtDfLeawmv6xVT1W0w0fctRCb4ABlaD3JTxwb1jXag=", - "zh:0d83ffb72fbd08986378204a7373d8c43b127049096eaf2765bfdd6b00ad9853", - "zh:7577d6edc67b1e8c2cf62fe6501192df1231d74125d90e51d570d586d95269c5", - "zh:9c669ded5d5affa4b2544952c4b6588dfed55260147d24ced02dca3a2829f328", - "zh:a404d46f2831f90633947ab5d57e19dbfe35b3704104ba6ec80bcf50b058acfd", - "zh:ae1caea1c936d459ceadf287bb5c5bd67b5e2a7819df6f5c4114b7305df7f822", - "zh:afb4f805477694a4b9dde86b268d2c0821711c8aab1c6088f5f992228c4c06fb", - "zh:b993b4a1de8a462643e78f4786789e44ce5064b332fee1cb0d6250ed085561b8", - "zh:c84b2c13fa3ea2c0aa7291243006d560ce480a5591294b9001ce3742fc9c5791", - "zh:c8966f69b7eccccb771704fd5335923692eccc9e0e90cb95d14538fe2e92a3b8", - "zh:d5fe68850d449b811e633a300b114d0617df6d450305e8251643b4d143dc855b", - "zh:ddebfd1e674ba336df09b1f27bbaa0e036c25b7a7087dc8081443f6e5954028b", - ] -} - provider "registry.terraform.io/hashicorp/google" { - version = "4.1.0" + version = "4.6.0" constraints = ">= 4.1.0" hashes = [ - "h1:eqp/ZZ0N2tF0ZSaAUdS6b5TLSZKPegmFLqEFid89V9k=", - "h1:oXcSMwbjSCr0PO2PyZbKPbPXnd4EhxdJGZQwtzQqwrM=", - "zh:3477415ef4ef02d7c065a08fb24b7011ddd77f76b2a011db25e0b73c767acaae", - "zh:43be16d0bbb56d29c090c1abe49e877e4f3ca66bb372a661a2cd0a377cd61e8f", - "zh:6bb202a40055ed302f9dd05e2f3f87aa13080e580a9ac7b0241d634b78b68a2a", - "zh:7179303f628c5fc58129013ef4a4e754e225e266e68af4a7167a06a64d9d97db", - "zh:837cdcf1bafd4c936f15a4a22353efeec96ca23727f8d8ff22e9d53414d87084", - "zh:a853f1a1e9f5ac261fd9a02d869ce7da16917fdd16464dabf2200e2ccd04fba9", - "zh:aba631b9db47cc34857c25459475f17d939a46022f886e396a8254588f720c58", - "zh:ac461358984ba480b4fef1d2be3538d9714aa8814a6f420e1e954227054a14a4", - "zh:ade64689485fc28b6aa0c36861c6c9c66b5d7a8e7282739ecf97c7791b973312", - "zh:c3fbbfe7f6e870e19bb552a2ad84ea38c9ddf3e25e0b7e996ecb2fc7ce336b03", - "zh:d1419f4fe9c07f136ee9015a299cd6acf25a13bea0afa0f69727a576058603d3", + "h1:QbO4yjDrnoSpiYKSHrICNL1ZuWsl5J2rVRFj2kNg7xA=", + "h1:uGcZfOySgiqtYDw0eQXgmdzMDZrsuRXhmzNJYxJbgcc=", + "zh:005a28a2c79f6b29680b0f57260c69c85d8a992688007b6e5645149bd379951f", + "zh:2604d825de72cf99b4899d7880837adeb19d371f48e419666e32c4c3cf6a72e9", + "zh:290da4eb18e44469480cf299bebce89f54e4d301f856cdffe2837b498878c7ec", + "zh:3e5ba1a55d38fa17533a18fc14a612e781ded76c6309734d3dc0a937be27eec1", + "zh:4a85de3cdb33c092d8ccfced3d7302934de0dd4f72bbcebd79d45afe0a0b6f85", + "zh:5fb1a79800833ae922aaba594a8b2bc83be1d254052e12e0ce8330ca0d8933d9", + "zh:679b9f50c6fe0476e74d37935f7598d46d6e9612f75b26a8ef1ca3c13144d06a", + "zh:893216e32378839668c51ef135af1676cd887d63e2edb6625cf9adad7bfa346f", + "zh:ad8f2fd19adbe4c10281ba9b3c8d5100877a9c541d3580bbbe9357714aa77619", + "zh:bff5d6fd15e98c12ee9ed98b0338761dc4a9ba671a37834926daeabf73c71783", + "zh:debdf15fbed8d63e397cd004bf65586bd2b93ce04e47ca51a7c70c1fe9168b87", ] } diff --git a/iam.tf b/iam.tf index 63c7677..7b33bc1 100644 --- a/iam.tf +++ b/iam.tf @@ -20,6 +20,8 @@ resource "google_cloud_run_service_iam_binding" "this" { ] } +# Grant cleaner service account roles/browser role in order to query the registry. +# This is the most minimal permission. resource "google_project_iam_member" "this" { project = google_cloud_run_service.this.project role = "roles/browser" diff --git a/locals.tf b/locals.tf index a33036a..9c74442 100644 --- a/locals.tf +++ b/locals.tf @@ -19,13 +19,14 @@ locals { # Set default values for optional fields. project_all_repositories = [ for repo in var.gcr_repositories : { - repo = "${repo.storage_region != null ? "${repo.storage_region}.gcr.io" : "gcr.io"}/${repo.project_id != null ? repo.project_id : local.google_project_id}" - grace = repo.parameters != null ? (repo.parameters.grace != null ? repo.parameters.grace : "0") : "0" - allow_tagged = repo.parameters != null ? (repo.parameters.allow_tagged != null ? repo.parameters.allow_tagged : false) : false - keep = repo.parameters != null ? (repo.parameters.keep != null ? repo.parameters.keep : "0") : "0" - tag_filter = repo.parameters != null ? (repo.parameters.tag_filter != null ? repo.parameters.tag_filter : "") : "" - recursive = true - filter = repo.parameters != null ? "grace-${repo.parameters.grace != null ? repo.parameters.grace : "0"}-allow_tagged-${repo.parameters.allow_tagged != null ? repo.parameters.allow_tagged : false}-keep-${repo.parameters.keep != null ? repo.parameters.keep : "0"}-tag_filter-${repo.parameters.tag_filter != null ? repo.parameters.tag_filter : "no"}" : "delete-all-untagged-images-recursive" + repo = "${repo.storage_region != null ? "${repo.storage_region}.gcr.io" : "gcr.io"}/${repo.project_id != null ? repo.project_id : local.google_project_id}" + grace = repo.parameters != null ? (repo.parameters.grace != null ? repo.parameters.grace : "0") : "0" + keep = repo.parameters != null ? (repo.parameters.keep != null ? repo.parameters.keep : "0") : "0" + tag_filter = repo.parameters != null ? (repo.parameters.tag_filter != null ? repo.parameters.tag_filter : "") : "" + tag_filter_any = repo.parameters != null ? (repo.parameters.tag_filter_any != null ? repo.parameters.tag_filter_any : "") : "" + tag_filter_all = repo.parameters != null ? (repo.parameters.ttag_filter_allag_filter != null ? repo.parameters.tag_filter_all : "") : "" + recursive = true + filter = repo.parameters != null ? "grace-${repo.parameters.grace != null ? repo.parameters.grace : "0"}-keep-${repo.parameters.keep != null ? repo.parameters.keep : "0"}-tag_filter-${repo.parameters.tag_filter != null ? repo.parameters.tag_filter : "no"}-tag_filter_any-${repo.parameters.tag_filter_any != null ? repo.parameters.tag_filter_any : "no"}-tag_filter_any-${repo.parameters.tag_filter_any != null ? repo.parameters.tag_filter_any : "no"}" : "delete-all-untagged-images-recursive" } if repo.clean_all == true ] @@ -35,13 +36,14 @@ locals { for gcr in var.gcr_repositories : [ for repo in gcr.repositories : merge(repo, { - repo = "${gcr.storage_region != null ? "${gcr.storage_region}.gcr.io" : "gcr.io"}/${gcr.project_id != null ? gcr.project_id : local.google_project_id}/${repo.name}" - grace = repo.grace != null ? repo.grace : "0" - allow_tagged = repo.allow_tagged != null ? repo.allow_tagged : false - keep = repo.keep != null ? repo.keep : "0" - tag_filter = repo.tag_filter != null ? repo.tag_filter : "" - recursive = repo.recursive != null ? repo.recursive : false - filter = "grace-${repo.grace != null ? repo.grace : "0"}-allow_tagged-${repo.allow_tagged != null ? repo.allow_tagged : false}-keep-${repo.keep != null ? repo.keep : "0"}-tag_filter-${repo.tag_filter != null ? repo.tag_filter : "no"}-recursive-${repo.recursive != null ? repo.recursive : false}" + repo = "${gcr.storage_region != null ? "${gcr.storage_region}.gcr.io" : "gcr.io"}/${gcr.project_id != null ? gcr.project_id : local.google_project_id}/${repo.name}" + grace = repo.grace != null ? repo.grace : "0" + keep = repo.keep != null ? repo.keep : "0" + tag_filter = repo.tag_filter != null ? repo.tag_filter : "" + tag_filter_any = repo.tag_filter_any != null ? repo.tag_filter_any : "" + tag_filter_all = repo.tag_filter_all != null ? repo.tag_filter_all : "" + recursive = repo.recursive != null ? repo.recursive : false + filter = "grace-${repo.grace != null ? repo.grace : "0"}-keep-${repo.keep != null ? repo.keep : "0"}-tag_filter-${repo.tag_filter != null ? repo.tag_filter : "no"}-tag_filter_any-${repo.tag_filter_any != null ? repo.tag_filter_any : "no"}-tag_filter_all-${repo.tag_filter_all != null ? repo.tag_filter_all : "no"}-recursive-${repo.recursive != null ? repo.recursive : false}" } ) ] if gcr.repositories != null diff --git a/main.tf b/main.tf index f56713f..3f99ec7 100644 --- a/main.tf +++ b/main.tf @@ -82,12 +82,13 @@ resource "google_cloud_scheduler_job" "this" { http_method = "POST" uri = "${google_cloud_run_service.this.status[0].url}/http" body = base64encode(jsonencode({ - allow_tagged = tobool(each.value.allow_tagged), - grace = each.value.grace, - keep = tonumber(each.value.keep), - repos = [each.value.repo], - tag_filter = each.value.tag_filter, - recursive = tobool(each.value.recursive), + grace = each.value.grace, + keep = tonumber(each.value.keep), + repos = [each.value.repo], + tag_filter = each.value.tag_filter, + tag_filter_any = each.value.tag_filter_any, + tag_filter_all = each.value.tag_filter_all, + recursive = tobool(each.value.recursive), })) oidc_token { service_account_email = google_service_account.invoker.email diff --git a/variables.tf b/variables.tf index a6082cc..ccd4ae4 100644 --- a/variables.tf +++ b/variables.tf @@ -62,22 +62,24 @@ variable "gcr_repositories" { List of Google Container Registries objects to create: ``` list(object({ - project_id = Value of the Google project id, if ommited, it will be assigned `google_project_id` variable value (optional(string)) - storage_region = Location of the storage bucket (optional(string)) - repositories = Docker image repositories to clean (optional(list(object({ - name = Name of the repository (string) - grace = Relative duration in which to ignore references. This value is specified as a time duration value like "5s" or "3h". If set, refs newer than the duration will not be deleted. If unspecified, the default is no grace period (all untagged image refs are deleted) (optional(string)) - allow_tagged = If set to true, will check all images including tagged. If unspecified, the default will only delete untagged images (optional(bool)) - keep = If an integer is provided, it will always keep that minimum number of images. Note that it will not consider images inside the `grace` duration (optional(string)) - tag_filter = Used for tags regexp definition to define pattern to clean, requires `allow_tagged` must be true. For example: use `"^dev.+$"` to limit cleaning only on the tags with beginning with is `dev`. The default is no filtering (optional(string)) - recursive = If set to true, will recursively search all child repositories (optional(bool)) + project_id = Value of the Google project id, if ommited, it will be assigned `google_project_id` variable value (optional(string)) + storage_region = Location of the storage bucket (optional(string)) + repositories = Docker image repositories to clean (optional(list(object({ + name = Name of the repository (string) + grace = Relative duration in which to ignore references. This value is specified as a time duration value like "5s" or "3h". If set, refs newer than the duration will not be deleted. If unspecified, the default is no grace period (all untagged image refs are deleted) (optional(string)) + keep = If an integer is provided, it will always keep that minimum number of images. Note that it will not consider images inside the `grace` duration (optional(string)) + tag_filter = (Deprecated) If specified, any image where the first tag matches this given regular expression will be deleted. The image will not be deleted if other tags match the regular expression (optional(string)) + tag_filter_any = If specified, any image with at least one tag that matches this given regular expression will be deleted. The image will be deleted even if it has other tags that do not match the given regular expression (optional(string)) + tag_filter_all = If specified, any image where all tags match this given regular expression will be deleted. The image will not be delete if it has other tags that do not match the given regular expression (optional(string)) + recursive = If set to true, will recursively search all child repositories (optional(bool)) })))) - clean_all = Set to `true` to clean all project's repositories (optional(bool)) - parameters = Map of parameters to apply to all repositories when `clean_all` is set to `true` (optional(object({ - grace = Relative duration in which to ignore references. This value is specified as a time duration value like "5s" or "3h". If set, refs newer than the duration will not be deleted. If unspecified, the default is no grace period (all untagged image refs are deleted) (optional(string)) - allow_tagged = If set to true, will check all images including tagged. If unspecified, the default will only delete untagged images (optional(bool)) - keep = If an integer is provided, it will always keep that minimum number of images. Note that it will not consider images inside the `grace` duration (optional(string)) - tag_filter = Used for tags regexp definition to define pattern to clean, requires `allow_tagged` must be true. For example: use `"^dev.+$"` to limit cleaning only on the tags with beginning with is `dev`. The default is no filtering (optional(string)) + clean_all = Set to `true` to clean all project's repositories (optional(bool)) + parameters = Map of parameters to apply to all repositories when `clean_all` is set to `true` (optional(object({ + grace = Relative duration in which to ignore references. This value is specified as a time duration value like "5s" or "3h". If set, refs newer than the duration will not be deleted. If unspecified, the default is no grace period (all untagged image refs are deleted) (optional(string)) + keep = If an integer is provided, it will always keep that minimum number of images. Note that it will not consider images inside the `grace` duration (optional(string)) + tag_filter = (Deprecated) If specified, any image where the first tag matches this given regular expression will be deleted. The image will not be deleted if other tags match the regular expression (optional(string)) + tag_filter_any = If specified, any image with at least one tag that matches this given regular expression will be deleted. The image will be deleted even if it has other tags that do not match the given regular expression (optional(string)) + tag_filter_all = If specified, any image where all tags match this given regular expression will be deleted. The image will not be delete if it has other tags that do not match the given regular expression (optional(string)) }))) })) ``` @@ -87,19 +89,21 @@ EOF project_id = optional(string) storage_region = optional(string) repositories = optional(list(object({ - name = string - grace = optional(string) - allow_tagged = optional(bool) - keep = optional(string) - tag_filter = optional(string) - recursive = optional(bool) + name = string + grace = optional(string) + keep = optional(string) + tag_filter = optional(string) + tag_filter_any = optional(string) + tag_filter_all = optional(string) + recursive = optional(bool) }))) clean_all = optional(bool) parameters = optional(object({ - grace = optional(string) - allow_tagged = optional(bool) - keep = optional(string) - tag_filter = optional(string) + grace = optional(string) + keep = optional(string) + tag_filter = optional(string) + tag_filter_any = optional(string) + tag_filter_all = optional(string) })) })) default = []