Bu örnekte, AWS ECR deposu için bir Terraform modülü oluşturacağız ve bunu Docker görüntülerini depolamak için kullanacağız.


Modül


└── ecr
├── aws_ecr_lifecycle_policy.tf
├── aws_ecr_repository.tf
├── main.tf
├── outputs.tf
├── providers.tf
└── variables.tf

variables.tf


variable "aws_region" {
description = "AWS region where the resources are provisioned."
type = string
}

variable "aws_organisation" {
description = "The AWS organisation name."
type = string
}

variable "app_repository" {
description = "The application repository name."
type = string
}

variable "app_environment" {
description = "The application environment that image represents."
type = string
}

variable "image_description" {
description = "A meaningful description for the image."
type = string
}

variable "image_scan" {
description = "Defines if the image should be scanned for vulnerabilities on push."
type = bool
}

variable "image_age" {
description = "Delete images older than number of days."
type = number
}

main.tf


terraform {
required_version = "~> 1.4.4"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.30.0"
}
}
}

providers.tf


provider "aws" {
region = var.aws_region
}

aws_ecr_repository.tf


resource "aws_ecr_repository" "app_repository" {
name = "${var.aws_organisation}/${var.app_repository}/${var.app_environment}"
image_tag_mutability = "IMMUTABLE"

image_scanning_configuration {
scan_on_push = var.image_scan
}

tags = {
description = var.image_description
environment = var.app_environment
}
}

aws_ecr_lifecycle_policy.tf


resource "aws_ecr_lifecycle_policy" "image_age" {
count = var.image_age > 0 ? 1 : 0

repository = aws_ecr_repository.app_repository.name

policy = jsonencode({
"rules" : [
{
"description" : "Delete images older than ${var.image_age} days.",
"rulePriority" : 1,
"selection" : {
"tagStatus" : "any",
"countType" : "sinceImagePushed",
"countUnit" : "days",
"countNumber" : "${var.image_age}"
},
"action" : {
"type" : "expire"
}
}
]
})
}

outputs.tf


output "app_ecr_repository" {
description = "The ECR registry ID and repository URL."

value = {
registry_id = aws_ecr_repository.app_repository.registry_id
repository_url = aws_ecr_repository.app_repository.repository_url
}
}

Uygulama


└── terraform
└── development
├── ecr.tf
├── local.tf
├── main.tf
├── outputs.tf
└── providers.tf

local.tf


locals {
terraform_version = "~> 1.2.6"

aws_version = "~> 4.30.0"
aws_region = "eu-west-1"
aws_organisation = "inanzzz"

app_repository = "blog"
app_environment = "development"

ecr_image_description = "Backend application image."
ecr_image_scan = true
ecr_image_age = 28
}

main.tf


terraform {
required_version = "~> 1.4.4"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.30.0"
}
}
}

providers.tf


provider "aws" {
region = local.aws_region
}

ecr.tf


module "ecr_image_backend" {
source = "../../../modules/ecr"

aws_region = local.aws_region
aws_organisation = local.aws_organisation

app_repository = local.app_repository
app_environment = local.app_environment

image_description = local.ecr_image_description
image_scan = local.ecr_image_scan
image_age = local.ecr_image_age
}

outputs.tf


output "backend_image" {
value = "${module.ecr_image_backend.app_ecr_repository}"
}

AWS CLI yapılandırma


[default]
region = eu-west-1
output = json

[default]
aws_access_key_id = 123456JHGFDS098765FD
aws_secret_access_key = onsadasd213123SxiTsadRHsWasd123dT57zdsa

$ aws sts get-caller-identity
{
"UserId": "JHGFBVCX1234587HGF",
"Account": "123456789000",
"Arn": "arn:aws:iam::123456789000:user/admin-1"
}

AWS ECR deposu oluşturun


$ terraform apply
...

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Outputs:

backend_image = {
"registry_id" = "123456789000"
"repository_url" = "123456789000.dkr.ecr.eu-west-1.amazonaws.com/inanzzz/blog/development"
}

Depoya giriş yap


Önce URL'nin repository_url özelliğiyle eşleştiğini doğrulayın. Doğruysa oturum açmaya devam edin.


$ echo https://$(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.$(aws configure get region).amazonaws.com

https://123456789000.dkr.ecr.eu-west-1.amazonaws.com

$ aws ecr get-login-password | \
docker login -u AWS --password-stdin "https://$(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.$(aws configure get region).amazonaws.com"

Login Succeeded

Temel bir görüntü hazırlayın


Mevcut bir genel görüntüyü çekin


$ docker pull golang:1.20.2-alpine3.17

$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
golang 1.20.2-alpine3.17 897fd20494bd 6 weeks ago 254MB

ECR deposunu kullanarak görüntüyü etiketleyin


$ docker tag golang:1.20.2-alpine3.17 $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.$(aws configure get region).amazonaws.com/inanzzz/blog/development:latest

$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
golang 1.20.2-alpine3.17 897fd20494bd 6 weeks ago 254MB
123456789000.dkr.ecr.eu-west-1.amazonaws.com/inanzzz/blog/development latest e66264b98777 11 months ago 254MB

ECR görüntüsünü iletin


$ docker push $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.$(aws configure get region).amazonaws.com/inanzzz/blog/development:latest

The push refers to repository [123456789000.dkr.ecr.eu-west-1.amazonaws.com/inanzzz/blog/development]
24302eb7d908: Pushed
latest: digest: sha256:123456qwertasdfg12345 size: 528

$ aws ecr list-images --repository-name inanzzz/blog/development
{
"imageIds": [
{
"imageDigest": "sha256:123456qwertasdfg12345",
"imageTag": "latest"
}
]
}

ECR görüntüsünü çekin


$ docker pull $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.$(aws configure get region).amazonaws.com/inanzzz/blog/development:latest

latest: Pulling from inanzzz/blog/development
Digest: sha256:123456qwertasdfg12345
Status: Downloaded newer image for 123456789000.dkr.ecr.eu-west-1.amazonaws.com/inanzzz/blog/development:latest
123456789000.dkr.ecr.eu-west-1.amazonaws.com/inanzzz/blog/development:latest