From 5ab16934286614689a394b92f52e7fcc06f2030d Mon Sep 17 00:00:00 2001 From: Charles Treatman Date: Thu, 3 Oct 2024 09:39:12 -0500 Subject: [PATCH] [WIP] Layer 2 example including interconnection and VRF --- examples/layer2/README.md | 34 ++++++ examples/layer2/main.yml | 113 ++++++++++++++++++++ examples/layer2/vars/equinix_metal_vars.yml | 10 ++ 3 files changed, 157 insertions(+) create mode 100644 examples/layer2/README.md create mode 100644 examples/layer2/main.yml create mode 100644 examples/layer2/vars/equinix_metal_vars.yml diff --git a/examples/layer2/README.md b/examples/layer2/README.md new file mode 100644 index 0000000..b251538 --- /dev/null +++ b/examples/layer2/README.md @@ -0,0 +1,34 @@ +# Layer 2 networking with Equinix Metal + +This example playbook demonstrates the use of the `equinix.cloud.metal_connection`, `equinix.cloud.metal_device`, and `equinix.cloud.metal_port` modules to configure Layer 2 connectivity from an Equinix Metal device to an AWS S3 bucket over a Metal-billed Fabric interconnection. + +## Overview + +The [playbook](main.yml) creates a new project, creates 2 VLANs, provisions a device, and configures the device through different [network types](https://deploy.equinix.com/developers/docs/metal/layer2-networking/overview/#network-configuration-types). + + +## Prerequisites + +Before running the playbook, you will need to have the following: + +- Ansible installed on your local machine. +- The Equinix Ansible Collection installed. You can install it using the following command: + ```bash + ansible-galaxy collection install equinix.cloud + ``` +- An Equinix Metal API token. You can obtain an API token from the Equinix Metal Portal. Set the environment variable METAL_AUTH_TOKEN to your API token: + ```bash + export METAL_AUTH_TOKEN=your_api_token_here + ``` + +## Variables + +You can customize some variables from [vars/equinix_metal_vars.yml](vars/equinix_metal_vars.yml). + +## Running the Playbook + +To run the playbook, navigate to the directory containing the playbook file `main.yml` and run the following command: + +```bash +ansible-playbook main.yml -extra-vars "bgp_md5_password=" +``` diff --git a/examples/layer2/main.yml b/examples/layer2/main.yml new file mode 100644 index 0000000..4869b88 --- /dev/null +++ b/examples/layer2/main.yml @@ -0,0 +1,113 @@ +--- +- name: Equinix Metal Example Playbook + hosts: localhost + gather_facts: no + tasks: + - name: Include the required variables + include_vars: "vars/equinix_metal_vars.yml" + + # Equinix resources + - name: Create a project + equinix.cloud.metal_project: + name: "{{ project_name }}" + register: project + + - name: create a vlan + equinix.cloud.metal_vlan: + project_id: "{{ project.id }}" + metro: "{{ metro }}" + vxlan: "1234" + register: vlan + + - name: create a VRF + equinix.cloud.metal_vrf: + name: example-vrf + metro: "{{ metro }}" + local_asn: 65000 + ip_ranges: + - "{{ vrf_peering_ip_range }}" + - "{{ vrf_gateway_ip_range }}" + project_id: "{{ project.id }}" + register: vrf + + - name: create a VRF IP reservation + equinix.cloud.metal_reserved_ip_block: + project_id: "{{ project.id }}" + vrf_id: "{{ vrf.id }}" + type: "vrf" + metro: "{{ metro }}" + network: "{{ vrf_gateway_ip_range | split('/') | first }}" + cidr: "{{ vrf_gateway_ip_range | split('/') | last }}" + register: vrf_ip_reservation + + - name: create a VRF Metal Gateway + equinix.cloud.metal_gateway: + project_id: "{{ project.id }}" + ip_reservation_id: "{{ vrf_ip_reservation.id }}" + virtual_network_id: "{{ vlan.id }}" + register: gateway + + - debug: + var: vrf_ip_reservation + + # Create a device + - name: Create a device + equinix.cloud.metal_device: + project_id: "{{ project.id }}" + metro: "{{ metro }}" + hostname: "{{ device_hostname }}" + operating_system: "{{ operating_system }}" + plan: "{{ plan }}" + state: present + userdata: |2 + #!/bin/bash + + cat <> /etc/network/interfaces + auto bond0.{{vlan.vxlan}} + iface bond0.{{vlan.vxlan}} inet static + address {{ vrf_gateway_ip_range | ansible.utils.nthhost(2) }} + netmask {{ vrf_ip_reservation.netmask }} + post-up route add -net {{ vrf_gateway_ip_range }} gw {{ vrf_ip_reservation.gateway }} + post-up route add -net {{ aws_network_cidr }} gw {{ vrf_ip_reservation.gateway }} + EOF + + systemctl restart networking + register: device + + - name: capture port ids for device + set_fact: + bond_port_id: "{{ device.network_ports | selectattr('name', 'match', 'bond0') | map(attribute='id') | first }}" + eth1_port_id: "{{ device.network_ports | selectattr('name', 'match', 'eth1') | map(attribute='id') | first }}" + + - name: convert bond port to hybrid bonded mode + equinix.cloud.metal_port: + id: "{{ bond_port_id }}" + bonded: true + layer2: false + vlan_ids: + - "{{ vlan.id }}" + + - name: create a Metal-billed VRF interconnection + equinix.cloud.metal_connection: + project_id: "{{ project.id }}" + metro: "{{ metro }}" + name: "{{ interconnection_name }}" + type: "shared" + speed: "500Mbps" + service_token_type: a_side + redundancy: primary + vrfs: + - "{{ vrf.id }}" + register: connection + + # TODO this task will fail until the service token is + # redeemed on the Fabric side; consider checking virtual + # circuit status and skipping if it is `pending` + - name: configure BGP for interconnection virtual circuit + equinix.cloud.metal_virtual_circuit: + id: "{{ connection.ports[0].virtual_circuits[0].id }}" + peer_asn: "{{ vrf_peering_asn }}" + customer_ip: "{{ vrf_peering_ip_range | ansible.utils.nthhost(1) }}" + metal_ip: "{{ vrf_peering_ip_range | ansible.utils.nthhost(2) }}" + subnet: "{{ vrf_peering_ip_range }}" + md5: "{{ bgp_md5_password }}" diff --git a/examples/layer2/vars/equinix_metal_vars.yml b/examples/layer2/vars/equinix_metal_vars.yml new file mode 100644 index 0000000..8513173 --- /dev/null +++ b/examples/layer2/vars/equinix_metal_vars.yml @@ -0,0 +1,10 @@ +project_name: my_metal_layer2_project +device_hostname: layer2-device +metro: sv +operating_system: ubuntu_20_04 +plan: c3.small.x86 +interconnection_name: "layer2 interconnection" +vrf_gateway_ip_range: 192.168.200.0/25 +vrf_peering_ip_range: 169.254.0.0/29 +vrf_peering_asn: 65100 +aws_network_cidr: 172.31.0.0/16