From a8380af2ccf5aee580e4a6d931f788c3f43da557 Mon Sep 17 00:00:00 2001 From: Charles Treatman Date: Wed, 23 Oct 2024 16:32:39 -0500 Subject: [PATCH] use the right ASN on either end of the interconnection --- examples/layer2/README.md | 19 ++- examples/layer2/aws.yml | 56 --------- examples/layer2/post_fabric.yml | 119 ++++++++++++++++++ examples/layer2/{metal.yml => pre_fabric.yml} | 21 +--- examples/layer2/vars/vars.yml | 4 +- 5 files changed, 130 insertions(+), 89 deletions(-) delete mode 100644 examples/layer2/aws.yml create mode 100644 examples/layer2/post_fabric.yml rename examples/layer2/{metal.yml => pre_fabric.yml} (80%) diff --git a/examples/layer2/README.md b/examples/layer2/README.md index 85620f5..916744f 100644 --- a/examples/layer2/README.md +++ b/examples/layer2/README.md @@ -4,11 +4,11 @@ This example demonstrates the use of the `equinix.cloud.metal_connection`, `equi ## Overview -The [Metal playbook](metal.yml) creates a new project, a VLAN, a VRF, a VRF Metal Gateway, and a device, converts the device to [hybrid bonded mode](https://deploy.equinix.com/developers/docs/metal/layer2-networking/overview/#network-configuration-types), and then creates a Metal-billed VRF interconnection and configures BGP peering settings on the interconnection's virtual circuit. +The [pre-Fabric playbook](pre_fabric.yml) creates a new project, a VLAN, a VRF, a VRF Metal Gateway, and a device, converts the device to [hybrid bonded mode](https://deploy.equinix.com/developers/docs/metal/layer2-networking/overview/#network-configuration-types), and then creates a Metal-billed VRF interconnection and configures BGP peering settings on the interconnection's virtual circuit. Manual intervention is needed in order to finish setting up the interconnection and accept the Direct Connect request in AWS. -The [AWS playbook](aws.yml) creates a new VPC, a VPC endpoint for S3, and a Virtual Private Gateway attached to the specified Direct Connect. +The [post-Fabric playbook](post_fabric.yml) creates a new VPC, a VPC endpoint for S3, and a Virtual Private Gateway attached to the specified Direct Connect, and configures BGP peering between the Direct Connect and your Metal VRF. ## Prerequisites @@ -40,10 +40,10 @@ You can customize some variables, such as Equinix Metal device hostname and IP r This example contains multiple playbooks and requires manual intervention between the playbooks. -To create the Equinix Metal infrastructure for this example, navigate to the directory containing the playbook file `metal.yml` and run the following command: +To create the Equinix Metal infrastructure for this example, navigate to the directory containing the playbook file `pre_fabric.yml` and run the following command: ```bash -ansible-playbook metal.yml -extra-vars "bgp_md5_password=" +ansible-playbook pre_fabric.yml -extra-vars "bgp_md5_password=" ``` *NOTE:* The API performs some validation on the md5 for BGP. For the latest rules refer to [the VRF virtual circuit API docs](https://deploy.equinix.com/developers/api/metal/#tag/Interconnections/operation/updateVirtualCircuit). As of this writing, the md5: @@ -52,7 +52,7 @@ ansible-playbook metal.yml -extra-vars "bgp_md5_password=" * must be a combination of numbers and letters * must contain at least one lowercase, uppercase, and digit character -The last task in the `metal.yml` playbook will print out the service token for your Metal connection: +The last task in the `pre_fabric.yml` playbook will print out the service token for your Metal connection: ```bash TASK [print service token to redeem in Fabric portal] ************************************************************************** @@ -61,13 +61,10 @@ ok: [localhost] => { } ``` -After the Equinix Metal infrastructure is created, you will need to redeem the service token for your connection in the [Fabric portal](https://fabric.equinix.com). -After the Equinix Metal infrastructure is created, you will need to redeem the service token for your connection in the [Equinix portal](https://portal.equinix.com). Navigate to Fabric -> Connect to Provider, choose AWS, and finally AWS Direct Connect. Choose Primary, put in your account number, choose the metro, click next, then choose "Service Token" from the drop down, and put in the service token. +After the Equinix Metal infrastructure is created, you will need to redeem the service token for your connection in the [Equinix portal](https://portal.equinix.com). Navigate to Fabric -> Connect to Provider, choose AWS, and finally AWS Direct Connect. Choose Primary, put in your account number, choose the metro, click next, then choose "Service Token" from the drop down, and put in the service token. You will be prompted to name your connection; **take note of the name you use**, you will need it for the next playbook. -Once the service token is redeemed, you will need to accept the Direct Connect request in the [AWS console](https://console.aws.amazon.com). Take note of the Direct Connect ID and the Direct Connect VLAN when you accept the connection. You will need the ID and VLAN for the next playbook. - -To finish setting up the AWS infrastructure, wait for the connection to be available, then run the following command: +To finish setting up the AWS infrastructure, run the following command which will accept the direct connect request in AWS; wait for the connection to become active; create an AWS VPC, VPC endpoint, and VPN gateway; create a virtual interface connecting the VPC to your direct connect, and configure the Metal side of your interconnection to connect to the virtual interface in AWS: ```bash -ansible-playbook aws.yml --extra-vars "bgp_md5_password=" --extra-vars "aws_connection_id=" --extra-vars "aws_connection_vlan=" +ansible-playbook post_fabric.yml --extra-vars "bgp_md5_password=" --extra-vars "aws_connection_name=" ``` diff --git a/examples/layer2/aws.yml b/examples/layer2/aws.yml deleted file mode 100644 index ec98a88..0000000 --- a/examples/layer2/aws.yml +++ /dev/null @@ -1,56 +0,0 @@ ---- -# NOTE: this playbook should be run _after_: -# 1. Running the metal.yml playbook -# 2. Redeeming the Fabric service token in the Fabric portal -# 3. Accepting the Direct Connect request in the AWS console -- name: Equinix Layer 2 example -- AWS resources - hosts: localhost - gather_facts: no - tasks: - - name: Include the required variables - include_vars: "vars/vars.yml" - - - name: create a VPC - amazon.aws.ec2_vpc_net: - region: "{{ aws_region }}" - name: ansible-equinix-layer2-example - cidr_block: "{{ aws_network_cidr }}" - register: created_vpc - - - name: Gather information about any VPC route table within VPC with ID "{{ created_vpc.vpc.id }}" - amazon.aws.ec2_vpc_route_table_info: - region: "{{ aws_region }}" - filters: - vpc-id: "{{ created_vpc.vpc.id }}" - register: route_table_info - - - name: Create new vpc endpoint with the default policy - amazon.aws.ec2_vpc_endpoint: - region: "{{ aws_region }}" - vpc_id: "{{ created_vpc.vpc.id }}" - service: "com.amazonaws.{{ aws_region }}.s3" - route_table_ids: "{{ route_table_info.route_tables | map(attribute='id') }}" - register: new_vpc_endpoint - - - name: Create a new VGW attached to the VPC - community.aws.ec2_vpc_vgw: - region: "{{ aws_region }}" - vpc_id: "{{ created_vpc.vpc.id }}" - name: ansible-equinix-layer2-example - register: created_vgw - - # TODO this is failing, saying that the virtual gateway - # does not exist, but I can see it...so? - - name: Create an association between VGW and connection - community.aws.directconnect_virtual_interface: - region: "{{ aws_region }}" - state: present - name: "ansible-equinix-layer2-example" - public: false - connection_id: "{{ aws_connection_id }}" - vlan: "{{ aws_connection_vlan }}" - virtual_gateway_id: "{{ created_vgw.vgw.id }}" - customer_address: "{{ metal_peering_ip }}/30" - amazon_address: "{{ aws_peering_ip }}/30" - bgp_asn: "{{ vrf_peering_asn }}" - authentication_key: "{{ bgp_md5_password }}" diff --git a/examples/layer2/post_fabric.yml b/examples/layer2/post_fabric.yml new file mode 100644 index 0000000..99c560b --- /dev/null +++ b/examples/layer2/post_fabric.yml @@ -0,0 +1,119 @@ +--- +# NOTE: this playbook should be run _after_: +# 1. Running the pre_fabric.yml playbook +# 2. Redeeming the Fabric service token in the Fabric portal +- name: Equinix Layer 2 example -- AWS resources + hosts: localhost + gather_facts: no + tasks: + - name: Include the required variables + include_vars: "vars/vars.yml" + + - name: confirm the direct connect + community.aws.directconnect_confirm_connection: + region: "{{ aws_region }}" + name: "{{ aws_connection_name }}" + register: confirm_response + + - name: wait for the direct connect to become available + community.aws.directconnect_connection: + region: "{{ aws_region }}" + name: "{{ aws_connection_name }}" + # The below attributes are required by the community.aws.directconnect_connection + # module but do not appear to be used, since this works for looking up the connection + location: "dummy" + bandwidth: "1Gbps" + state: present + register: connection_response + until: connection_response.connection.connection_state == "available" + retries: 10 + delay: 60 + + - name: create a VPC + amazon.aws.ec2_vpc_net: + region: "{{ aws_region }}" + name: ansible-equinix-layer2-example + cidr_block: "{{ aws_network_cidr }}" + register: created_vpc + + - name: Gather information about any VPC route table within VPC with ID "{{ created_vpc.vpc.id }}" + amazon.aws.ec2_vpc_route_table_info: + region: "{{ aws_region }}" + filters: + vpc-id: "{{ created_vpc.vpc.id }}" + register: route_table_info + + - name: Create new vpc endpoint with the default policy + amazon.aws.ec2_vpc_endpoint: + region: "{{ aws_region }}" + vpc_id: "{{ created_vpc.vpc.id }}" + service: "com.amazonaws.{{ aws_region }}.s3" + route_table_ids: "{{ route_table_info.route_tables | map(attribute='id') }}" + register: new_vpc_endpoint + + - name: Create a new VGW attached to the VPC + community.aws.ec2_vpc_vgw: + region: "{{ aws_region }}" + vpc_id: "{{ created_vpc.vpc.id }}" + name: ansible-equinix-layer2-example + register: created_vgw + + - name: Create an association between VGW and connection + community.aws.directconnect_virtual_interface: + region: "{{ aws_region }}" + state: present + name: "ansible-equinix-layer2-example" + public: false + connection_id: "{{ connection_response.connection.connection_id }}" + vlan: "{{ connection_response.connection.vlan }}" + virtual_gateway_id: "{{ created_vgw.vgw.id }}" + customer_address: "{{ metal_peering_ip }}/30" + amazon_address: "{{ aws_peering_ip }}/30" + bgp_asn: "{{ metal_side_asn }}" + authentication_key: "{{ bgp_md5_password }}" + register: created_vif + until: created_vif.virtual_interface_state == "available" + retries: 10 + delay: 60 + + - name: Look up the project we created earlier + equinix.cloud.metal_project: + name: "{{ project_name }}" + register: project + + - name: Look up the VRF we created earlier + equinix.cloud.metal_vrf: + name: example-vrf + metro: "{{ metro }}" + local_asn: "{{ metal_side_asn }}" + ip_ranges: + - "{{ vrf_peering_ip_range }}" + - "{{ vrf_gateway_ip_range }}" + project_id: "{{ project.id }}" + register: vrf + + - name: look up the Metal-billed VRF interconnection we created earlier + equinix.cloud.metal_connection: + project_id: "{{ project.id }}" + metro: "{{ metro }}" + name: "{{ interconnection_name }}" + type: "shared" + speed: "50Mbps" + service_token_type: a_side + redundancy: primary + vrfs: + - "{{ vrf.id }}" + register: connection + + - name: Configure BGP for interconnection virtual circuit + equinix.cloud.metal_virtual_circuit: + id: "{{ connection.ports[0].virtual_circuits[0].id }}" + peer_asn: "{{ created_vif.amazon_side_asn }}" + customer_ip: "{{ aws_peering_ip }}" + metal_ip: "{{ metal_peering_ip }}" + subnet: "{{ vrf_vc_peering_ip_range }}" + md5: "{{ bgp_md5_password }}" + # The metal_virtual_circuit module requires this parameter + # in order to know that the circuit is a VRF circuit and + # not a VLAN circuit + vrf: "{{ vrf.id }}" diff --git a/examples/layer2/metal.yml b/examples/layer2/pre_fabric.yml similarity index 80% rename from examples/layer2/metal.yml rename to examples/layer2/pre_fabric.yml index 4c06322..2ec4154 100644 --- a/examples/layer2/metal.yml +++ b/examples/layer2/pre_fabric.yml @@ -12,12 +12,6 @@ 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 }}" @@ -29,7 +23,7 @@ equinix.cloud.metal_vrf: name: example-vrf metro: "{{ metro }}" - local_asn: "65000" + local_asn: "{{ metal_side_asn }}" ip_ranges: - "{{ vrf_peering_ip_range }}" - "{{ vrf_gateway_ip_range }}" @@ -103,19 +97,6 @@ - "{{ vrf.id }}" register: connection - - 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: "{{ aws_peering_ip }}" - metal_ip: "{{ metal_peering_ip }}" - subnet: "{{ vrf_vc_peering_ip_range }}" - md5: "{{ bgp_md5_password }}" - # The metal_virtual_circuit module requires this parameter - # in order to know that the circuit is a VRF circuit and - # not a VLAN circuit - vrf: "{{ vrf.id }}" - - name: print service token to redeem in Fabric portal debug: var: connection.service_tokens[0].id diff --git a/examples/layer2/vars/vars.yml b/examples/layer2/vars/vars.yml index 04f4a01..3537a84 100644 --- a/examples/layer2/vars/vars.yml +++ b/examples/layer2/vars/vars.yml @@ -4,14 +4,14 @@ device_hostname: layer2-device metro: sv operating_system: ubuntu_20_04 plan: c3.small.x86 -interconnection_name: "ansible-layer2-example" +interconnection_name: "layer2 interconnection" vrf_gateway_ip_range: 192.168.200.0/25 vrf_peering_ip_network: 169.254.0.0 vrf_peering_ip_range: "{{ vrf_peering_ip_network }}/29" vrf_vc_peering_ip_range: "{{ vrf_peering_ip_network }}/30" metal_peering_ip: "{{ vrf_vc_peering_ip_range | ansible.utils.nthhost(2) }}" aws_peering_ip: "{{ vrf_vc_peering_ip_range | ansible.utils.nthhost(1) }}" -vrf_peering_asn: 65100 +metal_side_asn: 65100 fabric_connection_name: ansible-layer2-example # AWS variables aws_network_cidr: 172.16.0.0/16