tjinjin's blog

さらなる高みに1nmずつ近づくブログ

最近Terraformで使ってみたresourceのサンプル集

とりあえずやってみたのでどこかに残したいと思ったので、ブログに書いておきます。

Terraform v0.6.16を想定しています。

Cloudwatchの設定をする

インスタンス作成だけでなく、合わせてCloudwatchで監視したいと思った時に。

resource "aws_cloudwatch_metric_alarm" "ec2_alarm" {
    alarm_name = "[FATAL][ec2] StatusCheckFailed"
    comparison_operator = "GreaterThanOrEqualToThreshold"
    evaluation_periods = "1"
    metric_name = "StatusCheckFailed"
    namespace = "AWS/EC2"
    period = "180"
    statistic = "Maximum"
    threshold = "1"
    alarm_description = "Created by Terraform"
    alarm_actions = ["${var.send_notification_to}"]
    insufficient_data_actions = ["${var.send_notification_to}"]
    ok_actions = ["${var.send_notification_to}"]
    dimensions = {
        InstanceId = "${aws_instance.web.id}"
    }
}

監視したい項目に合わせてmetric_nameなどを変更していけば何にでも使えそうです。

Elasticsearch serviceを追加する

最近何かと話題の可視化でも使えるElasticsearch serviceです。kibanaがデフォルトで入っているので、起動後すぐに利用できます。

resource "aws_elasticsearch_domain" "es" {
    domain_name = "tf-test"
    advanced_options {
        "rest.action.multi.allow_explicit_index" = true
    }

    access_policies = <<CONFIG
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "es:*",
            "Principal": "*",
            "Effect": "Allow",
            "Condition": {
                "IpAddress": {"aws:SourceIp": ["xxx.xxx.xxx.xxx"]}
            }
        }
    ]
}
CONFIG

    snapshot_options {
        automated_snapshot_start_hour = 23
    }

    ebs_options {
        ebs_enabled = true
        volume_type = "gp2"
        volume_size = 10

    }

    cluster_config {
        instance_type = "t2.micro.elasticsearch"
        instance_count = 1
    }


    tags {
      Domain = "TestDomain"
    }

    lifecycle {
        ignore_changes =["access_policies"]
    }
}

access_policies の設定が悪いのかapplyするたびに変更が走ってしまうので、ignore_changesを指定しています(よくない。

S3のVPCエンドポイントを追加する

S3のVPCエンドポイントはVPC内からS3にパブリックなネットワークを通らず直接アクセスできるような仕組みです。

詳細はこちら。

docs.aws.amazon.com

blog.serverworks.co.jp

resource "aws_vpc_endpoint" "private-s3" {
    vpc_id = "${aws_vpc.main.id}"
    service_name = "com.amazonaws.ap-northeast-1.s3"
    route_table_ids = ["${aws_route_table.public.id}", "${aws_route_table.private.id}"]
}

今回は東京リージョンを想定していますが、利用しているリージョンによってservice_nameが変わります。

VPC Flow logsを追加する

VPC Flow logsはVPC内の通信ログを取得できる仕組みです。ネットワークがどこまで届いているのか切り分けに重宝しそうです。

詳細はこちら。

docs.aws.amazon.com

dev.classmethod.jp

resource "aws_flow_log" "vpc_flow_log" {
    log_group_name = "test-vpc-flow-log"
    iam_role_arn = "${aws_iam_role.vpc_flow_log_role.arn}"
    vpc_id = "${aws_vpc.main.id}"
    traffic_type = "ALL"
}

resource "aws_iam_role" "vpc_flow_log_role" {
    name = "test-vpc-flow-log"
    assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "vpc-flow-logs.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

resource "aws_iam_role_policy" "vpc_role_policy" {
    name = "test-vpc-flow-log"
    role = "${aws_iam_role.vpc_flow_log_role.id}"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogGroups",
        "logs:DescribeLogStreams"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
EOF
}

traffic_typeはALL/ACCEPT/REJECTがあり、今のところALLを使おうと思ってます。ログが膨大でお金かかるようであれば、REJECTだけとるイメージでしょうか。

取得したデータはENI毎にCloudwatch logsで確認できます。

まとめ

Terraform無しではなんにもできない人間になりそうです。ただTerraform使うにせよ、AWSのサービス側を理解していないといけないので、それぞれの設定がどんな意味なのかをドキュメントなりで確認する必要がありそう。AWSのドキュメントをいきなり見たくない場合は、Black Beltシリーズを読むといい感じだと思います!

aws.amazon.com

公式リンク

www.terraform.io