使用 terraform 将公共映像从 Dockerhub(或只是自定义映像)拉取并重新加载到 ECR。我在想类似的事情
# Create ECR repository
resource "aws_ecr_repository" "ecr_repo" {
name = var.ecr_name
}
# Docker image
resource "null_resource" "docker_hub" {
......
......
depends_on = [aws_ecr_repository.ecr_repo]
}
基本上创建一个 ECR 存储库,然后上传图像...... 我是 terrform 的新手,并且在这方面花了很多时间。所以任何事情都会有所帮助。谢谢
Terraform 实际上只是为了创建 AWS ECR 存储库和策略文档资源等基础设施而设计。可以使用 local-exec 配置器强制 Terraform 执行您想要的操作,这可以让您添加任意命令,但这并不是真正的最佳实践。正如他们在文档中提到的那样,Terraform 配置程序应被视为最后的手段。
最简单的方法是将 Terraform 与 Docker 和 AWS CLI 命令结合起来来构建和推送映像:
# ...terraform commands
docker build -t ${ACCOUNT}.dkr.ecr.${REGION}.amazonaws.com/${REPO} .
aws ecr get-login-password \
--region ${REGION} \
| docker login \
--username AWS \
--password-stdin ${ACCOUNT}.dkr.ecr.${REGION}.amazonaws.com
docker push ${ACCOUNT}.dkr.ecr.${REGION}.amazonaws.com/${REPO}
或者,您可以使用HashiCorp Packer,它是为此目的(构建虚拟机/容器映像)而设计的,并且与 Terraform 具有良好的集成。但这意味着更多的学习曲线,因为 Packer 不使用 Dockerfile。无论如何,如果您沿着这条路走下去,您需要使用 Docker 构建器 与 Docker 推送后处理器。
aws_ecr_authorization_token
数据源将 Docker 提供程序配置为从 AWS ECR 读取/推送。从 2023 年 7 月起,这至少有效。请参阅示例 terraform 配置文件:
# tell terraform which provider plugins are needed
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "3.0.2"
}
aws = {
source = "hashicorp/aws"
version = "5.6.2"
}
}
}
# configure aws provider
provider "aws" {}
# create ecr repo
resource "aws_ecr_repository" "my-ecr-repo" {
name = "my-ecr-repo"
}
# get authorization credentials to push to ecr
data "aws_ecr_authorization_token" "token" {}
# configure docker provider
provider "docker" {
registry_auth {
address = data.aws_ecr_authorization_token.token.proxy_endpoint
username = data.aws_ecr_authorization_token.token.user_name
password = data.aws_ecr_authorization_token.token.password
}
}
# build docker image
resource "docker_image" "my-docker-image" {
name = "${data.aws_ecr_authorization_token.token.proxy_endpoint}/my-ecr-repo:latest"
build {
context = "."
}
platform = "linux/arm64"
}
# push image to ecr repo
resource "docker_registry_image" "media-handler" {
name = docker_image.my-docker-image.name
}
aws_ecr_repository
资源,以及您想要在 ECR AWS 提供商中使用的任何其他资源。下面是 aws_ecr_repository_policy ,能够设置存储库的权限。
resource "aws_ecr_repository_policy" "demo-repo-policy" {
repository = aws_ecr_repository.demo-repository.name
policy = <<EOF
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "adds full ecr access to the demo repository",
"Effect": "Allow",
"Principal": "*",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:CompleteLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:GetLifecyclePolicy",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
]
}
]
}
EOF
}
之后,您可以使用已使用的资源中的属性,用于 docker push
命令
docker push ${aws_account_id}.dkr.ecr.${region}.amazonaws.com/${repository-name}
https://www.oneworldcoders.com/blog/using-terraform-to-provision-amazons-ecr-and-ecs-to-manage-containers-docker
# Get authorization credentials to push to ECR
data "aws_ecr_authorization_token" "ecr_auth" {}
# Configure Docker provider with ECR credentials
provider "docker" {
registry_auth {
address = data.aws_ecr_authorization_token.ecr_auth.proxy_endpoint
username = data.aws_ecr_authorization_token.ecr_auth.user_name
password = data.aws_ecr_authorization_token.ecr_auth.password
}
}
# Define a local variable to remove "https://" from the ecr_proxy_endpoint
locals {
clean_image_repo_url = replace(data.aws_ecr_authorization_token.ecr_auth.proxy_endpoint, "https://", "")
}
# Pull and push the Docker image to the ECR repository using Docker commands
resource "null_resource" "pull_tag_push_image" {
provisioner "local-exec" {
command = <<-EOT
# Authenticate Docker to ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${local.clean_image_repo_url}
# Pull an existing image from Docker Hub
docker pull alpine:latest
# Tag the pulled image for ECR
docker tag alpine:latest ${local.clean_image_repo_url}/${aws_ecr_repository.<tf_repo_name>.name}:dummy
# Push the tagged image to the ECR repository
docker push ${local.clean_image_repo_url}/${aws_ecr_repository.<tf_repo_name>.name}:dummy
EOT
}
depends_on = [aws_ecr_repository.<tf_repo_name>]
}