I want to identify the public IP of the terraform execution environment
and add it to aws security group inbound to prevent access from other environments.
Currently, I am manually editing the values in the variables.tf file.
variables.tf
variable public_ip_address {
default = "xx"
}
I would like to execute the "curl ifconfig.co" command on the local host and automatically set the security group based on the result
Is there a way to do such things?
I could do it by putting the result of local-exec in some variable
but I don't know how to do it.
Thank you for reading my question.
There's an easier way to do that without any scripts. The trick is having a website such as icanhazip.com
which retrieve your IP, so set it in your terraform file as data
:
data "http" "myip" {
url = "http://ipv4.icanhazip.com"
}
And whenever you want to place your IP just use data.http.myip.body
, example:
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
cidr_blocks = ["${chomp(data.http.myip.body)}/32"]
}
Note I used terraform chomp()
method to remove any trailing space or new line which comes with body.
You can use your ipv6 with http://ipv6.icanhazip.com. Take care by just using http://icanhazip.com because it can retrieve ipv4 or ipv6
The most elegant solution I could come up with is to use the "external data source" provider. https://www.terraform.io/docs/providers/external/data_source.html
This was written for these kind of purposes where people were combining local-exec, null-resource and vars to inject something locally.
Anyway, I'm sure you can do this without writing a small script. The thing is the "external data source" expects to read JSON. So in my example I just built a JSON string in a program and then call that program. I'm sure this could be done in a one liner using echo or jq...
Here is my main.tf file:
data "external" "example" {
program = ["sh", "test.sh" ]
}
output "commandout" {
value = "${data.external.example.result}"
}
Here is my shell script (test.sh):
#!/bin/bash
echo {\"ip\":\""`hostname -I`"\"}
Technically once you have this situation you can use:
${data.external.example.result}
As your var input.
Here is my working example with terraform output.
data.external.example: Refreshing state...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
commandout = {
ip = 10.0.2.15
}
Note that hostname -I
is ok if you only have one NIC :) Otherwise use an alternative command or cut the output for your desired results.