アプリケーションエンジニアが Terraform 触ってみた

これはestie Advent Calendar 2021 19日目の記事です

はじめに

普段はRuby on Rails や Python を使って開発をしている、アプリケーションエンジニアのえりりんです。

最近、社内SREチームのみなさんが Terraform を使って既存のインフラリソースをコードに落とし込んでくれています(いわゆるIaCというやつですね)。

社内ツールに http で動作しているものがあり、これを https 化したいねという話が出ていたので、私がチャレンジしてみることにしました。

Terraform って?

インフラをコードで管理するためのツールでメジャーなもの。

例えば、ECS タスクでアプリケーションを動かすために必要なリソースを宣言的に書くことができます。

前提

  • 既に動いているサイトである

  • 既にロードバランサー・ターゲットグループが設定されている

  • サイトのインフラは Terraform コードにてすでに管理されている

  • 既に http / https それぞれのリスナールールが存在する

ゴール

  • 現在 http で動いているサイトを https にする

  • 裏側のアプリは http で動作しており、ALB で http / https を切り替えている

  • それをアプリケーションエンジニアである私が修正を完遂させる

TODO

  • ECSサービスのターゲットグループが紐づくリスナーを http から https に変更

  • http リスナーには https へリダイレクトするリスナールールを追加

本編

参考としたドキュメントはこのあたりです。

http と https のリスナーは既にありました。

resource "aws_alb_listener_rule" "forward_xxx" {
  listener_arn = aws_alb_listener.http.arn

  action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.app.arn
  }
  condition {
    host_header {
      values = [
        "xxx.co.jp"
      ]
    }
  }
}

http リスナーに紐付いている既存のリスナールールです

これを参考に新しく https のリスナールールをつくります

resource "aws_alb_listener_rule" "forward_xxx" {
  listener_arn = aws_alb_listener.https.arn

  action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.app.arn
  }
  condition {
    host_header {
      values = [
        "xxx.co.jp"
      ]
    }
  }
}

これで https のリスナールールが作成できました

続いて、http でアクセスがあったときに https にリダイレクトできるように変更します
ドキュメントに以下のようなサンプルがあったので、これをもとに変更します

# Redirect action

resource "aws_lb_listener_rule" "redirect_http_to_https" {
  listener_arn = aws_lb_listener.front_end.arn

  action {
    type = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }

  condition {
    http_header {
      http_header_name = "X-Forwarded-For"
      values           = ["192.168.1.*"]
    }
  }
}

condition block にはいくつかのオプションがあるようですhttps://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule#condition-blocks

サンブルでは http_header を使っています。しかし、特定のURLからアクセスがあった場合にのみリダイレクトをしたいので host_header オプションを使います。
なぜなら該当のリスナールールは他のサイトと共有しているためです。

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule#host_header 

上記条件を元に書いてみました

resource "aws_alb_listener_rule" "redirect_https" {
  listener_arn = aws_alb_listener.http.arn

  action {
    type = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }

  condition {
    # host が value の値に一致するときのみ適用される
    host_header {
      values = [
        "xxx.co.jp"
      ]
    }
  }
}

この設定で terraform plan -> terraform apply をしてみました

変更されましたね!

ちゃんとアクセスできるか確認します

できました! !

続いてリダイレクトできるか確認します

無事、アプリケーションエンジニアが Terraform を触ってインフラ構成を変更することができました!!!!

感想

インフラ構成もコード化できるとアプリケーションエンジニアの私でも管理できそう!

という感じがしてとても良かったです。

また、インフラ環境をコードにしてGitHub管理することで履歴管理できるようになるというのもとても良いなと思いました!

ただ、Terraform Apply ってしたらインフラ構成変わってしまうというのはちょっと怖いかも。。。と思ってしまいました笑

ドキュメントを見ると、今回のALB周り以外でもいろんな設定をコード管理できるようなので、よりできることを広げていきたいです!