Skip to content

Commit

Permalink
feat: add support to lifecycle policy
Browse files Browse the repository at this point in the history
- need to creating more tests
  • Loading branch information
cauealvesbraz committed Nov 13, 2022
1 parent 8bfe56c commit 9327d79
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 0 deletions.
9 changes: 9 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,12 @@ resource "aws_ecr_repository" "this" {
}
)
}

resource "aws_ecr_lifecycle_policy" "this" {
count = length(var.lifecycle_policy.rules) > 0 ? 1 : 0

repository = aws_ecr_repository.this.name
policy = jsonencode({
"rules" : var.lifecycle_policy.rules
})
}
85 changes: 85 additions & 0 deletions tests/lifecycle_policy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package tests

import (
"fmt"
"testing"

"github.com/gruntwork-io/terratest/modules/aws"
"github.com/gruntwork-io/terratest/modules/random"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)

func TestCanCreateRepositoryWithEmptyLifecyclePolicy(t *testing.T) {
t.Parallel()

expectedName := fmt.Sprintf("test-%d", random.Random(0, 10))

region := aws.GetRandomRegion(t, nil, nil)

terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
TerraformDir: "../",
Vars: map[string]interface{}{
"name": expectedName,
},
EnvVars: map[string]string{
"AWS_DEFAULT_REGION": region,
},
})

defer terraform.Destroy(t, terraformOptions)

terraform.InitAndApply(t, terraformOptions)

repository := aws.GetECRRepo(t, region, expectedName)

assert.Equal(t, "AES256", *repository.EncryptionConfiguration.EncryptionType)
assert.Equal(t, "IMMUTABLE", *repository.ImageTagMutability)
assert.True(t, *repository.ImageScanningConfiguration.ScanOnPush)
}

func TestCanCreateRepositoryWithLifecyclePolicyAndTaggedStatus(t *testing.T) {
t.Parallel()

expectedName := fmt.Sprintf("test-%d", random.Random(0, 10))

region := aws.GetRandomRegion(t, nil, nil)

terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
TerraformDir: "../",
Vars: map[string]interface{}{
"name": expectedName,
"lifecycle_policy": map[string]interface{}{
"rules": []map[string]interface{}{
{
"rulePriority": 1,
"description": "Expire images older than 14 days",
"selection": map[string]interface{}{
"tagStatus": "tagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 14,
"tagPrefixList": []string{"test-repo"},
},
"action": map[string]interface{}{
"type": "expire",
},
},
},
},
},
EnvVars: map[string]string{
"AWS_DEFAULT_REGION": region,
},
})

defer terraform.Destroy(t, terraformOptions)

terraform.InitAndApply(t, terraformOptions)

repository := aws.GetECRRepo(t, region, expectedName)

assert.Equal(t, "AES256", *repository.EncryptionConfiguration.EncryptionType)
assert.Equal(t, "IMMUTABLE", *repository.ImageTagMutability)
assert.True(t, *repository.ImageScanningConfiguration.ScanOnPush)
}
87 changes: 87 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,93 @@ variable "scan_on_push" {
description = "Indicates whether images are scanned after being pushed to the repository (true) or not scanned (false). Defauls to true"
}

## Lifecycle policy
variable "lifecycle_policy" {
type = object({
rules = list(object({
rulePriority = number
description = optional(string)
selection = object({
tagStatus = string
countType = string
countNumber = number
countUnit = string
tagPrefixList = optional(list(string))
}),
action = object({
type = string
})
}))
})

default = {
rules = []
}

description = "(Optional) A lifecycle policy for the repository. Default is empty"

validation {
condition = alltrue([
for rule in var.lifecycle_policy.rules : contains(
["tagged", "untagged", "any"],
rule.selection.tagStatus
)
])

error_message = "The tag status must be one of: tagged, untagged or any."
}

validation {
condition = alltrue([
for rule in var.lifecycle_policy.rules : contains(
["sinceImagePushed", "sinceImageCreated"],
rule.selection.countType
)
])

error_message = "The count type must be one of: sinceImagePushed or sinceImageCreated."
}

validation {
condition = alltrue([
for rule in var.lifecycle_policy.rules : contains(
["days", "weeks", "months"],
rule.selection.countUnit
)
])

error_message = "The count unit must be one of: days, weeks or months."
}

validation {
condition = alltrue([
for rule in var.lifecycle_policy.rules : rule.selection.countNumber > 0
])

error_message = "The count number must be greater than 0."
}

validation {
condition = alltrue([
for rule in var.lifecycle_policy.rules : rule.rulePriority > 0
])

error_message = "The priority must be greater than 0."
}

validation {
condition = alltrue([
for rule in var.lifecycle_policy.rules : contains(
["expire"],
rule.action.type
)
])

error_message = "The action type must be one of: expire."
}
}

## Tags
variable "tags" {
type = map(string)
default = {}
Expand Down

0 comments on commit 9327d79

Please sign in to comment.