[Openstack] HOT ResourceGroup index referencing with get_attr

Lars-Erik Helander lars-erik.helander at proceranetworks.com
Sun Mar 12 14:03:19 UTC 2017


I have also had similar problems with %index% and have resolved these using an additional “child” resource where I use “%index%” as a parameter and within the child resource use { get_attr: [instance, address, index] }

/Lasse

On 2017-03-12, 13:28, "Turbo Fredriksson" <turbo at bayour.com> wrote:

    I'm trying to figure out a way to setup a [number of] 'OS::Neutron::LBaaS::PoolMember’
    resource, from a list of IPs…
    
    I’m setting up my initial resources like this:
    
    —— s n i p ——
    resources:
      lbaas:
        type: Turbo::LoadBalancer
        properties:
          name: { get_param: 'OS::stack_name' }
          network: { get_param: network }
          protocol: TCP
          port_nr: 8300
          dnsname: consul
    
      instance:
        type: OS::Heat::ResourceGroup
        properties:
          count: { get_param: capacity }
          resource_def:
            type: Turbo::InstancePoolMember
            properties:
              name: { list_join: ['-', [ { get_param: "OS::stack_name"} ] ] }
              image: { get_param: image }
              pool_id: { get_attr: [lbaas, pool] }
              port_nr: { get_attr: [lbaas, port] }
              [etc]
    —— s n i p ——
    
    My “Turbo::LoadBalancer” is a [seriously] nested resource to setup
    the LBaaS, Pool, Monitor, FloatingIP, DNS forward and reverse
    resource and _one_ listener (the “initial” one).
    
    My "Turbo::InstancePoolMember” creates the instance(s) _and_ adds
    it/them to the listener created in the ‘lbaas’ resource.
    
    This work just fine, took quite a while to get all that working in a
    generic way. But it works.
    
    
    However, this specific service (Hashicorps Consul) I’m trying to create
    now needs additional listeners. Over all, I don’t “know” how many listeners
    a service need, so the nested resources only create one (at least one
    is required).
    
    
    My plan/idea was then to create additional listeners and add the
    ‘instance’s created from/in the ‘instance’ resource above to that
    listener in the HOT.
    
    I can create the listener just fine (this creates a listener and
    attaches a pool to that listener, then attaches the listener to the
    LBaaS created above):
    
    —— s n i p ——
      listener_tcp_8301:
        type: Turbo::LoadBalancerListener
        properties:
          name: { list_join: ['-', [ { get_param: "OS::stack_name"} ] ] }
          lbaas: { get_attr: [lbaas, lbaas] }
          protocol: TCP
          port_nr: 8301
    —— s n i p ——
    
    However, creating the members have shown to be a lot more complicated:
    
    —— s n i p ——
      member_tcp_8301:
        type: OS::Heat::ResourceGroup
        properties:
          count: { get_param: capacity }
          resource_def:
            type: OS::Neutron::LBaaS::PoolMember
            properties:
              protocol_port: 8301
              pool: { get_attr: [listener_tcp_8301, pool] }
              address: { get_attr: [instance, address, %index%] }
              subnet: { get_attr: [instance, port_subnet, %index%] }
    —— s n i p ——
    
    (All resources in this mail is in _one_ HOT, just referencing others, not
    shown).
    
    The problem is that
    
    	get_attr: [instance, address, %index%]
    
    doesn't seem to work :(
    
    
    
    This is what I’ve tried so far:
    
    —— s n i p ——
    address: { get_attr: [instance, address, "%index%"] }
    subnet: { get_attr: [instance, port_subnet, "%index%"] }
    2017-03-11 21:22:42Z [member_tcp_8301]: CREATE_FAILED  resources.member_tcp_8301: Property error: resources[1].properties.subnet: Value must be a string
    2017-03-11 21:22:42Z [admin-consul]: CREATE_FAILED  Resource CREATE failed: resources.member_tcp_8301: Property error: resources[1].properties.subnet: Value must be a string
    —— s n i p ——
    
    —— s n i p ——
    address: { get_attr: [instance, address.%index%] }
    subnet: { get_attr: [instance, port_subnet.%index%] }
    2017-03-11 23:31:35Z [admin-consul]: CREATE_FAILED  Resource CREATE failed: The Referenced Attribute (0 port_subnet.%index%) is incorrect.
    —— s n i p ——
    
    —— s n i p ——
    address: { get_attr: [instance, %index%, address] }
    subnet: { get_attr: [instance, %index%, port_subnet] }
    found character '%' that cannot start any token
      in "<unicode string>", line 71, column 43:
         ... address: { get_attr: [instance, %index%, address] }
    —— s n i p ——
    
    —— s n i p ——
    address: { get_attr: [instance, address, %index%] }
    subnet: { get_attr: [instance, port_subnet, %index%] }
    found character '%' that cannot start any token
      in "<unicode string>", line 71, column 52:
         ... { get_attr: [instance, address, %index%] }
    —— s n i p ——
    
    —— s n i p ——
    address: { get_attr: [instance, address, { list_join: ['', [ '', "%index%" ] ] } ] }
    subnet: { get_attr: [instance, port_subnet, { list_join: ['', [ '', "%index%" ] ] } ] }
    2017-03-12 00:32:56Z [member_tcp_8301]: CREATE_FAILED  resources.member_tcp_8301: Property error: resources[1].properties.subnet: Value must be a string
    2017-03-12 00:32:56Z [admin-consul]: CREATE_FAILED  Resource CREATE failed: resources.member_tcp_8301: Property error: resources[1].properties.subnet: Value must be a string
    —— s n i p ——
    
    I didn’t really expect the last one to work, but I figured I try something that
    would, in the shell, look like:
    
    	eval echo "$”${variable}
    
    
    The first example here seems like it almost (?) worked, at least in
    regards to the “address” field. Heat didn’t complain about that, only
    on the  “subnet” on the following line.
    
    
    I’m sure that "[instance, port_subnet]” DO work, because I have two
    outputs at the end of the HOT:
    
    —— s n i p ——
    outputs:
      address:
        value: { get_attr: [instance, address] }
        description: The IP address(es) of the server(s)
      lbaas_internal:
        value: { get_attr: [lbaas, lbaas_address] }
        description: The (internal) IP address of the LBaaS
      lbaas_external:
        value: { get_attr: [lbaas, address] }
        description: The (external) IP address of the LBaaS
      port_subnet:
        value: { get_attr: [instance, port_subnet] }
        description: The subnet ID(s) of the instance(s)
    —— s n i p ——
    
    and if/when I comment out the “member_tcp_8301” resource, I see
    (in Horizon):
    
    —— s n i p ——
    port_subnet     The subnet ID(s) of the instance(s)
    [
      "b776011f-0b72-4642-923e-935929dfb8f4",
      "b776011f-0b72-4642-923e-935929dfb8f4",
      "b776011f-0b72-4642-923e-935929dfb8f4"
    ]
    
    lbaas_internal  The (internal) IP address of the LBaaS
    10.0.17.28
    
    lbaas_external  The (external) IP address of the LBaaS
    10.0.6.11
    
    address         The IP address(es) of the server(s)
    [
      "10.0.17.25",
      "10.0.17.32",
      "10.0.17.26”
    ]
    —— s n i p ——
    
    
    _______________________________________________
    Mailing list: http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
    Post to     : openstack at lists.openstack.org
    Unsubscribe : http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack
    



More information about the Openstack mailing list