Skip to content

Commit

Permalink
add ecr module with example
Browse files Browse the repository at this point in the history
  • Loading branch information
Jlkan committed Jun 10, 2024
1 parent 459450d commit 8b786a1
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 0 deletions.
23 changes: 23 additions & 0 deletions examples/ecr-repository/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions examples/ecr-repository/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

module "info" {
source = "Selleo/context/null"
version = "0.3.0"

namespace = "kudos"
stage = "production"
name = "api"
}

module "this" {
source = "../../modules/ecr-repository"

context = module.info.context
}

output "url" {
value = module.this.url

}
30 changes: 30 additions & 0 deletions modules/ecr-repository/lifecycle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"rules": [
{
"rulePriority": 1,
"description": "Keep last ${image_count} images prefixed with version",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["v"],
"countType": "imageCountMoreThan",
"countNumber": ${image_count}
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 2,
"description": "Expire untagged images older than ${day_count} days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": ${day_count}
},
"action": {
"type": "expire"
}
}
]
}
82 changes: 82 additions & 0 deletions modules/ecr-repository/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
locals {
tags = {
"context.namespace" = var.context.namespace
"context.stage" = var.context.stage
"context.name" = var.context.name
}

name = "${var.context.namespace}/${var.context.stage}/${var.context.name}"
id = "${var.context.namespace}-${var.context.stage}-${var.context.name}"
}

resource "aws_ecr_repository" "this" {
name = local.name
image_tag_mutability = "MUTABLE"

image_scanning_configuration {
scan_on_push = true
}

encryption_configuration {
encryption_type = "KMS"
# kms_key = "TODO" if not specified, AWS will use default KMS for ECR
}

tags = local.tags

}

resource "aws_ecr_lifecycle_policy" "this" {
repository = aws_ecr_repository.this.name

policy = templatefile("${path.module}/policy/lifecycle.json", {
image_count = var.max_image_count
day_count = var.expire_untagged_after
})
}

data "aws_iam_policy_document" "deployment_group" {
statement {
actions = [
"ecr:GetAuthorizationToken"
]

resources = ["*"]
}

statement {
actions = [
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer",
"ecr:ListImages",
]

resources = [aws_ecr_repository.this.arn]
}

statement {
actions = [
"ecr:BatchCheckLayerAvailability",
"ecr:CompleteLayerUpload",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart",
]

resources = [aws_ecr_repository.this.arn]
}
}

resource "aws_iam_policy" "deployment_group" {
name = "ecr-${local.id}-deployment"
policy = data.aws_iam_policy_document.deployment_group.json
}

resource "aws_iam_group" "deployment" {
name = "ecr-${local.id}-deployment"
}

resource "aws_iam_group_policy_attachment" "deployment" {
group = aws_iam_group.deployment.name
policy_arn = aws_iam_policy.deployment_group.arn
}
29 changes: 29 additions & 0 deletions modules/ecr-repository/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
output "url" {
description = "Repository URL"
value = aws_ecr_repository.this.repository_url
}

output "url_tagged_latest" {
description = "Repository URL with `latest` tag."
value = "${aws_ecr_repository.this.repository_url}:latest"
}

output "arn" {
description = "Repository ARN."
value = aws_ecr_repository.this.arn
}

output "name" {
description = "Repository name."
value = aws_ecr_repository.this.name
}

output "deployment_group" {
value = aws_iam_group.deployment.name
description = "Deployment group name"
}

output "deployment_group_arn" {
value = aws_iam_group.deployment.arn
description = "Deployment group ARN"
}
30 changes: 30 additions & 0 deletions modules/ecr-repository/policy/lifecycle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"rules": [
{
"rulePriority": 1,
"description": "Keep last ${image_count} images prefixed with version",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["v"],
"countType": "imageCountMoreThan",
"countNumber": ${image_count}
},
"action": {
"type": "expire"
}
},
{
"rulePriority": 2,
"description": "Expire untagged images older than ${day_count} days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": ${day_count}
},
"action": {
"type": "expire"
}
}
]
}
24 changes: 24 additions & 0 deletions modules/ecr-repository/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
variable "context" {
description = "Project context"

type = object({
namespace = string
stage = string
name = string
})
}

# optional

variable "max_image_count" {
description = "Keep only last X images that are prefixed with `v`"
type = number
default = 100
}

variable "expire_untagged_after" {
description = "Expire untagged images after X days"
type = number
default = 14
}

10 changes: 10 additions & 0 deletions modules/ecr-repository/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = "~> 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0"
}
}
}

0 comments on commit 8b786a1

Please sign in to comment.