October 30, 2018
OpenStack supports “provider” networks, which are networks that pre-exist in your physical infrastructure and are “provided” to the cloud users rather than created by the user. Only an admin is permitted to create a provider network.
A prequisite is the provider network must be plumbed to the external bridge on your controller and nova nodes.
Here is an Ansible playbook to create a project, place a unshared provider network and subnet in that project. Afterwards we will grant access to the members of this project using the openstack client. It does not appear that Ansible has a OpenStack network RBAC module at this time.
---
# file: project-tools-build.yml
# playbook to create tools-build project and network
#
# Run me as `admin` on overcloud.
# That means you may want to run like this:
# `ansible-playbook -e cloud=admin project-tools-build.yml`
- hosts: localhost
connection: local
vars:
# use python from virtualenv path
ansible_python_interpreter: python
cloud: admin
admin_cloud: admin
cloud_domain: Default
projects:
- project: tools-build
users:
- username: tools-build-user
networks:
tools-build:
project: tools-build
network_name: tools-build
subnet_name: tools-build-subnet
external: True
shared: False
provider_physical_network: datacentre
provider_network_type: vlan
provider_segmentation_id: 2
cidr: 192.0.2.0/24
gateway_ip: 192.0.2.254
allocation_pool_start: 192.0.2.20
allocation_pool_end: 192.0.2.250
dns_nameservers:
- 192.0.1.1
- 192.0.1.2
tasks:
- name: Create projects
os_project:
cloud: "{{cloud}}"
name: "{{item.project}}"
domain_id: "{{ cloud_domain }}"
description: "{{item.project}} Project"
enabled: True
with_items: "{{ projects }}"
- name: Create users
os_user:
cloud: "{{ cloud }}"
name: "{{ item.1.username }}"
password: "{{ item.1.password | default('secret') }}"
email: "{{ item.1.username }}@example.com"
domain: "{{ cloud_domain }}"
default_project: "{{ item.0.project }}"
enabled: True
with_subelements:
- "{{ projects }}"
- users
- name: Add users as members of projects
os_user_role:
cloud: "{{ cloud }}"
user: "{{ item.1.username }}"
role: _member_
project: "{{ item.0.project }}"
with_subelements:
- "{{ projects }}"
- users
- name: Add admin user to projects
os_user_role:
cloud: "{{ cloud }}"
user: "admin"
role: _member_
project: "{{ item.project }}"
with_items:
- "{{ projects }}"
- name: Create networks
os_network:
cloud: "{{admin_cloud}}"
name: "{{item.value.network_name}}"
project: "{{ item.value.project | default(omit) }}"
external: "{{ item.value.external | default(True) }}"
provider_network_type: "{{ item.value.provider_network_type | default(omit) }}"
provider_segmentation_id: "{{ item.value.provider_segmentation_id | default(omit) }}"
provider_physical_network: "{{ item.value.provider_physical_network | default(omit) }}"
shared: "{{ item.value.shared | default(False) }}"
state: present
with_dict: "{{ networks }}"
- name: Create subnets
os_subnet:
cloud: "{{admin_cloud}}"
state: present
name: "{{ item.value.subnet_name }}"
network_name: "{{ item.value.network_name }}"
project: "{{ item.value.project | default(omit) }}"
cidr: "{{ item.value.cidr }}"
gateway_ip: "{{ item.value.gateway_ip | default(omit) }}"
allocation_pool_start: "{{ item.value.allocation_pool_start | default(omit) }}"
allocation_pool_end: "{{ item.value.allocation_pool_end | default(omit) }}"
dns_nameservers: "{{ item.value.dns_nameservers | default(dns_nameservers) | join(',') }}"
with_dict: "{{ networks }}"
At this point you will have a provider network called tools-build
located in the tools-build project, but members of that tenant will not have rights to access it, because we set shared: False
.
Neutron RBAC will enable us to selectively exclusively share this network with the tools-build
tenant.
Perform the following as admin on the overcloud:
# get the ID for tools-build project
$ openstack project show tools-build -f value -c id
05d445c63e104f5bafafe21a8bc2a28a
# get the ID for tools-build network
$ openstack network show tools-build -f value -c id
3474ccc2-4c77-4c65-a6fb-87364ec7f135
# create an RBAC rule allowing access
$ openstack network rbac create --target-project 05d445c63e104f5bafafe21a8bc2a28a \
--action access_as_shared \
--type network 3474ccc2-4c77-4c65-a6fb-87364ec7f135
Keep in mind the network will now say shared
is True from the tools-build project, but False from other projects. Examine the RBAC rules on the network to see how.
# find RBAC rules for tools-build network
$ openstack network rbac list | grep $(openstack network show tools-build -f value -c id)
| 206121dc-e7e7-4d95-a03a-40d171fce0b8 | network | 3474ccc2-4c77-4c65-a6fb-87364ec7f135 |
| 6a73157a-d532-43b0-aabf-8cf2f2f40e97 | network | 3474ccc2-4c77-4c65-a6fb-87364ec7f135 |
# show first rule
$ openstack network rbac show 206121dc-e7e7-4d95-a03a-40d171fce0b8
+-------------------+--------------------------------------+
| Field | Value |
+-------------------+--------------------------------------+
| action | access_as_shared |
| id | 206121dc-e7e7-4d95-a03a-40d171fce0b8 |
| name | None |
| object_id | 3474ccc2-4c77-4c65-a6fb-87364ec7f135 |
| object_type | network |
| project_id | f806371dd95d4bcf982fe801852fd996 |
| target_project_id | 05d445c63e104f5bafafe21a8bc2a28a |
+-------------------+--------------------------------------+
# show second rule
$ openstack network rbac show 6a73157a-d532-43b0-aabf-8cf2f2f40e97
+-------------------+--------------------------------------+
| Field | Value |
+-------------------+--------------------------------------+
| action | access_as_external |
| id | 6a73157a-d532-43b0-aabf-8cf2f2f40e97 |
| name | None |
| object_id | 3474ccc2-4c77-4c65-a6fb-87364ec7f135 |
| object_type | network |
| project_id | 05d445c63e104f5bafafe21a8bc2a28a |
| target_project_id | * |
+-------------------+--------------------------------------+
At this point you should be able to create an instance attached to this network.
export OS_CLOUD="tools-build"
openstack server create \
--flavor m1.small \
--image rhel-server-7.5-x86_64-kvm.raw \
--key-name $USER \
--nic net-id=$(openstack network show tools-build -c id -f value) \
tools-build-instance
See Also