Ansible: Como encontrar o ID da rota conectado a uma sub-rede

3

Eu tenho um VPC com algumas rotas e sub-redes. Eu quero que o ansible funcione com ele, mas não consigo ver uma maneira de vincular a sub-rede com o ID da tabela de rotas. Eu usei os módulos ec2_vpc_route_table_facts, ec2_vpc_subnet_facts e ec2_vpc_net_facts, mas, a menos que esteja faltando alguma coisa, nenhum deles fornecerá informações sobre qual sub-rede está associada à tabela de rotas.

TASK [ec2_vpc_route_table_facts] ***********************************************
ok: [localhost]

TASK [display routes] **********************************************************
ok: [localhost] => {
    "msg": {
        "changed": false, 
        "route_tables": [
            {
                "id": "rtb-83fd25e7", 
                "routes": [
                    {
                        "destination_cidr_block": "172.31.0.0/16", 
                        "gateway_id": "local", 
                        "instance_id": null, 
                        "interface_id": null, 
                        "origin": "CreateRouteTable", 
                        "state": "active", 
                        "vpc_peering_connection_id": null
                    }, 
                    {
                        "destination_cidr_block": "0.0.0.0/0", 
                        "gateway_id": "igw-6f792c0a", 
                        "instance_id": null, 
                        "interface_id": null, 
                        "origin": "CreateRoute", 
                        "state": "active", 
                        "vpc_peering_connection_id": null
                    }
                ], 
                "tags": {}, 
                "vpc_id": "vpc-e749a683"
            }, 
            {
                "id": "rtb-abf02bcf", 
                "routes": [
                    {
                        "destination_cidr_block": "172.31.0.0/16", 
                        "gateway_id": "local", 
                        "instance_id": null, 
                        "interface_id": null, 
                        "origin": "CreateRouteTable", 
                        "state": "active", 
                        "vpc_peering_connection_id": null
                    }
                ], 
                "tags": {}, 
                "vpc_id": "vpc-e749a683"
            }
        ]
    }
}

TASK [ec2_vpc_subnet_facts] ****************************************************
ok: [localhost]

TASK [display subnets] *********************************************************
ok: [localhost] => {
    "msg": {
        "changed": false, 
        "subnets": [
            {
                "availability_zone": "eu-west-1b", 
                "available_ip_address_count": 4091, 
                "cidr_block": "172.31.16.0/20", 
                "default_for_az": "true", 
                "id": "subnet-3ac33c4c", 
                "map_public_ip_on_launch": "true", 
                "state": "available", 
                "tags": {}, 
                "vpc_id": "vpc-e749a683"
            }, 
            {
                "availability_zone": "eu-west-1c", 
                "available_ip_address_count": 4091, 
                "cidr_block": "172.31.32.0/20", 
                "default_for_az": "true", 
                "id": "subnet-4efbef17", 
                "map_public_ip_on_launch": "true", 
                "state": "available", 
                "tags": {}, 
                "vpc_id": "vpc-e749a683"
            }, 
            {
                "availability_zone": "eu-west-1a", 
                "available_ip_address_count": 4091, 
                "cidr_block": "172.31.0.0/20", 
                "default_for_az": "true", 
                "id": "subnet-9a3deafe", 
                "map_public_ip_on_launch": "true", 
                "state": "available", 
                "tags": {}, 
                "vpc_id": "vpc-e749a683"
            }
        ]
    }
}

A única maneira que vejo para fazer isso funcionar é incluir tags na rota com um valor sensato (como o ID da sub-rede). Mas isso ainda precisaria de alguém para mantê-lo atualizado, não há como automatizar isso da Ansible, está lá?

    
por Max Allan 23.04.2016 / 20:25

2 respostas

1

Acho que um plugin de filtro bem colocado pode ajudá-lo nessa situação. Por exemplo, se você souber o id da tabela de rotas, poderá escrever uma função python simples para recuperar uma lista de subnet_ids associadas ao id da tabela de rotas. Você colocará esse filtro na raiz do seu diretório ansible.

Exemplo abaixo .... filter_plugins / example.py

def get_all_subnet_ids_in_route_table(route_table_id, region=None):
    """
    Args:
        route_table_id (str): The route table id you are retrieving subnets for.

    Kwargs:
        region (str): The aws region in which the route table exists.

    Basic Usage:
        >>> get_all_subnet_ids_in_route_table("rtb-1234567", "us-west-2")
        ['subnet-1234567', 'subnet-7654321']

    Returns:
        List of subnet ids
    """
    subnet_ids = list()
    client = boto3.client('ec2', region_name=region)
    params = {
        'RouteTableIds': [route_table_id]
    }
    routes = client.describe_route_tables(**params)
    if routes:
        for route in routes['RouteTables']:
            for association in route['Associations']:
                if association.get('SubnetId', None):
                    subnet_ids.append(association['SubnetId'])
        return subnet_ids
    else:
        raise errors.AnsibleFilterError(
            "No subnets were found for {0}".format(route_table_id)
        )


class FilterModule(object):
    ''' Ansible core jinja2 filters '''

    def filters(self):
        return {
            'get_all_subnet_ids_in_route_table': get_all_subnet_ids_in_route_table
        }

Se você quiser usar esse filtro, seria tão simples quanto fazer o seguinte ...

route_table_id: rtb-1234567
aws_region: eu-west-1
subnet_ids_for_example_rt: "{{ route_table_id | get_all_subnet_ids_in_route_table(aws_region) }}"
    
por 23.04.2016 / 21:26
0

Parece que isso é corrigido no Ansible 2.3 ( link ).

Agora, quando você chamar ec2_vpc_route_table_facts , além de uma routes list, cada tabela de rota retornada também terá uma associations list, que contém qualquer subnet_id (s) associado

{
    "associations": [
        {
            "id": "rtbassoc-02cf4c00",
            "main": false,
            "route_table_id": "rtb-7051d400",
            "subnet_id": "subnet-3099da00"
        }
    ],
    "id": "rtb-7051d400",
    "routes": [
        {
            "destination_cidr_block": "52.123.123.123/32",
            "gateway_id": "igw-96298400",
            "instance_id": null,
            "interface_id": null,
            "state": "active",
            "vpc_peering_connection_id": null
        },
        {
            "destination_cidr_block": "52.123.123.124/32",
            "gateway_id": "igw-96298400",
            "instance_id": null,
            "interface_id": null,
            "state": "active",
            "vpc_peering_connection_id": null
        },
        {
            "destination_cidr_block": "10.69.123.0/24",
            "gateway_id": "local",
            "instance_id": null,
            "interface_id": null,
            "state": "active",
            "vpc_peering_connection_id": null
        }
    ],
    "tags": {
        "Name": "test-gmd-b-routes"
    },
    "vpc_id": "vpc-c5439a00"
}
    
por 31.05.2017 / 21:46