"Conditions (..) They can be associated with resources and resource properties in the resources section (..)" - as the official openstack's docs said I can do that. But attached examples do not contains these with "resource properties".
I have my example, when user can set parameter to NOT create port2 AND not attach port2 (because port2 does not exist):
parameters:
global_port2_create:
description: Do you want eth1 (port2)
type: string
default: true
conditions:
create_port2: {equals : [{get_param: global_port2_create}, "true"]}
resources:
node_port1:
type: OS::Neutron::Port
properties:
network_id: {get_param: global_port1_net_id }
fixed_ips:
- subnet_id: {get_param: global_port1_net_id }
- ip_address: {get_param: node_port1_ip }
security_groups: {get_param: global_port1_security_groups_ids}
node_port2:
type: OS::Neutron::Port
condition: create_port2
properties:
network_id: {get_param: global_port_net_id }
fixed_ips:
- subnet_id: {get_param: global_port2_net_id }
- ip_address: {get_param: node5_port2_ip }
security_groups: {get_param: global_port2_security_groups_ids}
node5_server:
type: OS::Nova::Server
depends_on: [ node5_port1, node5_port2 ]
properties:
name: some_name
image: { get_param: global_image }
availability_zone: some_az
networks:
- port: { get_resource: node5_port1 }
- port: { get_resource: node5_port2 } #How to use a condition here?
I know, i can do a ResourceGroup with both ports and iterate them, but I do not want this resolution.
Maybe like this?
networks:
- port: { get_resource: node5_port1 }
- port:
condition: create_port2
get_resource: node5_port2
Anyone have any ideas how to accomplish this?
I had a similar use case and found a solution. However, say goodbye to readability if this was still a concern:
networks: {if: [ "create_port2", [port: { get_resource: node5_port1 }, port: { get_resource: node5_port2 }], [port: { get_resource: node5_port1 }]}
which you can also write:
networks:
if:
- "create_port2"
- [port: { get_resource: node5_port1 }, port: { get_resource: node5_port2 }]
- [port: { get_resource: node5_port1 }]
Or even:
networks:
if:
- "create_port2"
- - port: { get_resource: node5_port1 }
- port: { get_resource: node5_port2 }
- - port: { get_resource: node5_port1 }
Choose your poison!
Related
I would like to define some "global resources" (such as security groups) and then be able to export them to the templates in charge of the deployment nodes.
I tried following this documentation page: https://docs.openstack.org/heat/yoga/template_guide/composition.html
sec-group.yaml:
heat_template_version: 2018-08-31
resources:
sec_group:
type: OS::Neutron::SecurityGroup
properties:
name: my-sec-group
description: my security group
rules:
- direction: egress
ethertype: IPv4
- direction: egress
ethertype: IPv6
(simplified) deploy-node.yaml
...
...
resources:
flavor:
type: OS::Nova::Flavor
properties:
ram: 4096
disk: 20
vcpus: 1
instance:
type: OS::Nova::Server
properties:
flavor: { get_resource: flavor }
image: { get_param: image }
key_name: { get_param: key_name }
metadata: { get_param: metadata }
name: { get_param: "OS::stack_name" }
networks:
- port: { get_resource: instance_port }
sec_group:
type: sec-group.yaml
instance_port:
type: OS::Neutron::Port
properties:
network: { get_param: instance_net }
fixed_ips:
- subnet_id: { get_param: instance_subnet }
security_groups:
- { get_resource: sec_group }
However, Openstack returns EntityNotFound for the security group when creating the instance_port resource. What am I doing wrong?
Problem is that the stack won't build when the count is greater than 1.
The reason for this is because - port: { get_resource: test_port } is not unique for every instance made.
Error code received: CREATE_FAILED Conflict: resources.compute_nodes.resources[3]: Port XXX is still in use.
Question: How can I make - port: { get_resource: test_port } unique for each instance?
compute_nodes:
type: OS::Heat::ResourceGroup
properties:
count: 3
resource_def:
type: OS::Nova::Server
properties:
name: test-%index%
key_name: { get_param: key_name }
image: "Ubuntu Server 18.04 LTS (Bionic Beaver) amd64"
flavor: m1.small
networks:
- port: { get_resource: test_port }
test_port:
type: OS::Neutron::Port
properties:
network_id: { get_resource: private_net }
security_groups: { get_param: sec_group_lin }
fixed_ips:
- subnet_id: { get_resource: private_subnet }
test_floating_ip:
type: OS::Neutron::FloatingIP
properties:
floating_network: { get_param: public_net }
port_id: { get_resource: test_port }
Iterate comma_delimited_list OS::Heat::ResourceGroup
Your stack tries to attach the same port to different Nova server, so this is failing.
The solution would be to create a nested stack that would create your 3 resources (Nova server, Neutron port and Neutron Floating IP), and then your main stack would implement a resource group to "scale" your servers:
Nested_stack: nested_stack.yaml
parameter:
index:
type: number
sec_group_lin:
type: string
key_name:
type: string
public_net:
type: string
resources:
compute_nodes:
type: OS::Nova::Server
depends_on: [test_port, test_floating_ip]
properties:
name: { list-join: ['-', ['test', {get_param: index} ] ] }
key_name: { get_param: key_name }
image: "Ubuntu Server 18.04 LTS (Bionic Beaver) amd64"
flavor: m1.small
networks:
- port: { get_resource: test_port }
test_port:
type: OS::Neutron::Port
properties:
network_id: { get_resource: private_net }
security_groups: { get_param: sec_group_lin }
fixed_ips:
- subnet_id: { get_resource: private_subnet }
test_floating_ip:
type: OS::Neutron::FloatingIP
depends_on: [test_port]
properties:
floating_network: { get_param: public_net }
port_id: { get_resource: test_port }
Then your main stack would look like:
parameters:
key_name:
type: string
public_net:
type: string
sec_group_lin:
type: string
resources:
compute_nodes:
type: OS::Heat::ResourceGroup
properties:
count: 3
resource_def:
type: nested_stack.yaml
properties:
index: %index%
key_name: {get_param: key_name}
public_net: { get_param: public_net }
sec_group_lin: { get_param: sec_group_lin }
This will created x (here x=3 as your count is set to 3) servers with each of them having its own test port and test floating IP.
Make use of "depends_on" to align the flow of execution of template
compute_nodes:
type: OS::Heat::ResourceGroup
depends_on: [test_port, test_floating_ip]
properties:
count: 3
resource_def:
type: OS::Nova::Server
properties:
name: test-%index%
key_name: { get_param: key_name }
image: "Ubuntu Server 18.04 LTS (Bionic Beaver) amd64"
flavor: m1.small
networks:
- port: { get_resource: test_port }
test_port:
type: OS::Neutron::Port
properties:
network_id: { get_resource: private_net }
security_groups: { get_param: sec_group_lin }
fixed_ips:
- subnet_id: { get_resource: private_subnet }
test_floating_ip:
type: OS::Neutron::FloatingIP
depends_on: [test_port]
properties:
floating_network: { get_param: public_net }
port_id: { get_resource: test_port }
I want to add port to the instance only if the name is zee_1
template file:
resources:
vm_port_routable:
type: OS::Neutron::Port
properties:
network: { get_param: abc_routable_net }
name:
str_replace:
template: $stack_$name_routable_port
params:
$stack: { get_param: stack }
$name: { get_param: vm_name }
security_groups: [{ get_param: security_group }]
fixed_ips:
- ip_address: { get_param: port_ip_routable }
test_vm_port_routable:
type: OS::Neutron::Port
properties:
network: { get_param: test_zee_routable_net }
name:
str_replace:
template: $stack_$name_routable_port
params:
$stack: { get_param: stack }
$name: { get_param: vm_name }
security_groups: [{ get_param: security_group }]
fixed_ips:
- ip_address: { get_param: test_port_ip_routable }
zee_server:
type: OS::Nova::Server
properties:
block_device_mapping_v2:
- boot_index: 0
delete_on_termination: false
volume_id: { get_resource: root_volume }
device_name: vda
device_type: disk
- boot_index: -1
delete_on_termination: false
volume_id: { get_param: backup_volume }
device_name: vdc
device_type: disk
flavor: { get_param: flavor }
key_name: { get_param: ssh_keypair }
name: { get_param: vm_name }
networks:
- port: { get_resource: vm_port_routable }
- port: { get_resource: test_vm_port_routable }
I want to add port "test_vm_port_routable" only if name is zee_1....
I tried with below condition but it is giving error :ERROR: The template section is invalid: conditions
conditions:
create_prod_res: { equal: [{get_param: "vm_name"},"zee_1"]}
resources:
vm_port_routable:
type: OS::Neutron::Port
properties:
network: { get_param: abc_routable_net }
name:
str_replace:
template: $stack_$name_routable_port
params:
$stack: { get_param: stack }
$name: { get_param: vm_name }
security_groups: [{ get_param: security_group }]
fixed_ips:
- ip_address: { get_param: port_ip_routable }
test_vm_port_routable:
type: OS::Neutron::Port
properties:
network: { get_param: test_zee_routable_net }
name:
str_replace:
template: $stack_$name_routable_port
params:
$stack: { get_param: stack }
$name: { get_param: vm_name }
security_groups: [{ get_param: security_group }]
fixed_ips:
- ip_address: { get_param: test_port_ip_routable }
zee_server:
type: OS::Nova::Server
properties:
block_device_mapping_v2:
- boot_index: 0
delete_on_termination: false
volume_id: { get_resource: root_volume }
device_name: vda
device_type: disk
- boot_index: -1
delete_on_termination: false
volume_id: { get_param: backup_volume }
device_name: vdc
device_type: disk
flavor: { get_param: flavor }
key_name: { get_param: ssh_keypair }
name: { get_param: vm_name }
condition:create_prod_res
networks:
- port: { get_resource: vm_port_routable }
- port: { get_resource: test_vm_port_routable }
with the above changes to template it is failing
can some one help me in this .....
If you read the specification, you will note that support for the conditions section was only added in Newton. So you need either:
heat_template_version: newton
Or:
heat_template_version: 2016-10-14
Or the equivalent for a later release. If you're running an openstack release earlier than Newton, you simply won't be able to use this feature.
I am trying to create a HEAT template that will use 'allowed_address_pairs' and neutron ports to support the concept of a virtual IP address shared between instances for an application similar to VRRP.
I've followed the examples from http://superuser.openstack.org/articles/implementing-high-availability-instances-with-neutron-using-vrrp and from https://github.com/nvpnathan/heat/blob/master/allowed-address-pairs.yaml to come up with my own template to achieve this, and it works great for a single virtual IP address.
Here is what that template looks like:
heat_template_version: 2013-05-23
description: Simple template using allowed_address_pairs for a virtual IP
parameters:
image:
type: string
label: Image name or ID
description: Image to be used for compute instance
default: "cirros"
flavor:
type: string
label: Flavor
description: Type of instance (flavor) to be used
default: "t1.small"
key:
type: string
label: Key name
description: Name of key-pair to be used for compute instance
default: "mykey"
ext_network:
type: string
label: External network name or ID
description: External network that can assign a floating IP
default: "provider"
test_virtual_ip:
type: string
label: Virtual IP address
description: Virtual IP address that can be used on different instances
default: "192.168.10.101"
resources:
# Create the internal test network
test_net:
type: OS::Neutron::Net
properties:
admin_state_up: true
name: test_net
# Create a subnet on the test network
test_subnet:
type: OS::Neutron::Subnet
properties:
name: test_subnet
cidr: 192.168.10.2/24
enable_dhcp: true
allocation_pools: [{end: 192.168.10.99, start: 192.168.10.10}]
gateway_ip: 192.168.10.1
network_id: { get_resource: test_net }
# Create router for the test network
test_router:
type: OS::Neutron::Router
properties:
admin_state_up: true
name: test_router
external_gateway_info: { "network": { get_param: ext_network }}
# Create router interface and attach to subnet
test_router_itf:
type: OS::Neutron::RouterInterface
properties:
router_id: { get_resource: test_router }
subnet_id: { get_resource: test_subnet }
# Create extra port for a virtual IP address
test_vip_port:
type: OS::Neutron::Port
properties:
network_id: { get_resource: test_net }
fixed_ips:
- ip_address: { get_param: test_virtual_ip }
# Create instance ports that have an internal IP and the virtual IP
instance1_test_vip_port:
type: OS::Neutron::Port
properties:
admin_state_up: true
network_id: { get_resource: test_net }
allowed_address_pairs:
- ip_address: { get_param: test_virtual_ip}
security_groups:
- default
# Create instances
test_instance_1:
type: OS::Nova::Server
properties:
name: instance1
image: { get_param: image }
flavor: { get_param: flavor }
key_name: { get_param: key }
networks:
- port: { get_resource: instance1_test_vip_port }
user_data_format: RAW
user_data: |
#cloud-config
password: mysecret
chpasswd: { expire: False }
ssh_pwauth: True
final_message: "The system is up after $UPTIME sec"
outputs:
instance1_ip:
description: IP address of the first instance
value: { get_attr: [test_instance_1, first_address] }
So far so good. Now I need to take this to the next level and assign multiple IP addresses that can be used as virtual IPs within an instance. The problem is that it is not known in advance how many will be needed when the instance is launched, so it needs to be a parameter and cannot simply be hard-coded as
- ip_address: {get_param: ip1}
- ip_address: {get_param: ip2}
and so on
In other words, the parameter test_virtual_ip needs to be a list of IP addresses rather than a single IP address, e.g. "191.168.10.101, 192.168.10.102, 192.168.10.103"
This impacts the definitions for test_vip_port and instance1_test_vip_port, but I can't figure out the correct syntax.
I tried this:
# Create extra port for a virtual IP address
test_vip_port:
type: OS::Neutron::Port
properties:
network_id: { get_resource: test_net }
fixed_ips: [{ get_param: test_virtual_ip }]
# Create instance ports that have an internal IP and the virtual IP
instance1_test_vip_port:
type: OS::Neutron::Port
properties:
admin_state_up: true
network_id: { get_resource: test_net }
allowed_address_pairs: [{ get_param: test_virtual_ip}]
security_groups:
- default
But get error "unicode object has no attribute get" when I try to launch the stack.
What is the proper syntax for providing a list of IP addresses as a parameter to the OS::Neutron::Port::fixed_ips and OS::Neutron::Port::allowed_address_pairs ?
The only solution I was able to get to work was to use the repeat/for_each construct and define the parameter as a comma_delimited_list as follows:
test_virtual_ip:
type: comma_delimited_list
label: Virtual IP address
description: Virtual IP address that can be used on different instances
default: "192.168.10.101,192.168.10.102"
test_vip_port:
type: OS::Neutron::Port
properties:
network_id: { get_resource: test_net }
fixed_ips:
repeat:
for_each:
<%ipaddr%>: {get_param: test_virtual_ip}
template:
ip_address: <%ipaddr%>
A couple of details for this to work:
Your heat template version must support the repeat/for_each construct, I used heat_template_version: 2016-04-08
Don't include any spaces in the list of IP addresses or you will get validation errors.
firewall_rules:
- { get_resource: heat_firewall_tcp_22 }
- { get_resource: heat_firewall_tcp_43 }
- { get_resource: heat_firewall_tcp_53 }
- { get_resource: heat_firewall_tcp_80 }
- { get_resource: heat_firewall_tcp_443 }
This works fine for multiple entries type: OS::Neutron::FirewallPolicy
- { get_resource: heat_firewall_pol_web_1 }
- { get_resource: heat_firewall_pol_dns_1 }
- { get_resource: fw_pol_ssh_1 }
This does not work throwing expecting some sort of string value error for
type: OS::Neutron::Firewall
I am guessing there is not any general standard for formatting multiple entries in yaml?
I have configured 2-Node Openstack(Icehouse) setup and heat is also configured. when creating instance using HOT template it is successfully launched. But when I'm trying to create the flat network using my yml file it shows below error-
"Unable to create the network. No tenant network is available for allocation"
heat_template_version: 2013-05-23
description: Simple template to deploy a single compute instance
resources:
provider_01:
type: OS::Neutron::ProviderNet
properties:
physical_network: physnet2
shared: true
network_type: flat
network_01:
type: OS::Neutron::Net
properties:
admin_state_up: true
name: External2
shared: true
#admin tenant id
tenant_id: 6ec23610836048ddb8f9294dbf89a41e
subnet_01:
type: OS::Neutron::Subnet
properties:
name: Subnet2
network_id: { get_resource: network_01 }
cidr: 192.168.56.0/24
gateway_ip: 192.168.56.1
allocation_pools: [{"start": 192.168.56.50, "end": 192.168.56.70}]
enable_dhcp: true
port_01:
type: OS::Neutron::Port
properties:
admin_state_up: true
network_id: { get_resource: network_01 }
#security_groups: "default"
heat_template_version: 2014-10-16
description: Template to create a tenant network along with router config
parameters:
ImageId:
type: string
label: cirros-0.3.2-x86_64
description: cirros-0.3.2-x86_64
resources:
demo-net:
type: OS::Neutron::Net
properties:
name: demo-net
demo-subnet:
type: OS::Neutron::Subnet
properties:
name: demo-subnet
network_id: { get_resource: demo-net }
cidr: 10.10.0.0/24
gateway_ip: 10.10.0.1
my_instance:
type: OS::Nova::Server
properties:
name: "demo_test_nw_01"
image: { get_param: ImageId }
flavor: "m1.tiny"
networks:
- network : { get_resource: demo-net }