Example
In my previous posts in this project, I have explained how to setup NetBox and a couple of the Ansible collection features. In this post, I want to demonstrate what is possible using this approach.
I have created multiple Ansible roles with different vars files containing a lot of configuration parameters.
The repo for this example can be found in my GitLab.
Ensure that there are environment vars or similar such as the Ansible Vault to pass in the NetBox URL and API Key
I will first start with an almost empty NetBox environment. I will require the devices created and the rack created. I need the devices created due to the NetBox API changing, and the rack is to be created as the NetBox API is looking for the rack ID dcim.rack:3
and not the name.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
$ ansible-playbook site.yml PLAY [Playbook for configuring NetBox] *************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************************************* ok: [localhost] TASK [customisation : SETUP CUSTOM FIELDS] *********************************************************************************************************************************** changed: [localhost] => (item={'data': {'name': 'bankfx_id', 'content_types': ['dcim.site', 'tenancy.tenant'], 'type': 'text', 'label': 'BankFX ID'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'route_leaking', 'content_types': ['ipam.vrf'], 'type': 'text', 'label': 'Route Leaking Info', 'description': 'Route leaking data in JSON format'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'bgp_local_asn', 'content_types': ['ipam.ipaddress'], 'type': 'integer', 'label': 'Local ASN', 'description': 'Local AS to use with peer'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'bgp_peer_asn', 'content_types': ['ipam.ipaddress'], 'type': 'integer', 'label': 'BGP Peer ASN', 'description': 'ASN of BGP Peers on this subnet'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'edge_acl', 'content_types': ['ipam.ipaddress'], 'type': 'text', 'label': 'Edge ACL', 'description': 'Inbound ACL to apply (must already exist)'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'edge_bgp_as_prepend', 'content_types': ['ipam.ipaddress'], 'type': 'boolean', 'label': 'BGP AS Prepending', 'description': 'Prepend secondary AS Path or not'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'edge_bgp_lp_inbound', 'content_types': ['ipam.ipaddress'], 'type': 'text', 'label': 'BFP Local Pref', 'description': 'Applies appropriate local-pref to inbound prefixes'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'edge_bgp_multihop', 'content_types': ['ipam.ipaddress'], 'type': 'text', 'label': 'Enable EBGP Multihop', 'description': 'Enable EBGP Multihop 2 hops? (required for GCP)'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'edge_bgp_password', 'content_types': ['ipam.ipaddress'], 'type': 'text', 'label': 'BGP MD5 Password', 'description': 'Unencrypted (or prefixed/encrypted) password'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'edge_bgp_peer_ip', 'content_types': ['ipam.ipaddress'], 'type': 'text', 'label': 'Edge BGP Peer IP', 'description': 'Edge BGP Peer IP (optional for /30 or /31)'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'edge_bgp_prefix_adv', 'content_types': ['ipam.ipaddress'], 'type': 'text', 'label': 'BGP Advertised Prefixes', 'description': 'BGP Prefixes to advertise to peers from this IP (multiples allowed, comma separated), need to already be in BGP'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'edge_bgp_prefix_agg', 'content_types': ['ipam.ipaddress'], 'type': 'text', 'label': 'Edge BGP Prefixes to Aggregate', 'description': 'BGP Prefixes to aggregate to peers from this IP (multiples allowed, comma separated). Must add to edge_bgp_prefix_adv'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'edge_bgp_prefix_recv', 'content_types': ['ipam.ipaddress'], 'type': 'text', 'label': 'BGP Allowed Received Prefixes', 'description': 'Prefixes to allow from peer (prefix-list style) (multiples allowed, comma separated)'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'edge_bgp_set_med', 'content_types': ['ipam.ipaddress'], 'type': 'boolean', 'label': 'BGP Set MED', 'description': 'Set MED on outbound prefixes'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'edge_bgp_timers', 'content_types': ['ipam.ipaddress'], 'type': 'text', 'label': 'BGP Timers', 'description': '[keepalive] [hold timer]'}, 'state': 'present'}) TASK [customisation : SETUP TAGS] ******************************************************************************************************************************************** changed: [localhost] => (item={'data': {'name': 'XC', 'color': '673ab7', 'description': 'Cross Connect'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'DMZ', 'color': 'ff00ff'}, 'state': 'present'}) TASK [organisation : SETUP REGION] ******************************************************************************************************************************************* changed: [localhost] => (item={'data': {'name': 'EMEA'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'APAC'}, 'state': 'present'}) TASK [organisation : SETUP SITES] ******************************************************************************************************************************************** changed: [localhost] => (item={'data': {'name': 'uk1', 'time_zone': 'Europe/London', 'status': 'Active', 'region': 'EMEA', 'facility': 'DC1', 'slug': 'uk1', 'custom_fields': {'bankfx_id': '10'}}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'uk2', 'time_zone': 'Europe/London', 'status': 'Active', 'region': 'EMEA', 'facility': 'DC2', 'slug': 'uk2', 'custom_fields': {'bankfx_id': '128'}}, 'state': 'present'}) TASK [organisation : Create location within NetBox with a parent location] *************************************************************************************************** ok: [localhost] => (item={'data': {'name': 'location1', 'site': 'uk1'}, 'state': 'present'}) TASK [organisation : Create rack role within NetBox with only required information] ****************************************************************************************** ok: [localhost] => (item={'data': {'name': 'LabRack', 'color': 'ffc107'}, 'state': 'present'}) TASK [organisation : Create rack within NetBox with only required information] *********************************************************************************************** ok: [localhost] => (item={'data': {'name': 1, 'site': 'uk1', 'location': 'location1', 'status': 'active', 'facility_id': 'facilityid1', 'rack_role': 'LabRack'}, 'state': 'present'}) TASK [organisation : Create tenant within NetBox with only required information] ********************************************************************************************* ok: [localhost] => (item={'data': {'name': 'LPs', 'description': 'Liquidity Providers'}, 'state': 'present'}) TASK [organisation : Create tenant within NetBox with only required information] ********************************************************************************************* changed: [localhost] => (item={'data': {'name': 'Bank1', 'tenant_group': 'LPs', 'custom_fields': {'bankfx_id': 'SN123456789'}}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'Bank2', 'tenant_group': 'LPs', 'custom_fields': {'bankfx_id': 'SN987654321'}}, 'state': 'present'}) TASK [devices : Create Device Roles] ***************************************************************************************************************************************** ok: [localhost] => (item={'data': {'name': 'Leaf Switch', 'color': '9e9e9e', 'vm_role': False}, 'state': 'present'}) ok: [localhost] => (item={'data': {'name': 'Edge Switch', 'color': '9e9e9e', 'vm_role': False}, 'state': 'present'}) ok: [localhost] => (item={'data': {'name': 'Patch Panel', 'color': '673ab7', 'vm_role': False}, 'state': 'present'}) ok: [localhost] => (item={'data': {'name': 'Virtualisation Host', 'color': '2196f3', 'vm_role': False}, 'state': 'present'}) TASK [devices : Create Manufacturers] **************************************************************************************************************************************** ok: [localhost] => (item={'data': {'name': 'Arista'}, 'state': 'present'}) ok: [localhost] => (item={'data': {'name': 'Cisco'}, 'state': 'present'}) ok: [localhost] => (item={'data': {'name': 'Juniper'}, 'state': 'present'}) ok: [localhost] => (item={'data': {'name': 'Equinix'}, 'state': 'present'}) ok: [localhost] => (item={'data': {'name': 'Dell'}, 'state': 'present'}) TASK [devices : Create Device Types] ***************************************************************************************************************************************** ok: [localhost] => (item={'data': {'model': 'ASAv', 'manufacturer': 'Cisco', 'slug': 'asav', 'part_number': 'asav', 'is_full_depth': False}, 'state': 'present'}) ok: [localhost] => (item={'data': {'model': 'CSR1000v', 'manufacturer': 'Cisco', 'slug': 'csr1000v', 'part_number': 'csr1000v', 'is_full_depth': False}, 'state': 'present'}) ok: [localhost] => (item={'data': {'model': 'vEOS', 'manufacturer': 'Arista', 'slug': 'veos', 'part_number': 'veos', 'is_full_depth': False}, 'state': 'present'}) ok: [localhost] => (item={'data': {'model': '7060X', 'manufacturer': 'Arista', 'slug': '7060X', 'part_number': '7060X', 'is_full_depth': False}, 'state': 'present'}) ok: [localhost] => (item={'data': {'model': 'vSRX', 'manufacturer': 'Juniper', 'slug': 'vsrx', 'part_number': 'vsrx', 'is_full_depth': False}, 'state': 'present'}) ok: [localhost] => (item={'data': {'model': 'demarc', 'manufacturer': 'Equinix', 'slug': 'demarc', 'part_number': 'demarc', 'is_full_depth': False}, 'state': 'present'}) ok: [localhost] => (item={'data': {'model': 'R640', 'manufacturer': 'Dell', 'is_full_depth': True}, 'state': 'present'}) TASK [devices : Create Devices] ********************************************************************************************************************************************** ok: [localhost] => (item={'data': {'name': 'ld4leaf1', 'device_role': 'Leaf Switch', 'device_type': '7060X', 'site': 'UK1', 'status': 'staged'}, 'state': 'present'}) ok: [localhost] => (item={'data': {'name': 'ld4leaf2', 'device_role': 'Leaf Switch', 'site': 'UK1', 'status': 'active'}, 'state': 'present'}) ok: [localhost] => (item={'data': {'name': 'ld4leaf3', 'device_role': 'Leaf Switch', 'site': 'UK1', 'status': 'active'}, 'state': 'present'}) ok: [localhost] => (item={'data': {'name': 'PP:0000:1219408', 'device_role': 'Patch Panel', 'location': 'location1', 'rack': 3, 'device_type': 'demarc', 'site': 'UK1', 'status': 'active'}, 'state': 'present'}) ok: [localhost] => (item={'data': {'name': 'Server1', 'device_role': 'Virtualisation Host', 'location': 'location1', 'rack': 3, 'face': 'front', 'position': 35, 'device_type': 'R640', 'site': 'UK1', 'status': 'active'}, 'state': 'present'}) TASK [devices : Create interface and assign it to parent LAG] **************************************************************************************************************** changed: [localhost] => (item={'data': {'device': 'ld4leaf1', 'name': 'GigabitEthernet1', 'enabled': False, 'type': '1000Base-t (1GE)', 'mtu': 1600, 'mgmt_only': False, 'mode': 'Access', 'tags': ['DMZ', 'XC']}, 'state': 'present'}) changed: [localhost] => (item={'data': {'device': 'ld4leaf1', 'name': 'GigabitEthernet2', 'enabled': False, 'type': '1000Base-t (1GE)', 'description': 'Bank1', 'mtu': 1600, 'mgmt_only': False, 'mode': 'Access', 'tags': ['XC', 'DMZ']}, 'state': 'present'}) changed: [localhost] => (item={'data': {'device': 'ld4leaf1', 'name': 'GigabitEthernet3', 'enabled': False, 'type': '1000Base-t (1GE)', 'mtu': 1600, 'mgmt_only': False, 'mode': 'Access'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'device': 'ld4leaf1', 'name': 'port-channel1', 'type': 'Link Aggregation Group (LAG)', 'mtu': 1600, 'mgmt_only': False, 'mode': 'Tagged'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'device': 'ld4leaf1', 'name': 'GigabitEthernet4', 'enabled': False, 'type': '1000Base-t (1GE)', 'lag': {'name': 'port-channel1'}, 'mtu': 1600, 'mgmt_only': False, 'mode': 'Tagged'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'device': 'Server1', 'name': 'DRAC', 'enabled': True, 'type': '1000Base-t (1GE)', 'mgmt_only': True}, 'state': 'present'}) changed: [localhost] => (item={'data': {'device': 'Server1', 'name': 'NIC1', 'enabled': True, 'type': 'SFP+ (10GE)', 'mgmt_only': False}, 'state': 'present'}) changed: [localhost] => (item={'data': {'device': 'Server1', 'name': 'NIC2', 'enabled': True, 'type': 'SFP+ (10GE)', 'mgmt_only': False}, 'state': 'present'}) TASK [devices : Create rear port within NetBox with only required information] *********************************************************************************************** changed: [localhost] => (item={'data': {'name': 'Test Rear Port', 'device': 'PP:0000:1219408', 'type': 'lc', 'description': 'rear port description', 'positions': 24}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'Bank1', 'device': 'PP:0000:1219408', 'type': 'lc', 'description': 'Bank1', 'positions': 1}, 'state': 'present'}) TASK [devices : Update front port with other fields] ************************************************************************************************************************* changed: [localhost] => (item={'data': {'name': 'Bank1', 'device': 'PP:0000:1219408', 'type': 'lc', 'rear_port': 'Test Rear Port', 'rear_port_position': 1, 'description': 'Bank1'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'Test Front Port', 'device': 'PP:0000:1219408', 'type': 'lc', 'rear_port': 'Test Rear Port', 'rear_port_position': 5, 'description': 'front port description'}, 'state': 'present'}) TASK [devices : Create power port within NetBox with only required information] ********************************************************************************************** changed: [localhost] => (item={'data': {'name': 'Power A', 'device': 'Server1', 'type': 'iec-60320-c6', 'allocated_draw': 100, 'maximum_draw': 200}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'Power B', 'device': 'Server1', 'type': 'iec-60320-c6', 'allocated_draw': 100, 'maximum_draw': 200}, 'state': 'present'}) TASK [ipam : Create vrf within NetBox with only required information] ******************************************************************************************************** changed: [localhost] => (item={'data': {'name': 'v001_v139_bank1', 'rd': 1111, 'tenant': 'Bank1', 'custom_fields': {'route_leaking': '{"route_leak_to": ["v001_v104_Prod", "v001_v124_ECN_Prod", "v001_v134_Maxx_Prod"]}'}}, 'state': 'present'}) changed: [localhost] => (item={'data': {'name': 'v139_bank1', 'rd': 1112, 'tenant': 'Bank1'}, 'state': 'present'}) TASK [ipam : Create vlan group within NetBox with only required information - Post 2.11] ************************************************************************************* changed: [localhost] => (item={'data': {'name': 'Edge VLANs', 'scope_type': 'dcim.site', 'scope': 'uk1'}, 'state': 'present'}) TASK [ipam : Create vlan with all information] ******************************************************************************************************************************* changed: [localhost] => (item={'data': {'name': 'Bank1-2139', 'vid': 2139, 'site': 'uk1', 'vlan_group': 'Edge VLANs', 'tenant': 'Bank1', 'status': 'Active', 'description': 'Just a test', 'tags': ['DMZ']}, 'state': 'present'}) TASK [ipam : Create prefix with several specified options] ******************************************************************************************************************* changed: [localhost] => (item={'data': {'family': 4, 'prefix': '10.156.32.0/19', 'site': 'uk1', 'vrf': 'v139_bank1', 'status': 'Active', 'description': 'Test description', 'is_pool': False, 'tags': ['DMZ']}, 'state': 'present', 'first_available': False}) changed: [localhost] => (item={'data': {'prefix': '10.156.33.0/24', 'site': 'uk1', 'vrf': 'v139_bank1', 'tenant': 'Bank1', 'tags': ['DMZ']}, 'state': 'present', 'first_available': False}) changed: [localhost] => (item={'data': {'prefix': '10.156.34.0/24', 'site': 'uk1', 'vrf': 'v139_bank1', 'tenant': 'Bank1', 'tags': ['DMZ']}, 'state': 'present', 'first_available': False}) changed: [localhost] => (item={'data': {'prefix': '10.156.35.0/24', 'site': 'uk1', 'vrf': 'v139_bank1', 'tenant': 'Bank1', 'description': 'Bank1 peering', 'vlan': {'name': 'Bank1-2139', 'site': 'uk1', 'tenant': 'Bank1', 'vlan_group': 'Edge VLANs'}, 'tags': ['DMZ']}, 'state': 'present', 'first_available': False}) TASK [ipam : Create IP address with several specified options] *************************************************************************************************************** changed: [localhost] => (item={'data': {'address': '10.156.35.74/32', 'vrf': 'v139_bank1', 'status': 'active', 'description': 'Dummy'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'address': '2a11:b4ca:ffee:0:139:128:0:6/128', 'vrf': 'v001_v139_bank1', 'tenant': 'Bank1', 'status': 'active', 'description': 'IPv6 NAT'}, 'state': 'present'}) changed: [localhost] => (item={'data': {'address': '10.156.35.174/32', 'vrf': 'v139_bank1', 'tenant': 'Bank1', 'status': 'active', 'description': 'IPv6 NAT', 'nat_inside': '2a11:b4ca:ffee:0:139:128:0:6/128', 'tags': ['DMZ']}, 'state': 'present'}) TASK [circuits : Create provider within NetBox with only required information] *********************************************************************************************** changed: [localhost] => (item={'data': {'name': 'XC'}, 'state': 'present'}) TASK [circuits : Create type within NetBox with only required information] *************************************************************************************************** changed: [localhost] => (item={'data': {'name': 'Cross-Connect', 'description': 'Cross-Connects to LPs, Buy-Sides and Service Providers'}, 'state': 'present'}) TASK [circuits : Create circuit within NetBox with only required information] ************************************************************************************************ changed: [localhost] => (item={'data': {'cid': 'Bank1-ID', 'circuit_type': 'Cross-Connect', 'tenant': 'Bank1', 'description': 'Bank1', 'tags': ['DMZ'], 'provider': 'XC'}, 'state': 'present'}) TASK [circuits : Create circuit termination within NetBox with only required information] ************************************************************************************ changed: [localhost] => (item={'data': {'circuit': 'Bank1-ID', 'term_side': 'Z', 'site': 'uk1', 'port_speed': 1000000, 'xconnect_id': 123456789}, 'state': 'present'}) PLAY RECAP ******************************************************************************************************************************************************************* localhost : ok=27 changed=18 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 |
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
$ tree . ├── group_vars │ └── all.yml ├── README.md ├── roles │ ├── circuits │ │ ├── defaults │ │ │ └── main.yml │ │ ├── tasks │ │ │ └── main.yml │ │ └── vars │ │ └── main.yml │ ├── connections │ │ ├── defaults │ │ │ └── main.yml │ │ ├── tasks │ │ │ └── main.yml │ │ └── vars │ │ └── main.yml │ ├── customisation │ │ ├── defaults │ │ │ └── main.yml │ │ ├── tasks │ │ │ └── main.yml │ │ └── vars │ │ └── main.yml │ ├── devices │ │ ├── defaults │ │ │ └── main.yml │ │ ├── tasks │ │ │ └── main.yml │ │ └── vars │ │ └── main.yml │ ├── ipam │ │ ├── defaults │ │ │ └── main.yml │ │ ├── tasks │ │ │ └── main.yml │ │ └── vars │ │ └── main.yml │ └── organisation │ ├── defaults │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── vars │ └── main.yml └── site.yml 26 directories, 21 files |