Terraform如何获取aws_lb的IP地址 [英] Terraform how to get IP address of aws_lb

查看:126
本文介绍了Terraform如何获取aws_lb的IP地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Terraform创建aws_lb时是否可以获取aws_lb资源的分配IP地址?

If there a way to get the assigned IP address of an aws_lb resource at the time aws_lb is created by Terraform?

AWS文档-NLB-要找到要列入白名单的私有IP地址,我们可以找到与ELB关联的IP地址.

As in AWS documentation - NLB - To find the private IP addresses to whitelist, we can find out the IP address associated to ELB.

  1. 通过 https://console.aws.amazon.com/ec2/<打开Amazon EC2控制台./a>.
  2. 在导航窗格中,选择网络接口".
  3. 在搜索字段中,键入网络负载平衡器的名称. 每个负载均衡器子网有一个网络接口.
  4. 在每个网络接口的详细信息"选项卡上,从以下地址复制地址: 主专用IPv4 IP .
  1. Open the Amazon EC2 console at https://console.aws.amazon.com/ec2/.
  2. In the navigation pane, choose Network Interfaces.
  3. In the search field, type the name of your Network Load Balancer. There is one network interface per load balancer subnet.
  4. On the Details tab for each network interface, copy the address from Primary private IPv4 IP.

背景

由于网络负载平衡器不能像考虑了 aws_network_interface ,但它不能正常工作

Considered aws_network_interface but it does not work with an error.

错误:找不到匹配的网络接口

Error: no matching network interface found

我还认为数据源假定资源已经存在,并且不能用于Terraform创建的资源.

Also I think datasource assumes the resource already exists and cannot be used for the resource to be created by Terraform.

推荐答案

使用外部提供程序

使用从外部提供程序调用的Python/boto3获取NLB IP.

Using external provider

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}"
}

get_nlb_private_ips.py

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()

使用aws_network_interfaces数据源

aws_lb创建完成之后.

Using aws_network_interfaces datasource

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])}"
}

这篇关于Terraform如何获取aws_lb的IP地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆