If there a way to get the assigned IP address of an aws_lb resource at the time aws_lb is created by Terraform?
As in AWS documentation - NLB - To find the private IP addresses to whitelist, we can find out the IP address associated to ELB.
To be able to setup security group to white list the ELB IP address as Network Load Balancer cannot not have Security Group as in Network Load Balancers don't have Security Groups.
Considered aws_network_interface but it does not work with an error.
Error: no matching network interface found
Also I think datasource assumes the resource already exists and cannot be used for the resource to be created by Terraform.
Resource: aws_eip. Provides an Elastic IP resource. Note: EIP may require IGW to exist prior to association. Use depends_on to set an explicit dependency on the IGW.
Data Source: aws_lb_target_group Note: aws_alb_target_group is known as aws_lb_target_group . The functionality is identical. Provides information about a Load Balancer Target Group. This data source can prove useful when a module accepts an LB Target Group as an input variable and needs to know its attributes.
The trick is having a website such as icanhazip.com which retrieve your IP, so set it in your terraform file as data: 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"] }
Find private IP addresses associated with load balancer elastic network interfaces using the AWS Management Console 1. Open the Amazon Elastic Compute Cloud (Amazon EC2) console. 2. Under Load Balancing, choose Load Balancers from the navigation pane. 3. Select the load balancer that you're finding IP addresses for.
A way to get the IP address from alb_lb (NLB) so that the white listing IP in Security Group, etc can be possible. Being able to create aws_security_group and set the IP addresses of NLB at the time alb_lb is created.
More elegent solution using only HCL in Terraform :
data "aws_network_interface" "lb" {
for_each = var.subnets
filter {
name = "description"
values = ["ELB ${aws_lb.example_lb.arn_suffix}"]
}
filter {
name = "subnet-id"
values = [each.value]
}
}
resource "aws_security_group" "lb_sg" {
vpc_id = var.vpc_id
ingress {
from_port = 0
to_port = 0
protocol = "tcp"
cidr_blocks = formatlist("%s/32", [for eni in data.aws_network_interface.lb : eni.private_ip])
description = "Allow connection from NLB"
}
}
Source : https://github.com/terraform-providers/terraform-provider-aws/issues/3007
Hope this helps.
Get the NLB IP using Python/boto3 invoking from external provider.
variable "nlb_name" {
}
variable "vpc_id" {
}
variable "region" {
}
data "external" "get_nlb_ips" {
program = ["python", "${path.module}/get_nlb_private_ips.py"]
query = {
aws_nlb_name = "${var.nlb_name}"
aws_vpc_id = "${var.vpc_id}"
aws_region = "${var.region}"
}
}
output "aws_nlb_ip_decoded" {
value = "${jsondecode(data.external.get_nlb_ips.result.private_ips)}"
}
output "aws_nlb_ip_encoded" {
value = "${data.external.get_nlb_ips.result.private_ips}"
}
import boto3
import json
import sys
def json_serial(obj):
"""JSON serializer for objects not serializable by default json code
Args:
obj: object to serialize into JSON
"""
_serialize = {
"int": lambda o: int(o),
"float": lambda o: float(o),
"decimal": lambda o: float(o) if o % 1 > 0 else int(o),
"date": lambda o: o.isoformat(),
"datetime": lambda o: o.isoformat(),
"str": lambda o: o,
}
return _serialize[type(obj).__name__.lower()](obj)
def pretty_json(dict):
"""
Pretty print Python dictionary
Args:
dict: Python dictionary
Returns:
Pretty JSON
"""
return json.dumps(dict, indent=2, default=json_serial, sort_keys=True, )
def get_nlb_private_ips(data):
ec2 = boto3.client('ec2', region_name=data['aws_region'])
response = ec2.describe_network_interfaces(
Filters=[
{
'Name': 'description',
'Values': [
"ELB net/{AWS_NLB_NAME}/*".format(
AWS_NLB_NAME=data['aws_nlb_name'])
]
},
{
'Name': 'vpc-id',
'Values': [
data['aws_vpc_id']
]
},
{
'Name': 'status',
'Values': [
"in-use"
]
},
{
'Name': 'attachment.status',
'Values': [
"attached"
]
}
]
)
# print(pretty_json(response))
interfaces = response['NetworkInterfaces']
# ifs = list(map(lamba index: interfaces[index]['PrivateIpAddresses'], xrange(len(interfaces))))
# --------------------------------------------------------------------------------
# Private IP addresses associated to an interface (ENI)
# Each association has the format:
# {
# "Association": {
# "IpOwnerId": "693054447076",
# "PublicDnsName": "ec2-52-88-47-177.us-west-2.compute.amazonaws.com",
# "PublicIp": "52.88.47.177"
# },
# "Primary": true,
# "PrivateDnsName": "ip-10-5-1-205.us-west-2.compute.internal",
# "PrivateIpAddress": "10.5.1.205"
# },
# --------------------------------------------------------------------------------
associations = [
association for interface in interfaces
for association in interface['PrivateIpAddresses']
]
# --------------------------------------------------------------------------------
# Get IP from each IP association
# --------------------------------------------------------------------------------
private_ips = [
association['PrivateIpAddress'] for association in associations
]
return private_ips
def load_json():
data = json.load(sys.stdin)
return data
def main():
data = load_json()
"""
print(data['aws_region'])
print(data['aws_vpc_id'])
print(data['aws_nlb_name'])
"""
ips = get_nlb_private_ips(data)
print(json.dumps({"private_ips": json.dumps(ips)}))
if __name__ == '__main__':
main()
After aws_lb has been created.
data "aws_network_interfaces" "this" {
filter {
name = "description"
values = ["ELB net/${aws_lb.this.name}/*"]
}
filter {
name = "vpc-id"
values = ["${var.vpc_id}"]
}
filter {
name = "status"
values = ["in-use"]
}
filter {
name = "attachment.status"
values = ["attached"]
}
}
locals {
nlb_interface_ids = "${flatten(["${data.aws_network_interfaces.this.ids}"])}"
}
data "aws_network_interface" "ifs" {
count = "${length(local.nlb_interface_ids)}"
id = "${local.nlb_interface_ids[count.index]}"
}
output "aws_lb_network_interface_ips" {
value = "${flatten([data.aws_network_interface.ifs.*.private_ips])}"
}
The solution from @user1297406 leads to an exeption. data.aws_network_interface.lb is tuple with 2 elements.
Correct syntax is:
data "aws_network_interface" "lb" {
count = length(var.vpc_private_subnets)
filter {
name = "description"
values = ["ELB ${aws_alb.lb.arn_suffix}"]
}
filter {
name = "subnet-id"
values = [var.vpc_private_subnets[count.index]]
}
}
resource "aws_security_group_rule" "lb_sg" {
from_port = 0
protocol = "TCP"
to_port = 0
type = "ingress"
cidr_blocks = formatlist("%s/32", data.aws_network_interface.lb.*.private_ip)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With