web-dev-qa-db-ja.com

Terraform実行環境のパブリックIPを識別して、セキュリティグループに追加したい

他の環境からのアクセスを防ぐために、Teraform実行環境のパブリックIPを識別し、それをawsセキュリティグループの受信に追加したいと考えています。

現在、variables.tfファイルの値を手動で編集しています。

variables.tf

variable public_ip_address {
  default     = "xx"
}

ローカルホストで「curl ifconfig.co」コマンドを実行し、結果に基づいてセキュリティグループを自動的に設定したい

そのようなことをする方法はありますか?

Local-execの結果をいくつかの変数に入れることでそれを行うことができますが、それを行う方法がわかりません。

私の質問を読んでいただきありがとうございます。

13
sukho

スクリプトなしでそれを行う簡単な方法があります。コツはあなたのIPを取得する_icanhazip.com_のようなウェブサイトを持っていることなので、それをterraformファイルにdataとして設定します:

_data "http" "myip" {
  url = "http://ipv4.icanhazip.com"
}
_

そして、IPを配置したいときはいつでも_data.http.myip.body_を使用するだけです:例:

_ingress {
  from_port = 5432
  to_port = 5432
  protocol = "tcp"
  cidr_blocks = ["${chomp(data.http.myip.body)}/32"]
}
_
  • メモterform chomp()メソッドを使用して、本文に続く末尾のスペースまたは改行を削除しました。

  • http://ipv6.icanhazip.com でipv6を使用できます。 http://icanhazip.com を使用して注意してください。ipv4またはipv6を取得できるためです。

27
Wagner Leonardi

Terraform 0.12以降では、ネイティブのjsondecodeとjsonencodeを使用して、文字列操作に依存するのではなく、信頼性と長期的な再現性を向上させることができます。参考までに、この実装はTerraform 0.12.16でテストされました。

現在利用可能な新しいTerraformメソッドを使用してパブリックIPアドレスを取得するための実装例を以下に示します。出力ブロックが追加され、意図したとおりに機能していることを視覚的に確認できます。

data "http" "my_public_ip" {
  url = "https://ifconfig.co/json"
  request_headers = {
    Accept = "application/json"
  }
}

locals {
  ifconfig_co_json = jsondecode(data.http.my_public_ip.body)
}

output "my_ip_addr" {
  value = local.ifconfig_co_json.ip
}

これをネットワーク上りルールで利用したい場合は、次の操作を実行できます(これは、ブラインドコピーアンドペーストの場合にポートを不必要に開くことなく、例ではテスト容易性のために利用されています)。

ingress {
  from_port = 0
  to_port = 0
  protocol = "-1"
  cidr_blocks = ["${local.ifconfig_co_json.ip)}/32"]
}

参照されているサービスのレートは1分あたり最大1リクエストに制限されているため、ニーズがこれを超える場合は、これを自分でホストしたい場合があります。または、より保証された可用性が必要な場合。 echoipサービスはコンテナー化されているため、ほぼどこでもホストできます。

https://github.com/mpolden/echoip

1
Michael Joy

私が思いつくことができる最もエレガントなソリューションは、「外部データソース」プロバイダーを使用することです。 https://www.terraform.io/docs/providers/external/data_source.html

これは、人々がlocal-exec、null-resource、varsを組み合わせてローカルに何かを注入するような種類の目的のために書かれました。

とにかく、私はあなたが小さなスクリプトを書かずにこれを行うことができると確信しています。事は「外部データソース」がJSONを読むことを期待していることです。したがって、私の例では、プログラムでJSON文字列を作成し、そのプログラムを呼び出しました。これは、echoまたはjqを使用して1つのライナーで行うことができると確信しています...

ここに私のmain.tfファイルがあります:

data "external" "example" {
  program = ["sh", "test.sh" ]
}

output "commandout" {
  value = "${data.external.example.result}"
}

ここに私のシェルスクリプト(test.sh)があります:

#!/bin/bash

echo {\"ip\":\""`hostname -I`"\"}

技術的には、このような状況が発生すると、以下を使用できます。

${data.external.example.result}

Var入力として。

これは、terraform出力を使用した私の実際の例です。

data.external.example: Refreshing state...

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

commandout = {
  ip = 10.0.2.15
}

ご了承ください hostname -Iは、NIC=)が1つしかない場合は問題ありません。それ以外の場合は、別のコマンドを使用するか、出力をカットして目的の結果を得ます。

1
d1ll1nger