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 8, 2024
1 parent d31f17a commit e1f46b6
Show file tree
Hide file tree
Showing 3 changed files with 149 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
```
108 changes: 108 additions & 0 deletions examples/layer2/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
- 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:
- 192.168.200.0/25
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: 192.168.200.0
cidr: 25
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
# TODO: gateway module does not expose the
# gateway IP so I'm hard-coding it for now.
# In the future it should be referenced as
# {{gateway.ip}} (or similar) instead. The
# device IP address should also be calculated
# rather than hard-coded
- 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 192.168.200.2
netmask 255.255.255.128
post-up route add -net 192.168.200.0/25 gw 192.168.200.1
post-up route add -net {{aws_network_cidr}} gw 192.168.200.1
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 }}"

# NOTE: I initially wrote this as a redundant connection
# but decided that was unnecessary; Ansible attempted to
# update the connection in place and threw a weird validation
# error from pydantic. IIRC redundancy can't be updated
# in place, so we should probably protect against that but
# also the error message was not useful
- name: create a Metal-billed VRF interconnection
equinix.cloud.metal_connection:
project_id: "{{ project.id }}"
metro: "{{ metro }}"
name: "{{ interconnection_name }}"
type: "shared"
speed: "1Gbps"
service_token_type: a_side
redundancy: primary
vrfs:
- "{{ vrf.id }}"
7 changes: 7 additions & 0 deletions examples/layer2/vars/equinix_metal_vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
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"
aws_network_cidr: 10.0.0.0/24

0 comments on commit e1f46b6

Please sign in to comment.