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「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、これ以外にも色々使い道がありそうですね!何かまた思いついたら書いてみたいと思います。
2020/01/24追記: エラーになりました
本機構を入れたコードを terraform apply
したところエラーになりました。
Error: HTTP request error. Response code: 403
原因調査したところ、IP取得に使っていたサイト https://ifconfig.co/ip がセキュリティチェック(reCaptcha)を導入したようです… パッとこれの解決方法がわからなかったので、ひとまず同様のサービスを提供している別サイト http://ipv4.icanhazip.com/ に切り替えたところ動作しました。