Terraformで自分のパブリックIPを使う方法

やりたいこと

こんにちは、大阪オフィスのかずえです。今回は今週知ったTerraformのテクニックをご紹介します。

現在自分が使っているパブリックIPをTerraform内で使いたいって時、ありますよね。よくあるのがSSHインバウンドの許可IPとして。コンソールだとこちら、選択肢に「マイIP」が出てきて、それを選択すると現在使っているIPがサクッと入力されますよね。

こんな感じで、Terraformでも使っているIPをサクッと参照できるようにします。そのIPを使ってセキュリティグループのルールを作成します。

とはいえ、現在使っているIP以外をセキュリティグループのルールで使いたい場合もありますよね。より実践的にするためこの点にも対応します。変数値を設定した場合はそのCIDRで、設定しなかった場合は現在使っているIPを/32のCIDRにして参照するようにします。

実装方針

TerraformにはHTTPというProviderがあります。この中のData Sourceにhttpがあります。
Data Sourceとは、Terraformで作成していないリソースのパラメータをTerraform内で参照するための機能です。このhttp Data Sourceは何のリソースを扱うかというと、指定URLへのリクエストのレスポンスです。

世の中には現在使っているパブリックIPを返してくれるwebサービスが多数存在します。それらのサービスにリクエストした結果をTerraform 内で使うことができます。

コード

Provider設定

まずは HTTP providerを利用できるようにします。

provider http {
  version = "~> 1.1"
}

terraform init が必要です。

http Data Source

data http ifconfig {
  url = "https://ifconfig.co/ip"
}

url 引数値で設定するリクエスト先には以下条件があります。

  • 200 OK のステータスコードを返す
  • Content-Typeが text/* もしくは application/json

「AWSなんだったらIP取得に http://checkip.amazonaws.com/ を使えば?」と思われた方もいらっしゃるかもしれません。が、 http://checkip.amazonaws.com/ はContent-Typeがレスポンスヘッダーに含まれていないためエラーになり使えませんでした。。

別途IP指定したい時用の変数

variable allowed-cidr {
  default = null
}

CIDRの決定

上記変数が指定されている場合はそれを、ない場合はhttp Data Sourceで取得した現在使っているパブリックIPを代入します。

locals {
  current-ip = chomp(data.http.ifconfig.body)
  allowed-cidr  = (var.allowed-cidr == null) ? "${local.current-ip}/32" : var.allowed-cidr
}

セキュリティグループで利用

踏み台インスタンスにアタッチするセキュリティグループにSSHインバウンドを許可するルールを付与します。

resource aws_security_group bastion {
  name        = "bastion-sg"
  description = "bastion-sg"
  vpc_id      = aws_vpc.vpc.id
}

resource aws_security_group_rule bastion-ssh-ingress {
  type              = "ingress"
  security_group_id = aws_security_group.bastion.id
  protocol          = "tcp"
  from_port         = 22
  to_port           = 22
  cidr_blocks       = [local.allowed-cidr]
}

※ 余談ですが、egress(アウトバウンド)ルールもちゃんと書きましょうね!

まとめ

http Data Sourceを使って、Terraformで現在自分が使っているパブリックIPを参照する方法をご紹介しました。http Data Source、これ以外にも色々使い道がありそうですね!何かまた思いついたら書いてみたいと思います。

参考情報