Skip to content

Commit 6e1f223

Browse files
k8soneillstevemul
authored andcommitted
Feature/nonhttp (#90)
* adding configuration for non-http connectivity * adding readme
1 parent ae20e6d commit 6e1f223

File tree

10 files changed

+282
-5
lines changed

10 files changed

+282
-5
lines changed

bastion-template.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ parameters:
156156
type: json
157157
description: Configuration needed for SSO integration
158158
hidden: true
159+
external_service_subnet:
160+
type: string
161+
description: Internal subnet reserved for external service IPs
159162
registry_details:
160163
type: json
161164
description: Configuration needed for authenticated container registry
@@ -276,7 +279,8 @@ resources:
276279
__bastion_ip__ : { get_param: bastion_fixed_ip }
277280
__sso_client_id__ : { get_param: [ sso_config, client_id ] }
278281
__sso_client_secret__: { get_param: [ sso_config, client_secret ] }
279-
__sso_urls__ : { get_param: [ sso_config, urls ] }
282+
__sso_urls__: { get_param: [ sso_config, urls ] }
283+
__external_service_subnet__: { get_param: external_service_subnet }
280284
__registry_url__ : { get_param: [ registry_details, registry_url ] }
281285
__registry_user__: { get_param: [ registry_details, registry_user ] }
282286
__registry_password__ : { get_param: [ registry_details, registry_password ] }

environment_example.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ parameter_defaults:
5858
# dns: [ "8.8.4.4" ]
5959
# gateway: "10.3.1.102"
6060
# bastion_ip: "10.3.1.101"
61+
# service_subnet: This should be a /29 starting at .240 unless more addresses are required. .249-.254 will be left for routers "10.3.1.240/29"
62+
#external_services_config:
63+
# - service_ip: Neutron network IP for service. Must be within the external_service_subnet.
64+
# floating_network: External network to expose the service on e.g. [ "Internet" ], must be a comma delimited list
65+
# proto: tcp or udp
66+
# port: port to expose e.g. 3306
67+
# allowed_sources: sources allowed to hit service e.g. 0.0.0.0/0
6168
# Example of passing in configuration for SSO
6269
#sso_config:
6370
# client_id: <client ID>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
heat_template_version: 2016-10-14
2+
3+
parameters:
4+
external_services_json:
5+
type: json
6+
description: Configuration values for external services in a json array
7+
index:
8+
type: string
9+
internal_network:
10+
type: string
11+
description: neutron network name to attach port on
12+
13+
resources:
14+
external_service_security_group_rule:
15+
type: OS::Neutron::SecurityGroupRule
16+
condition: sec_rule_create
17+
properties:
18+
security_group: external_service_sg
19+
protocol: { get_param: [ external_services_json, { get_param: index}, proto ]}
20+
remote_ip_prefix: { get_param: [ external_services_json, { get_param: index}, allowed_sources ] }
21+
ethertype: IPv4
22+
direction: ingress
23+
port_range_max: { get_param: [ external_services_json, { get_param: index}, port ] }
24+
port_range_min: { get_param: [ external_services_json, { get_param: index}, port ] }
25+
26+
service_floating_ip:
27+
type: OS::Neutron::FloatingIP
28+
condition: port_ip_create
29+
properties:
30+
floating_network: { get_param: [ external_services_json, { get_param: index }, floating_network ] }
31+
32+
service_port:
33+
type: OS::Neutron::Port
34+
condition: port_ip_create
35+
properties:
36+
name:
37+
str_replace:
38+
template: external_service_port_index
39+
params:
40+
index: { get_param: index }
41+
network: { get_param: internal_network }
42+
fixed_ips:
43+
[ip_address: { get_param: [ external_services_json, { get_param: index }, service_ip ] }]
44+
45+
service_floating_ip_association:
46+
type: OS::Neutron::FloatingIPAssociation
47+
condition: port_ip_create
48+
depends_on: [ service_floating_ip, service_port ]
49+
properties:
50+
floatingip_id: { get_resource: service_floating_ip }
51+
port_id: { get_resource: service_port }
52+
53+
conditions:
54+
port_ip_create:
55+
not:
56+
equals:
57+
- get_param: [ external_services_json, { get_param: index }, port_ip_deploy ]
58+
- false
59+
60+
sec_rule_create:
61+
not:
62+
equals:
63+
- get_param: [ external_services_json, { get_param: index }, sec_rule_deploy ]
64+
- false
65+
66+
outputs:
67+
external_service_ip_pair:
68+
condition: port_ip_create
69+
value: [{ get_attr: [ service_floating_ip, floating_ip_address ] }, { get_attr: [ service_port, fixed_ips, 0, ip_address ] }]

external_services/readme.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
### Exposing External Services
2+
3+
This readme intends to give you the information required to run stack updates that deploy the necessary infrastructure to allow non-http services to be exposed outside our clusters. The following parameter addition is required to deploy even if you are not exposing any services:
4+
5+
```
6+
network_config:
7+
allocation_pool: [{"start": "10.3.1.2", "end": "10.3.1.100"}]
8+
cidr: "10.3.1.0/24"
9+
dns: [ "8.8.4.4" ]
10+
gateway: "10.3.1.102"
11+
bastion_ip: "10.3.1.101"
12+
service_subnet: "10.3.1.240/29" # This is the new addition. It's the subnet to be used for service_ip on services. Must be within internal network range and not conflict with allocation pool.
13+
```
14+
15+
The parameter used to deploy the actual external_services infrastructure is ```external_services_config``` this can be hashed out if not required and it will not try to create the external services resource at the top level. If you do want to use an external service then the following block is an example:
16+
17+
```
18+
external_services_config:
19+
- service_ip: 10.3.1.240 # Sets the internal IP of the port that a floating IP will be associated to
20+
floating_network: "Internet" # Will create a floating IP on the specified network and associate it to the service_ip port.
21+
proto: tcp or udp # Used in the security rule thats created to allow access. Should match the service protocol.
22+
port: 3306 # Used in the security rule thats created to allow access. Should match the service port.
23+
allowed_sources: sources allowed to hit service e.g. 0.0.0.0/0 # Used in the security rule thats created to allow access
24+
```
25+
> [!WARNING]
26+
> Always do a stack show before attempting to update the external_services to ensure you pass in all of the existing json blocks.
27+
28+
29+
It's important to note that the blocks are a list of json objects. The order of them matters, if you are updating a cluster to add extra services you MUST keep them in the correct order otherwise the already exposed services will be destroyed. An example of deploying two external services would be:
30+
31+
```
32+
external_services_config:
33+
- service_ip: 10.3.1.240
34+
floating_network: "Internet"
35+
proto: tcp
36+
port: 3306
37+
allowed_sources: 0.0.0.0/0
38+
- service_ip: 10.3.1.241
39+
floating_network: "Internet"
40+
proto: tcp
41+
port: 3307
42+
allowed_sources: 0.0.0.0/0
43+
```
44+
45+
The above will deploy two floating IPs on the internet, one mapped to the internal IP of 10.3.1.240 and the other mapped to the internal IP of 10.3.1.241. It will also add two security rules to all nodes allowing access to 3307 and 3306 from all sources. While this may seem insecure IPtables rules within the cluster will ensure you can only hit the relevant service on the relevant IP once they have been exposed.
46+
47+
What if a customer wants to expose multiple services on a single IP? Well let's say the customer wants one internet IP and would like to expose tcp 3306 and udp 53 on it. The way this would be done is:
48+
49+
```
50+
external_services_config:
51+
- service_ip: 10.3.1.240
52+
floating_network: "Internet"
53+
proto: tcp
54+
port: 3306
55+
allowed_sources: 0.0.0.0/0
56+
- port_ip_deploy: false
57+
proto: udp
58+
port: 53
59+
allowed_sources: 0.0.0.0/0
60+
```
61+
62+
In the above ```port_ip_deploy: false``` specifies to not create a floating IP or internal IP so the second block is only creating a security rule allowing access to the nodes on port 53 from all sources. You could then expose two services on 10.3.1.240 from inside the cluster and each would be reachable on the same floating IP.
63+
64+
To remove a resource you would simply change the block it exists in to the following:
65+
66+
```
67+
external_services_config:
68+
- port_ip_deploy: false
69+
sec_rule_deploy: false
70+
- port_ip_deploy: false
71+
proto: udp
72+
port: 53
73+
allowed_sources: 0.0.0.0/0
74+
```
75+
76+
In the above the first block used to create an internal IP of 10.3.1.240, map a floating IP from the internet to it and create a security rule allowing access on 3306. ```port_ip_deploy: false``` and ```sec_rule_deploy: false``` will ensure that when you update the stack this resource block will be evaluated and all resources previously related to it will be destroyed.
77+
78+
If you wanted to change a floating IP to a different network you cannot simply overwrite the ```floating_network``` parameter and update. You first need to destroy the resources from the block in an update and then specify a new network and update. The stages would be:
79+
80+
```
81+
external_services_config:
82+
- service_ip: 10.3.1.240
83+
floating_network: "Internet"
84+
proto: tcp
85+
port: 3306
86+
allowed_sources: 0.0.0.0/0
87+
```
88+
89+
Original deployment config. Customer then asks for the 10.3.1.240 to be accessible on HSCN rather than the internet:
90+
91+
```
92+
external_services_config:
93+
- port_ip_deploy: false
94+
sec_rule_deploy: false
95+
```
96+
97+
Update is run, destroying the resources.
98+
99+
```
100+
external_services_config:
101+
- service_ip: 10.3.1.240
102+
floating_network: "HSCN"
103+
proto: tcp
104+
port: 3306
105+
allowed_sources: 0.0.0.0/0
106+
```
107+
108+
Final update is run re-creating the resources.
109+
110+
Finally, the best way to go about updating these parameters is to create your own yaml file containing the block (in this example it's service-update.yml) and running the following:
111+
112+
```
113+
openstack stack update <stack> --existing -e service-update.yml
114+
```

files/setup_bastion.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,12 @@
5050
ssoClientId: __sso_client_id__
5151
ssoClientSecret: __sso_client_secret__
5252
ssoUrls: __sso_urls__
53+
externalServiceSubnet: __external_service_subnet__
5354
registryUrl: __registry_url__
5455
registryUser: __registry_user__
5556
registryPassword: __registry_password__
56-
tasks:
5757

58+
tasks:
5859
- name: Check if stack update or create and register variable
5960
shell: if [[ $(openstack stack show "openshift-{{ osTenantName }}" -f value -c stack_status \
6061
--os-auth-url "{{ osAuthUrl }}" \
@@ -253,6 +254,7 @@
253254
sso_client_id: {{ ssoClientId }}
254255
sso_client_secret: {{ ssoClientSecret }}
255256
sso_urls: '{{ ssoUrls | to_json }}'
257+
external_service_subnet: {{ externalServiceSubnet }}
256258
registryUrl: {{ registryUrl }}
257259
registryUser: {{ registryUser }}
258260
registryPassword: {{ registryPassword }}
@@ -293,4 +295,4 @@
293295
owner: cloud-user
294296
group: cloud-user
295297
recurse: yes
296-
when: stack_create
298+
when: stack_create

node_group.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ parameters:
5656
cluster_security_groups:
5757
type: comma_delimited_list
5858
description: Security groups for cluster
59+
external_service_subnet:
60+
type: string
61+
description: subnet to be used when deploying external services
5962
server_group:
6063
type: string
6164
description: server group to associate nodes with
@@ -92,6 +95,7 @@ resources:
9295
port_network: { get_param: internal_network }
9396
sec_groups: { get_param: cluster_security_groups }
9497
storage_setup: { get_param: storage_setup }
98+
external_service_subnet: { get_param: external_service_subnet }
9599
server_group: { get_param: server_group }
96100

97101
outputs:

security_groups.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ parameters:
3333
default: [ "0.0.0.0/0" ]
3434

3535
resources:
36+
external_service_secgroup:
37+
type: OS::Neutron::SecurityGroup
38+
properties:
39+
name: external_service_sg
40+
3641
bastion_egress_secgroup:
3742
type: OS::Neutron::SecurityGroup
3843
properties:
@@ -354,6 +359,16 @@ resources:
354359
port_range_min: 443
355360
port_range_max: 443
356361

362+
vrrp_nodes_secgroup:
363+
type: OS::Neutron::SecurityGroup
364+
properties:
365+
name: vrrp_nodes_sg
366+
rules:
367+
- direction: ingress
368+
ethertype: IPv4
369+
remote_mode: remote_group_id
370+
protocol: vrrp
371+
357372
dns_internet_secgroup:
358373
type: OS::Neutron::SecurityGroup
359374
properties:
@@ -468,6 +483,9 @@ resources:
468483
remote_group_id: { get_resource: all_net2_egress_secgroup }
469484

470485
outputs:
486+
external_service_security_group:
487+
description: Externally exposed service security group
488+
value: { get_resource: external_service_secgroup }
471489
bastion_egress_security_group:
472490
description: Bastion egress security group
473491
value: { get_resource: bastion_egress_secgroup }
@@ -501,6 +519,9 @@ outputs:
501519
all_internet_egress_security_group:
502520
description: All internet facing servers egress security group
503521
value: { get_resource: all_internet_egress_secgroup }
522+
vrrp_nodes_security_group:
523+
description: VRRP access between tenant and net2 nodes
524+
value: { get_resource: vrrp_nodes_secgroup }
504525

505526
bastion_external_security_group:
506527
description: Bastion external security group

server_atomic.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ parameters:
4747
server_group:
4848
type: string
4949
label: group server belongs to
50+
external_service_subnet:
51+
type: string
52+
description: Subnet to be used for external services
5053

5154
resources:
5255
resize_lv:
@@ -114,6 +117,7 @@ resources:
114117
servername: { get_param: server_name }
115118
network: { get_param: port_network }
116119
security_groups: { get_param: sec_groups }
120+
allowed_address_pairs: [ ip_address: { get_param: external_service_subnet } ]
117121

118122
outputs:
119123
server_ip:

setup-heat-templates.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
local_domain_suffix: { get_param: local_domain_suffix }
149149
internal_network: { get_attr: [internal_network, outputs, network] }
150150
internal_network_subnet: { get_attr: [internal_network, outputs, subnet] }
151+
external_service_subnet: { get_param: [ network_config, service_subnet ] }
151152
server_group: { get_attr: [server_groups, outputs, nodes-servergroup] }
152153
cluster_security_groups:
153154
- { get_attr: [ security_groups, outputs, net2_nodes_egress_security_group ] }
@@ -156,6 +157,8 @@
156157
- { get_attr: [ security_groups, outputs, bastion_internal_ssh_security_group ] }
157158
- { get_attr: [ security_groups, outputs, all_nodes_security_group ] }
158159
- { get_attr: [ security_groups, outputs, net2_nodes_security_group ] }
160+
- { get_attr: [ security_groups, outputs, external_service_security_group ] }
161+
- { get_attr: [ security_groups, outputs, vrrp_nodes_security_group ] }
159162
160163
net2_nodes_medium_deployment:
161164
type: OS::Heat::Stack
@@ -171,6 +174,7 @@
171174
local_domain_suffix: { get_param: local_domain_suffix }
172175
internal_network: { get_attr: [internal_network, outputs, network] }
173176
internal_network_subnet: { get_attr: [internal_network, outputs, subnet] }
177+
external_service_subnet: { get_param: [ network_config, service_subnet ] }
174178
server_group: { get_attr: [server_groups, outputs, nodes-servergroup] }
175179
cluster_security_groups:
176180
- { get_attr: [ security_groups, outputs, net2_nodes_egress_security_group ] }
@@ -179,6 +183,8 @@
179183
- { get_attr: [ security_groups, outputs, bastion_internal_ssh_security_group ] }
180184
- { get_attr: [ security_groups, outputs, all_nodes_security_group ] }
181185
- { get_attr: [ security_groups, outputs, net2_nodes_security_group ] }
186+
- { get_attr: [ security_groups, outputs, external_service_security_group ] }
187+
- { get_attr: [ security_groups, outputs, vrrp_nodes_security_group ] }
182188
183189
net2_nodes_large_deployment:
184190
type: OS::Heat::Stack
@@ -194,6 +200,7 @@
194200
local_domain_suffix: { get_param: local_domain_suffix }
195201
internal_network: { get_attr: [internal_network, outputs, network] }
196202
internal_network_subnet: { get_attr: [internal_network, outputs, subnet] }
203+
external_service_subnet: { get_param: [ network_config, service_subnet ] }
197204
server_group: { get_attr: [server_groups, outputs, nodes-servergroup] }
198205
cluster_security_groups:
199206
- { get_attr: [ security_groups, outputs, net2_nodes_egress_security_group ] }
@@ -202,6 +209,8 @@
202209
- { get_attr: [ security_groups, outputs, bastion_internal_ssh_security_group ] }
203210
- { get_attr: [ security_groups, outputs, all_nodes_security_group ] }
204211
- { get_attr: [ security_groups, outputs, net2_nodes_security_group ] }
212+
- { get_attr: [ security_groups, outputs, external_service_security_group ] }
213+
- { get_attr: [ security_groups, outputs, vrrp_nodes_security_group ] }
205214
206215
data_plane_net2_lb:
207216
type: OS::Heat::Stack

0 commit comments

Comments
 (0)