Skip to content

Commit

Permalink
[WIP] Layer 2 example including interconnection and VRF
Browse files Browse the repository at this point in the history
  • Loading branch information
ctreatma committed Oct 17, 2024
1 parent fa993fd commit c2b39fd
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 0 deletions.
34 changes: 34 additions & 0 deletions examples/layer2/README.md
Original file line number Diff line number Diff line change
@@ -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=<some_value>"
```
127 changes: 127 additions & 0 deletions examples/layer2/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
---
- name: Equinix Metal Example Playbook
hosts: localhost
gather_facts: no
tasks:
- name: Include the required variables
include_vars: "vars/equinix_metal_vars.yml"

- name: Look up Fabric credentials from env
set_fact:
equinix_client_id: "{{ lookup('env', 'EQUINIX_CLIENT_ID') }}"
equinix_client_secret: "{{ lookup('env', 'EQUINIX_CLIENT_SECRET') }}"

- name: Compute peering ranges for VRF and virtual circuit
set_fact:
vrf_peering_ip_range: "{{ vrf_peering_ip_network }}/29"
vrf_vc_peering_ip_range: "{{ vrf_peering_ip_network }}/30"

# Equinix resources
- name: Create a project
equinix.cloud.metal_project:
name: "{{ project_name }}"
register: project

- name: Enable BGP for the project
equinix.cloud.metal_project_bgp_config:
project_id: "{{ project.id }}"
deployment_type: local
asn: 65000

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

# 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 <<EOF >> /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_vc_peering_ip_range | ansible.utils.nthhost(1) }}"
metal_ip: "{{ vrf_vc_peering_ip_range | ansible.utils.nthhost(2) }}"
subnet: "{{ vrf_vc_peering_ip_range }}"
md5: "{{ bgp_md5_password }}"
11 changes: 11 additions & 0 deletions examples/layer2/vars/equinix_metal_vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
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_network: 169.254.0.0
vrf_peering_asn: 65100
aws_network_cidr: 172.16.0.0/16
fabric_connection_name: ansible-layer2-example

0 comments on commit c2b39fd

Please sign in to comment.