https://github.com/terraform-aws-modules には、TerraformですぐにAWSリソースを立ち上げるためのModuleがいくつか存在します。
terraform-aws-vpcでは、主に以下のリソースを作ってくれます。オプションでNATとかも用意してくれます。
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "test"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = false
enable_vpn_gateway = false
}
ALBの作成
terraform-aws-albでは、主に以下のリソースを作ってくれます。
Security Group は作ってくれないので、自前で用意しましょう。
resource "aws_security_group" "alb" {
name = "alb"
description = "alb"
vpc_id = module.vpc.vpc_id
}
module "alb" {
source = "terraform-aws-modules/alb/aws"
version = "~> 5.0"
name = "test"
load_balancer_type = "application"
vpc_id = module.vpc.vpc_id
subnets = module.vpc.public_subnets
security_groups = [aws_security_group.alb.id]
target_groups = [
{
name = "test"
backend_protocol = "HTTP"
backend_port = 80
target_type = "ip"
deregistration_delay = 10
}
]
http_tcp_listeners = [
{
port = 80
protocol = "HTTP"
target_group_index = 0
}
]
}
terraform-aws-acmでは、ACM証明書を一発で作ってくれます。これは定型フォーマットなので、そのまま利用して問題ないでしょう。(手元にRoute53管理のドメインがなかったので試してはいません)
module "acm" {
source = "terraform-aws-modules/acm/aws"
version = "~> v2.0"
domain_name = "my-domain.com"
zone_id = "Z2ES7B9AZ6SHAE"
subject_alternative_names = [
"*.my-domain.com",
"app.sub.my-domain.com",
]
tags = {
Name = "my-domain.com"
}
}
SNSのSlack通知
terraform-aws-notify-slackを使うと、SNSトピックをSlackに通知させるやつも簡単にTerraformで管理することが可能です。おそらくこれが一番使うのではないでしょうか。
使い方も簡単で、よくあるCloudWatch AlarmをSlackに通知するのは以下の書き方で実装できます。(手元に通知するものがなかったので試していません)
provider "aws" {
region = "eu-west-1"
}
resource "aws_kms_key" "this" {
description = "KMS key for notify-slack test"
}
# Encrypt the URL, storing encryption here will show it in logs and in tfstate
# https://www.terraform.io/docs/state/sensitive-data.html
resource "aws_kms_ciphertext" "slack_url" {
plaintext = "https://hooks.slack.com/services/AAA/BBB/CCC"
key_id = aws_kms_key.this.arn
}
module "notify_slack" {
source = "../../"
sns_topic_name = "slack-topic"
slack_webhook_url = aws_kms_ciphertext.slack_url.ciphertext_blob
slack_channel = "aws-notification"
slack_username = "reporter"
kms_key_arn = aws_kms_key.this.arn
lambda_description = "Lambda function which sends notifications to Slack"
log_events = true
tags = {
Name = "cloudwatch-alerts-to-slack"
}
}
resource "aws_cloudwatch_metric_alarm" "LambdaDuration" {
alarm_name = "NotifySlackDuration"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = "1"
metric_name = "Duration"
namespace = "AWS/Lambda"
period = "60"
statistic = "Average"
threshold = "5000"
alarm_description = "Duration of notifying slack exceeds threshold"
alarm_actions = [module.notify_slack.this_slack_topic_arn]
dimensions = {
FunctionName = module.notify_slack.notify_slack_lambda_function_name
}
}
https://github.com/terraform-aws-modules/terraform-aws-notify-slack/blob/master/examples/cloudwatch-alerts-to-slack/main.tf
まとめ
公式とはいえ外部にあるmoduleだと、例えば最新の機能を入れたい場合にmoduleの反映を待たないといけないですし、そういう理由以外でもカスタマイズすることが難しく、また、moduleが勝手にアップデートされることが嬉しくないことも多いため、実際に使うのであればローカルにmoduleまるごどcloneして利用するのがいいのではないでしょうか。
SNSのSlack通知やACMに関してはほぼそのまま使っても問題ないと思います。
今はVPC一通りとALBがあればECS on Fargateでクラスタを作ればサービスを上げられるので(DBとかは別にして)、Terraformで管理したいけど書き方が難しいという場合は使ってみるのもありなのではないでしょうか(そんなに難しくないですが…)。