👥
【terraform】yamlファイルにちょっと書くだけでリソース作成できる仕組みを作りたい
概要
terraformを知らなくても、簡単な項目だけ書けばリソースをデプロイできる仕組みをterraformで用意しました
こんな感じのイメージです
- 開発者: yamlファイルに必要項目を書く
- SRE(インフラ): ↑を反映させるTFを用意する
題材
題材はECRリポジトリにします
ユーザは以下の情報だけを記述すればよいものとします
- リポジトリ名
- チーム名(tagに反映する)
- mutable or immutable
- IAMロール(リポジトリポリシーに反映する)
ユーザに書いてもらうファイル
yamlにしました
- name: frontend-app
team: team-alpha
immutable: false
iam_roles:
- arn:aws:iam::123456789012:role/team-alpha-deploy-role
- arn:aws:iam::123456789012:role/ci-cd-role
- name: backend-api
team: team-alpha
immutable: true
iam_roles:
- arn:aws:iam::123456789012:role/team-alpha-deploy-role
- name: batch-worker
team: team-beta
immutable: false
iam_roles:
- arn:aws:iam::123456789012:role/team-beta-deploy-role
TFコード
# YAMLファイルを読み込み
locals {
repositories = yamldecode(file("${path.module}/ecr-repositories.yaml"))
# リポジトリ名をキーとしたマップに変換
repositories_map = {
for repo in local.repositories : repo.name => repo
}
}
# ECRリポジトリの作成
resource "aws_ecr_repository" "this" {
for_each = local.repositories_map
name = each.value.name
image_tag_mutability = each.value.immutable ? "IMMUTABLE" : "MUTABLE"
tags = {
Name = each.value.name
Team = each.value.team
ManagedBy = "terraform"
}
}
# リポジトリポリシーの設定
resource "aws_ecr_repository_policy" "this" {
for_each = local.repositories_map
repository = aws_ecr_repository.this[each.key].name
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "AllowPushPull"
Effect = "Allow"
Principal = {
AWS = each.value.iam_roles
}
Action = [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
]
}
]
})
}
# ライフサイクルポリシー(オプション)
resource "aws_ecr_lifecycle_policy" "this" {
for_each = local.repositories_map
repository = aws_ecr_repository.this[each.key].name
policy = jsonencode({
rules = [
{
rulePriority = 1
description = "Keep last 10 images"
selection = {
tagStatus = "any"
countType = "imageCountMoreThan"
countNumber = 10
}
action = {
type = "expire"
}
}
]
})
}
ポイントはYAMLファイルからリポジトリ設定を読み込むところです
ecr-repositories.yamlファイルを読み込みリスト形式のデータを取得、リストをマップ(辞書)形式に変換し、リポジトリ名をキーとして使用しています
あとはfor_eachで処理するだけです
動作確認
これをapplyすると
$ terraform state list
aws_ecr_lifecycle_policy.this["backend-api"]
aws_ecr_lifecycle_policy.this["batch-worker"]
aws_ecr_lifecycle_policy.this["frontend-app"]
aws_ecr_repository.this["backend-api"]
aws_ecr_repository.this["batch-worker"]
aws_ecr_repository.this["frontend-app"]
aws_ecr_repository_policy.this["backend-api"]
aws_ecr_repository_policy.this["batch-worker"]
aws_ecr_repository_policy.this["frontend-app"]
よさそうです
yaml1つ用意しておけば、すぐにチーム専用のリソースを作成できます
まとめ
意外と簡単にterraformファイルはできたので、チーム毎に必要なAWSリソースがあったら使ってみると便利かと思います
モジュールにも応用できる手法です
ただ書いていて、「immutableってわかりずらい?」「なんのためにIAMロール設定するの?」等の疑問は生じると思うので、ちゃんとREADMEに説明書くなりするのが大事と思いました
Discussion