Locations are the environments to which Brooklyn deploys applications. Most commonly these are cloud services such as AWS, GCE, and IBM Softlayer. Brooklyn also supports deploying to a pre-provisioned network or to localhost (primarily useful for testing blueprints).

See also:


For most cloud provisioning tasks, Brooklyn uses Apache jclouds. The identifiers for some of the most commonly used jclouds-supported clouds are (or see the full list):

  • jclouds:aws-ec2:<region>: Amazon EC2, where :<region> might be us-east-1 or eu-west-1 (or omitted)
  • jclouds:softlayer:<region>: IBM Softlayer, where :<region> might be dal05 or ams01 (or omitted)
  • jclouds:google-compute-engine: Google Compute Engine
  • jclouds:openstack-nova:<endpoint>: OpenStack, where :<endpoint> is the access URL (required)
  • jclouds:cloudstack:<endpoint>: Apache CloudStack, where :<endpoint> is the access URL (required)

For any of these, of course, Brooklyn needs to be configured with an identity and a credential:

    credential: s3cr3tsq1rr3ls3cr3tsq1rr3ls3cr3tsq1rr3l

The above YAML can be embedded directly in blueprints, either at the root or on individual services. If you prefer to keep the credentials separate, you can instead store them as a catalog entry or set them in brooklyn.properties in the jclouds.<provider> namespace:


And in this case you can reference the location in YAML with location: jclouds:aws-ec2.

Alternatively, you can use the location wizard tool available within the web console to create any cloud location supported by Apache jclouds. This location will be saved as a catalog entry for easy reusability.

Brooklyn irons out many of the differences between clouds so that blueprints run similarly in a wide range of locations, including setting up access and configuring images and machine specs. The configuration options are described in more detail below.

In some cases, cloud providers have special features or unusual requirements. These are outlined in More Details for Specific Clouds.

OS Initial Login and Setup

Once a machine is provisioned, Brooklyn will normally attempt to log in via SSH and configure the machine sensibly.

The credentials for the initial OS log on are typically discovered from the cloud, but in some environments this is not possible. The keys loginUser and either loginUser.password or loginUser.privateKeyFile can be used to force Brooklyn to use specific credentials for the initial login to a cloud-provisioned machine.

(This custom login is particularly useful when using a custom image templates where the cloud-side account management logic is not enabled. For example, a vCloud (vCD) template can have guest customization that will change the root password. This setting tells Apache Brooklyn to only use the given password, rather than the initial randomly generated password that vCD returns. Without this property, there is a race for such templates: does Brooklyn manage to create the admin user before the guest customization changes the login and reboots, or is the password reset first (the latter means Brooklyn can never ssh to the VM). With this property, Brooklyn will always wait for guest customization to complete before it is able to ssh at all. In such cases, it is also recommended to use useJcloudsSshInit=false.)

Following a successful logon, Brooklyn performs the following steps to configure the machine:

  1. creates a new user with the same name as the user brooklyn is running as locally (this can be overridden with user, below).

  2. install the local user’s ~/.ssh/id_rsa.pub as an authorized_keys on the new machine, to make it easy for the operator to ssh in (override with privateKeyFile; or if there is no id_{r,d}sa{,.pub} an ad hoc keypair will be generated for the regular Brooklyn user; if there is a passphrase on the key, this must be supplied)

  3. give sudo access to the newly created user (override with grantUserSudo: false)

  4. disable direct root login to the machine

These steps can be skipped or customized as described below.

jclouds Config Keys

The following is a subset of the most commonly used configuration keys used to customize cloud provisioning. For more keys and more detail on the keys below, see JcloudsLocationConfig (src) .

VM Creation
  • Most providers require exactly one of either region (e.g. us-east-1) or endpoint (the URL, usually for private cloud deployments)

  • Hardware requirements can be specified, including minRam, minCores, and os64Bit; or as a specific hardwareId

  • VM image constraints can be set using osFamily (e.g. Ubuntu, CentOS, Debian, RHEL) and osVersionRegex, or specific VM images can be specified using imageId or imageNameRegex

  • Specific VM images can be specified using imageId or imageNameRegex

  • Specific Security Groups can be specified using securityGroups, as a list of strings (the existing security group names), or inboundPorts can be set, as a list of numeric ports (selected clouds only)

  • Where a key pair is registered with a target cloud for logging in to machines, Brooklyn can be configured to request this when provisioning VMs by setting keyPair (selected clouds only). Note that if this keyPair does not correspond your default ~/.ssh/id_rsa, you must typically also specify the corresponding loginUser.privateKeyFile as a file or URL accessible from Brooklyn.

  • A specific VM name (often the hostname) base to be used can be specified by setting groupId. By default, this name is constructed based on the entity which is creating it, including the ID of the app and of the entity. (As many cloud portals let you filter views, this can help find a specific entity or all machines for a given application.) For more sophisticated control over host naming, you can supply a custom CloudMachineNamer (src) , for example cloudMachineNamer: CustomMachineNamer. CustomMachineNamer (src)

    will use the entity’s name or following a template you supply. On many clouds, a random suffix will be appended to help guarantee uniqueness; this can be removed by setting vmNameSaltLength: 0 (selected clouds only).

  • A DNS domain name where this host should be placed can be specified with domainName (in selected clouds only)

  • User metadata can be attached using the syntax userMetadata: { key: value, key2: "value 2" } (or userMetadata=key=value,key2="value 2" in a properties file)

  • By default, several pieces of user metadata are set to correlate VMs with Brooklyn entities, prefixed with brooklyn-. This user metadata can be omitted by setting includeBrooklynUserMetadata: false.

  • You can specify the number of attempts Brooklyn should make to create machines with machineCreateAttempts (jclouds only). This is useful as an efficient low-level fix for those occasions when cloud providers give machines that are dead on arrival. You can of course also resolve it at a higher level with a policy such as ServiceRestarter (src) .

  • If you want to investigate failures, set destroyOnFailure: false to keep failed VM’s around. (You’ll have to manually clean them up.) The default is false: if a VM fails to start, or is never ssh’able, then the VM will be terminated.

    OS Setup
  • user and password can be used to configure the operating user created on cloud-provisioned machines

  • The loginUser config key (and subkeys) control the initial user to log in as, in cases where this cannot be discovered from the cloud provider

  • Private keys can be specified using privateKeyFile; these are not copied to provisioned machines, but are required if using a local public key or a pre-defined authorized_keys on the server. (For more information on SSH keys, see here.)

  • If there is a passphrase on the key file being used, you must supply it to Brooklyn for it to work, of course! privateKeyPassphrase does the trick (as in brooklyn.location.jclouds.privateKeyPassphrase, or other places where privateKeyFile is valid). If you don’t like keys, you can just use a plain old password.

  • Public keys can be specified using publicKeyFile, although these can usually be omitted if they follow the common pattern of being the private key file with the suffix .pub appended. (It is useful in the case of loginUser.publicKeyFile, where you shouldn’t need, or might not even have, the private key of the root user when you log in.)

  • Provide a list of URLs to public keys in extraSshPublicKeyUrls, or the data of one key in extraSshPublicKeyData, to have additional public keys added to the authorized_keys file for logging in. (This is supported in most but not all locations.)

  • Use dontCreateUser to have Brooklyn run as the initial loginUser (usually root), without creating any other user.

  • A post-provisioning setup.script can be specified to run an additional script, before making the Location available to entities. This may take the form of a URL of a script or a data URI. Note that if using a data URI it is usually a good idea to base64 this string to escape problem characters in more complex scripts. The base64 encoded script should then be prefixed with data:text/plain;base64, to denote this. For example if you wanted to disable a yum repository called reponame prior to using the machine, you could use the following command:

    sudo yum-config-manager --disable reponame

    Base64 encoding can be done with a with a tool such as this or a linux command such as:

    echo "sudo yum-config-manager --disable reponame" | base64

    With the base64 prefix this would then look like this:

    setup.script: data:text/plain;base64,c3VkbyB5dW0tY29uZmlnLW1hbmFnZXIgLS1kaXNhYmxlIHJlcG9uYW1l

    The setup.script can also take FreeMarker variables in a setup.script.vars property. Variables are set in the format key1:value1,key2:value2 and used in the form ${key1}. So for the above example:

    setup.script.vars: repository:reponame


    setup.script: data:sudo yum-config-manager --disable ${repository}

    or encoded in base64:

    setup.script: data:text/plain;base64,c3VkbyB5dW0tY29uZmlnLW1hbmFnZXIgLS1kaXNhYmxlICR7cmVwb3NpdG9yeX0=

    This enables the name of the repository to be passed in to the script.

  • Use openIptables: true to automatically configure iptables, to open the TCP ports required by the software process. One can alternatively use stopIptables: true to entirely stop the iptables service.

  • Use installDevUrandom: true to fall back to using /dev/urandom rather than /dev/random. This setting is useful for cloud VMs where there is not enough random entropy, which can cause /dev/random to be extremely slow (causing ssh to be extremely slow to respond).

  • Use useJcloudsSshInit: false to disable the use of the native jclouds support for initial commands executed on the VM (e.g. for creating new users, setting root passwords, etc.). Instead, Brooklyn’s ssh support will be used. Timeouts and retries are more configurable within Brooklyn itself. Therefore this option is particularly recommended when the VM startup is unusual (for example, if guest customizations will cause reboots and/or will change login credentials).

  • Use brooklyn.ssh.config.noDeleteAfterExec: true to keep scripts on the server after execution. The contents of the scripts and the stdout/stderr of their execution are available in the Brooklyn web console, but sometimes it can also be useful to have them on the box. This setting prevents scripts executed on the VMs from being deleted on completion. Note that some scripts run periodically so this can eventually fill a disk; it should only be used for dev/test.

Custom Template Options

jclouds supports many additional options for configuring how a virtual machine is created and deployed, many of which are for cloud-specific features and enhancements. Brooklyn supports some of these, but if what you are looking for is not supported directly by Brooklyn, we instead offer a mechanism to set any parameter that is supported by the jclouds template options for your cloud.

Part of the process for creating a virtual machine is the creation of a jclouds TemplateOptions object. jclouds providers extends this with extra options for each cloud - so when using the AWS provider, the object will be of type AWSEC2TemplateOptions. By examining the source code, you can see all of the options available to you.

The templateOptions config key takes a map. The keys to the map are method names, and Brooklyn will find the method on the TemplateOptions instance; it then invokes the method with arguments taken from the map value. If a method takes a single parameter, then simply give the argument as the value of the key; if the method takes multiple parameters, the value of the key should be an array, containing the argument for each parameter.

For example, here is a complete blueprint that sets some AWS EC2 specific options:

location: AWS_eu-west-1
- type: org.apache.brooklyn.entity.software.base.EmptySoftwareProcess
      subnetId: subnet-041c8373
      mapNewVolumeToDeviceName: ["/dev/sda1", 100, true]
      securityGroupIds: ['sg-4db68928']

Here you can see that we set three template options:

  • subnetId is an example of a single parameter method. Brooklyn will effectively try to run the statement templateOptions.subnetId("subnet-041c88373");
  • mapNewVolumeToDeviceName is an example of a multiple parameter method, so the value of the key is an array. Brooklyn will effectively true to run the statement templateOptions.mapNewVolumeToDeviceName("/dev/sda1", 100, true);
  • securityGroupIds demonstrates an ambiguity between the two types; Brooklyn will first try to parse the value as a multiple parameter method, but there is no method that matches this parameter. In this case, Brooklyn will next try to parse the value as a single parameter method which takes a parameter of type List; such a method does exist so the operation will succeed.

If the method call cannot be matched to the template options available - for example if you are trying to set an AWS EC2 specific option but your location is an OpenStack cloud - then a warning is logged and the option is ignored.

Cloud Machine Naming

The name that Apache Brooklyn generates for your virtual machine will, by default, be based on your Apache Brooklyn server name and the IDs of the entities involved. This is the name you see in places such as the AWS console and will look something like:


If you have created a lot of virtual machines, this kind of naming may not be helpful. This can be changed using the following YAML in your location’s brooklyn.config:

cloudMachineNamer: org.apache.brooklyn.core.location.cloud.names.CustomMachineNamer
custom.machine.namer.machine: My-Custom-Name-${entity.displayName}

A FreeMarker format is used in custom.machine.namer.machine which can take values from places such as the launching entity or location.

The above example will create a name such as:


Allowing you to more easily identify your virtual machines.

More Details on Specific Clouds

Clouds vary in the format of the identity, credential, endpoint, and region. Some also have their own idiosyncracies. More details for configuring some common clouds is included below. You may also find these sources helpful:

  • The template brooklyn.properties file in the Getting Started guide contains numerous examples of configuring specific clouds, including the format of credentials and options for sometimes-fiddly private clouds.
  • The jclouds guides describes low-level configuration sometimes required for various clouds.

Amazon Web Services (AWS)


AWS has an “access key” and a “secret key”, which correspond to Brooklyn’s identity and credential respectively.

These keys are the way for any programmatic mechanism to access the AWS API.

To generate an access key and a secret key, see jclouds instructions and AWS IAM instructions.

An example of the expected format is shown below:

    region: us-east-1
    credential: abcdefghijklmnopqrstu+vwxyzabcdefghijklm

Users are strongly recommended to use externalized configuration for better credential management, for example using Vault.

Common Configuration Options

Below are examples of configuration options that use values specific to AWS EC2:

  • The region is the AWS region code. For example, region: us-east-1. You can in-line the region name using the following format: jclouds:aws-ec2:us-east-1. A specific availability zone within the region can be specified by including its letter identifier as a suffix. For example, region: us-east-1a.

  • The hardwareId is the instance type. For example, hardwareId: m4.large.

  • The imageId is the region-specific AMI id. For example, imageId: us-east-1/ami-05ebd06c.

  • The securityGroups option takes one or more names of pre-existing security groups. For example, securityGroups: mygroup1 or securityGroups: [ mygroup1, mygroup2 ].

Using Subnets and Security Groups

Apache Brooklyn can run with AWS VPC and both public and private subnets. Simply provide the subnet-a1b2c3d4 as the networkName when deploying:

    region: us-west-1
    networkName: subnet-a1b2c3d4   # use your subnet ID

Subnets are typically used in conjunction with security groups. Brooklyn does not attempt to open additional ports when private subnets or security groups are supplied, so the subnet and ports must be configured appropriately for the blueprints being deployed. You can configure a default security group with appropriate (or all) ports opened for access from the appropriate (or all) CIDRs and security groups, or you can define specific securityGroups on the location or as provisioning.properties on the entities.

Make sure that Brooklyn has access to the machines under management. This includes SSH, which might be done with a public IP created with inbound access on port 22 permitted for a CIDR range including the IP from which Brooklyn contacts it. Alternatively you can run Brooklyn on a machine in that same subnet, or set up a VPN or jumphost which Brooklyn will use.

EC2 “Classic” Problems with VPC-only Hardware Instance Types

If you have a pre-2014 Amazon account, it is likely configured in some regions to run in “EC2 Classic” mode by default, instead of the more modern “VPC” default mode. This can cause failures when requesting certain hardware configurations because many of the more recent hardware “instance types” only run in “VPC” mode. For instance when requesting an instance with minRam: 8gb, Brooklyn may opt for an m4.large, which is a VPC-only instance type. If you are in a region configured to use “EC2 Classic” mode, you may see a message such as this:

400 VPCResourceNotSpecified: The specified instance type can only be used in a VPC.
A subnet ID or network interface ID is required to carry out the request.

This is a limitation of “legacy” accounts. The easiest fixes are either:

  • specify an instance type which is supported in classic, such as m3.xlarge (see below)
  • move to a different region where VPC is the default (eu-central-1 should work as it only offers VPC mode, irrespective of the age of your AWS account)
  • get a new AWS account – “VPC” will be the default mode (Amazon recommend this and if you want to migrate existing deployments they provide detailed instructions)

To understand the situation, the following resources may be useful:

If you want to solve this problem with your existing account, you can create a VPC and instruct Brooklyn to use it:

  1. Use the “Start VPC Wizard” option in the VPC dashboard, making sure it is for the right region, and selecting a “Single Public Subnet”. (More information is in these AWS instructions.)
  2. Once the VPC is created, open the “Subnets” view and modify the “Public subnet” so that it will “Auto-assign Public IP”.
  3. Next click on the “Security Groups” and find the default security group for that VPC. Modify its “Inbound Rules” to allow “All traffic” from “Anywhere”. (Or for more secure options, see the instructions in the previous section, “Using Subnets”.)
  4. Finally make a note of the subnet ID (e.g. subnet-a1b2c3d4) for use in Brooklyn.

You can then deploy blueprints to the subnet, allowing VPC hardware instance types, by specifying the subnet ID as the networkName in your YAML blueprint. This is covered in the previous section, “Using Subnets”.

Tidying up after jclouds

Security groups are not always deleted by jclouds. This is due to a limitation in AWS (see https://issues.apache.org/jira/browse/JCLOUDS-207). In brief, AWS prevents the security group from being deleted until there are no VMs using it. However, there is eventual consistency for recording which VMs still reference those security groups: after deleting the VM, it can sometimes take several minutes before the security group can be deleted. jclouds retries for 3 seconds, but does not block for longer.

Whilst there is eventual consistency for recording which VMs still reference security groups, after deleting a VM, it can sometimes take several minutes before a security group can be deleted

There is utility written by Cloudsoft for deleting these unused resources: http://blog.abstractvisitorpattern.co.uk/2013/03/tidying-up-after-jclouds.html.

Google Compute Engine (GCE)


GCE uses a service account e-mail address for the identity and a private key as the credential.

To obtain credentials for GCE, use the GCE web page’s “APIs & auth -> Credentials” page, creating a “Service Account” of type JSON, then extracting the client_email as the identity and private_key as the credential. For more information, see the jclouds instructions.

An example of the expected format is shown below. Note that when supplying the credential in a properties file, it can either be one long line with \n representing the new line characters, or in YAML it can be split over multiple lines as below:

    region: us-central1-a
    identity: 1234567890-somet1mesArand0mU1Dhere@developer.gserviceaccount.com
    credential: |
      -----BEGIN RSA PRIVATE KEY-----
      -----END RSA PRIVATE KEY-----

It is also possible to have the credential be the path of a local file that contains the key. However, this can make it harder to setup and manage multiple Brooklyn servers (particularly when using high availability mode).

Users are strongly recommended to use externalized configuration for better credential management, for example using Vault.


GCE accounts can have low default quotas.

It is easy to request a quota increase by submitting a quota increase form.


GCE accounts often have a limit to the number of networks that can be created. One work around is to manually create a network with the required open ports, and to refer to that named network in Brooklyn’s location configuration.

To create a network, see GCE network instructions.

For example, for dev/demo purposes an “everything” network could be created that opens all ports.

  Name   everything
  Description   opens all tcp ports
  Source IP Ranges
  Allowed protocols and ports   tcp:0-65535 and udp:0-65535

To configure the location to use this, you can include a location configuration option like:

  network: https://www.googleapis.com/compute/v1/projects/<project name>/global/networks/everything


GCE images often have little entropy. One option to work around this is to use installDevUrandom: true. For more information, see Linux kernel entropy.

IBM SoftLayer


Credentials can be obtained from the Softlayer API, under “administrative -> user administration -> api-access”.

For example:

    region: ams01
    identity: my-user-name
    credential: 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef

Users are strongly recommended to use externalized configuration for better credential management, for example using Vault.

Common Configuration Options

Below are examples of configuration options that use values specific to Softlayer:

  • The region is the Softlayer datacenter. For example, region: dal05.

  • The hardwareId is an auto-generated combination of the hardware configuration options. This is because there is no concept of hardwareId or hardware profile names in Softlayer. An example value is hardwareId: "cpu=1,memory=1024,disk=25,type=LOCAL".

  • The imageId is the Image template. For example, imageId: CENTOS_6_64.

VLAN Selection

SoftLayer may provision VMs in different VLANs, even within the same region. Some applications require VMs to be on the same internal subnet; blueprints for these can specify this behaviour in SoftLayer in one of two ways.

The VLAN ID can be set explicitly using the fields primaryNetworkComponentNetworkVlanId and primaryBackendNetworkComponentNetworkVlanId of SoftLayerTemplateOptions when specifying the location being used in the blueprint, as follows:

    region: ams01
      # Enter your preferred network IDs
      primaryNetworkComponentNetworkVlanId: 1153481
      primaryBackendNetworkComponentNetworkVlanId: 1153483

This method requires that a VM already exist and you look up the IDs of its VLANs, for example in the SoftLayer console UI, and that subsequently at least one VM in that VLAN is kept around. If all VMs on a VLAN are destroyed SoftLayer may destroy the VLAN. Creating VLANs directly and then specifying them as IDs here may not work. Add a line note

The second method tells Brooklyn to discover VLAN information automatically: it will provision one VM first, and use the VLAN information from it when provisioning subsequent machines. This ensures that all VMs are on the same subnet without requiring any manual VLAN referencing, making it very easy for end-users.

To use this method, we tell brooklyn to use SoftLayerSameVlanLocationCustomizer as a location customizer. This can be done on a location as follows:

    region: lon02
    - $brooklyn:object:
        type: org.apache.brooklyn.location.jclouds.softlayer.SoftLayerSameVlanLocationCustomizer
    softlayer.vlan.scopeUid: "my-custom-scope"
    softlayer.vlan.timeout: 10m

Usually you will want the scope to be unique to a single application, but if you need multiple applications to share the same VLAN, simply configure them with the same scope identifier.

It is also possible with many blueprints to specify this as one of the provisioning.properties on an application:

- type: org.apache.brooklyn.entity.stock.BasicApplication
  id: same-vlan-application
      - $brooklyn:object:
          type: org.apache.brooklyn.location.jclouds.softlayer.SoftLayerSameVlanLocationCustomizer
    softlayer.vlan.scopeUid: "my-custom-scope"
    softlayer.vlan.timeout: 10m

If you are writing an entity in Java, you can also use the helper method forScope(String) to create the customizer. Configure the provisioning flags as follows:

JcloudsLocationCustomizer vlans = SoftLayerSameVlanLocationCustomizer.forScope("my-custom-scope");
flags.put(JcloudsLocationConfig.JCLOUDS_LOCATION_CUSTOMIZERS.getName(), ImmutableList.of(vlans));

Configuration Options

The allowed configuration keys for the SoftLayerSameVlanLocationCustomizer are:

  • softlayer.vlan.scopeUid The scope identifier for locations whose VMs will have the same VLAN.

  • softlayer.vlan.timeout The amount of time to wait for a VM to be configured before timing out without setting the VLAN ids.

  • softlayer.vlan.publicId A specific public VLAN ID to use for the specified scope.

  • softlayer.vlan.privateId A specific private VLAN ID to use for the specified scope.

An entity being deployed to a customized location will have the VLAN ids set as sensors, with the same names as the last two configuration keys.

NOTE If the SoftLayer location is already configured with specific VLANs then this customizer will have no effect.


Apache jclouds

Support for OpenStack is provided by Apache jclouds. For more information, see their guide here.

Connection Details

The endpoint URI is that of keystone (normally on port 5000).

The identity normally consists of a colon-separated tenant and username. The credential is the password. For example:

    endpoint: http://x.x.x.x:5000/v2.0/
    identity: "your-tenant:your-username"
    credential: your-password

OpenStack Nova access information can be downloaded from the openstack web interface, for example as an openrc.sh file. It is usually available from API Access tab in “Access & Security” section. This file will normally contain the identity and credential.

Users are strongly recommended to use externalized configuration for better credential management, for example using Vault.

Common Configuration Options

Below are examples of configuration options that use values specific to OpenStack environments:

  • The imageId is the id of an image. For example, imageId: RegionOne/08086159-8b0b-4970-b332-a7a929ee601f. These ids can be found from the the CLI or the web-console, for example in IBM Blue Box London, the URL is https://tenant-region.openstack.blueboxgrid.com/project/images/.

  • The hardwareId is the flavor id. For example hardwareId: RegionOne/1. These ids can be found from the the CLI or the web-console, for example in IBM Blue Box, the URL is https://tenant-region.openstack.blueboxgrid.com/admin/flavors/.

The default flavors are shown below (though the set of flavors can be managed by the admin):

| ID  | Name      | Memory_MB | Disk |
| 1   | m1.tiny   | 512       | 1    |
| 2   | m1.small  | 2048      | 20   |
| 3   | m1.medium | 4096      | 40   |
| 4   | m1.large  | 8192      | 80   |
| 5   | m1.xlarge | 16384     | 160  |

For further configuration options, consult jclouds Nova template options. These can be used with the templateOptions configuration option.


When multiple networks are available you should indicate which ones machines should join. Do this by setting the desired values id as an option in the templateOptions configuration:

      # Assign the node to all networks in the list.
      - network-one-id
      - network-two-id
      - ...

Floating IPs

The autoAssignFloatingIp option means that a floating ip will be assigned to the VM at provision-time.

A floating IP pool name can also be specified. If not set, a floating IP from any available pool will be chosen. This is set using the template option. For example:

    autoAssignFloatingIp: true
      # Pool names to use when allocating a floating IP
      - "pool name"

Basic Location Structure

This is a basic inline YAML template for an OpenStack location:

        endpoint: http://x.x.x.x:5000/v2.0/
        identity: "your-tenant:your-username"
        credential: your-password

        # imageId, hardwareId, and loginUser* are optional
        imageId: your-region-name/your-image-id
        hardwareId: your-region-name/your-flavor-id
        loginUser: 'ubuntu'
        loginUser.privateKeyFile: /path/to/your/privatekey

        jclouds.openstack-nova.auto-generate-keypairs: false
        jclouds.openstack-nova.auto-create-floating-ips: true

            networks: [ "your-network-id" ]
            floatingIpPoolNames: [ "your-floatingIp-pool" ]
            securityGroups: ['your-security-group']

            # Optional if 'jclouds.openstack-nova.auto-generate-keypairs' is assigned to 'true'
            keyPairName: "your-keypair"

This is the same OpenStack location in a format that can be added to your brooklyn.properties file:

brooklyn.location.named.My\ OpenStack=jclouds:openstack-nova:http://x.x.x.x:5000/v2.0/
brooklyn.location.named.My\ OpenStack.identity=your-tenant:your-username
brooklyn.location.named.My\ OpenStack.credential=your-password
brooklyn.location.named.My\ OpenStack.endpoint=http://x.x.x.x:5000/v2.0/

brooklyn.location.named.My\ OpenStack.imageId=your-region-name/your-image-id
brooklyn.location.named.My\ OpenStack.hardwareId=your-region-name/your-flavor-id
brooklyn.location.named.My\ OpenStack.loginUser=ubuntu
brooklyn.location.named.My\ OpenStack.loginUser.privateKeyFile=/path/to/your/privatekey
brooklyn.location.named.My\ OpenStack.openstack-nova.auto-generate-keypairs=false
brooklyn.location.named.My\ OpenStack.openstack-nova.auto-create-floating-ips=true

brooklyn.location.named.My\ OpenStack.networks=your-network-id
brooklyn.location.named.My\ OpenStack.floatingIpPoolNames=your-floatingIp-pool
brooklyn.location.named.My\ OpenStack.securityGroups=your-security-group
brooklyn.location.named.My\ OpenStack.keyPair=your-keypair


Cloud Credentials Failing

If the cloud API calls return 401 Unauthorized (e.g. in a org.jclouds.rest.AuthorizationException), then this could be because the credentials are incorrect.

A good way to check this is to try the same credentials with the OpenStack nova command line client.

Unable to SSH: Wrong User

If SSH authentication fails, it could be that the login user is incorrect. For most clouds, this is inferred from the image metadata, but if no (or the wrong) login user is specified then it will
default to root. The correct login user can be specified using the configuration option loginUser. For example, loginUser: ubuntu.

The use of the wrong login user can also result in the obscure message, caused by an unexpected response saying to use a different user. For more technical information, see this sshj github issue. The message is:

Received message too long 1349281121

I Want to Use My Own KeyPair

By default, jclouds will auto-generate a new key pair for the VM. This key pair will be deleted automatically when the VM is deleted.

Alternatively, you can use a pre-existing key pair. If so, you must also specify the corresponding private key (pem file, or data) to be used for the initial login. The name used in the keyPair configuration must match the name of a key pair that has already been added in OpenStack. For example:

    jclouds.openstack-nova.auto-generate-keypairs: false
    keyPair: "my-keypair"
    loginUser: ubuntu
    loginUser.privateKeyFile: /path/to/my/privatekey.pem

Error “doesn’t contain … —–BEGIN”

If using loginUser.privateKeyFile (or loginUser.privateKeyData), this is expected to be a .pem file. If a different format is used (e.g. a .ppk file), it will give an error like that below:

Error invoking start at EmptySoftwareProcessImpl{id=TrmhitVc}: chars
PuTTY-User-Key-File-2: ssh-rsa
doesn't contain % line [-----BEGIN ]

Warning Message: “Ignoring request to set…”

If you see a warning log message like that below:

2016-06-23 06:05:12,297 WARN  o.a.b.l.j.JcloudsLocation [brooklyn-execmanager-XlwkWB3k-312]: 
Ignoring request to set template option loginUser because this is not supported by 

It can mean that the location configuration option is in the wrong place. The configuration under templateOptions must correspond to those options on the jclouds Nova template options. However, template options such as loginUser are top-level configuration options that should not be inside the templateOptions section.

HttpResponseException Accessing Compute Endpoint

The Keystone endpoint is first queried to get the API access endpoints for the appropriate services.

Some private OpenStack installs are (mis)configured such that the returned addresses are not always directly accessible. It could be that the service is behind a VPN, or that they rely on hostnames that are only in a private DNS.

You can find the service endpoints in OpenStack, either using the CLI or the web-console. For example, in Blue Box the URL is https://tenant-region.openstack.blueboxgrid.com/project/access_and_security/. You can then check if the Compute service endpoint is directly reachable.

VM Failing to Provision

It can be useful to drop down to the OpenStack nova CLI, or to jclouds, to confirm that VM provisioning is working and to check which options are required.

For example, try following these jclouds instructions.

jclouds Namespace Issue

A change to Nova’s API (in the Mitaka release) resulted in all extensions having the same “fake” namespace which the current version of jclouds does not yet support.

If you are having problems deploying to OpenStack, consult your Brooklyn debug log and look for the following:

"namespace": "http://docs.openstack.org/compute/ext/fake_xml"

If you already have jclouds:openstack-mitaka-nova, then try using this instead of the vanilla jclouds:openstack-nova. For example:

        endpoint: http://x.x.x.x:5000/v2.0/
        identity: "your-tenant:your-username"
        credential: your-password
            networks: [ "your-network-id" ]
            floatingIpPoolNames: [ "your-floatingIp-pool" ]

Note that the following values will be set by default when omitted above:

jclouds.openstack-nova.auto-generate-keypairs: true
jclouds.openstack-nova.auto-create-floating-ips: true

If you do not have openstack-mitaka-nova, you can build and install it using the following steps:

  • Generate a JAR openstack-mitaka-nova-1.9.3-cloudsoft.20160831.jar by building: https://github.com/cloudsoft/jclouds-openstack-mitaka-nova
  • If using Karaf, install this bundle (e.g. bundle:install mvn:io.cloudsoft.jclouds.api/openstack-mitaka-nova/1.9.3-cloudsoft.20160831), and start it (e.g. bundle:start openstack-mitaka-nova).
  • Or if using the old-style main, copy the jar into the lib/patch directory and retart.

Apache CloudStack

Connection Details

The endpoint URI will normally have the suffix /client/api/.

The identity is the “api key” and the credential is the “secret key”. These can be generated in the CloudStack gui: under accounts, select “view users”, then “generate key”.

    endpoint: https://cloud.acme.com/client/api
    identity: abcdefghijklmnopqrstuvwxyz01234567890-abcdefghijklmnopqrstuvwxyz01234567890-abcdefghij
    credential: mycred-abcdefghijklmnopqrstuvwxyz01234567890-abcdefghijklmnopqrstuvwxyz01234567890-abc

Users are strongly recommended to use externalized configuration for better credential management, for example using Vault.

Common Configuration Options

Below are examples of configuration options that use values specific to CloudStack environments:

  • The imageId is the template id. For example, imageId: db0bcce3-9e9e-4a87-a953-2f46b603498f.

  • The region is CloudStack zone id. For example region: 84539b9c-078e-458a-ae26-c3ffc5bb1ec9..

  • networkName is the network id (within the given zone) to be used. For example, networkName: 961c03d4-9828-4037-9f4d-3dd597f60c4f.

For further configuration options, consult jclouds CloudStack template options. These can be used with the templateOptions configuration option.

Using a Pre-existing Key Pair

The configuration below uses a pre-existing key pair:

    loginUser: root
    loginUser.privateKeyFile: /path/to/keypair.pem
    keyPair: my-keypair

Using Pre-existing Security Groups

To specify existing security groups, their IDs must be used rather than their names (note this differs from the configuration on other clouds!).

The configuration below uses a pre-existing security group:

      generateSecurityGroup: false
      - 12345678-90ab-def0-1234-567890abcdef

Using Static NAT

Assigning a public IP to a VM at provision-time is referred to as “static NAT” in CloudStack parlance. To give some consistency across different clouds, the configuration option is named autoAssignFloatingIp. For example, autoAssignFloatingIp: false.

CloudMonkey CLI

The CloudStack CloudMonkey CLI is a very useful tool. It gives is an easy way to validate that credentials are correct, and to query
the API to find the correct zone IDs etc.

Useful commands include:

# for finding the ids of the zones:
cloudmonkey api listZones

# for finding the ids of the networks.
cloudmonkey api listNetworks | grep -E "id =|name =|========="

CloudStack Troubleshooting

These troubleshooting tips are more geared towards problems encountered in old test/dev CloudStack environment.

Resource Garbage Collection Issues

The environment may run out of resources, due to GC issues, preventing the user from creating new VMs or allocating IP addresses (May respond with this error message: errorCode=INTERNAL_ERROR, errorText=Job failed due to exception Unable to create a deployment for VM). There are two options worth checking it to enforce clearing up the zombie resources:

  • Go to the Accounts tab in the webconsole and tap on the Update Resource Count button.
  • Restart the VPC in question from the Network tab.

Releasing Allocated Public IP Addresses

Releasing an allocated Public IP from the web console did not free up the resources. Instead CloudMonkey can be used to dissociate IPs and expunge VMs.

Here is a CloudMonkey script to dissociate any zombie IPs:

cloudmonkey set display json;
cloudmonkey api listPublicIpAddresses | grep '"id":' > ips.txt; 
sed -i -e s/'      "id": "'/''/g ips.txt;
sed -i -e s/'",'/''/g ips.txt
for line in $(cat ips.txt); do cloudmonkey api disassociateIpAddress id="$line"; done
rm ips.txt;
cloudmonkey set display default;

Restarting VPCs

Errors have been encountered when a zone failed to provision new VMs, with messages like:

Job failed due to exception Resource [Host:15] is unreachable: Host 15: Unable to start instance due to null

The workaround was to restart the VPC networks:

  • Log into the CloudStack web-console.
  • Go to Network -> VPC (from the “select view”)
  • For each of the VPCs, click on the “+” in the “quickview” column, and invoke “restart VPC”.

Other symptoms of this issue were that: 1) an administrator could still provision VMs using the admin account, which used a different network; and 2) the host number was very low, so it was likely to be a system host/VM that was faulty.

Inheritance and Named Locations

Named locations can be defined for commonly used groups of properties, with the syntax brooklyn.location.named.your-group-name. followed by the relevant properties. These can be accessed at runtime using the syntax named:your-group-name as the deployment location.

Some illustrative examples using named locations and showing the syntax and properties above are as follows:

# Production pool of machines for my application (deploy to named:prod1)

# AWS using my company's credentials and image standard, then labelling images so others know they're mine
brooklyn.location.named.company-jungle.userMetadata=application=my-jungle-app,owner="Bob Johnson"

brooklyn.location.named.AWS\ Virginia\ Large\ Centos = jclouds:aws-ec2
brooklyn.location.named.AWS\ Virginia\ Large\ Centos.region = us-east-1
brooklyn.location.named.AWS\ Virginia\ Large\ Centos.imageId=us-east-1/ami-7d7bfc14
brooklyn.location.named.AWS\ Virginia\ Large\ Centos.user=root
brooklyn.location.named.AWS\ Virginia\ Large\ Centos.minRam=4096

Named locations can refer to other named locations using named:xxx as their value. These will inherit the configuration and can override selected keys. Properties set in the namespace of the provider (e.g. b.l.jclouds.aws-ec2.KEY=VALUE) will be inherited by everything which extends AWS Sub-prefix strings are also inherited up to brooklyn.location.*, except that they are filtered for single-word and other known keys (so that we exclude provider-scoped properties when looking at sub-prefix keys). The precedence for configuration defined at different levels is that the value defined in the most specific context will apply.

This is rather straightforward and powerful to use, although it sounds rather more complicated than it is! The examples below should make it clear. You could use the following to install a public key on all provisioned machines, an additional public key in all AWS machines, and no extra public key in prod1:

brooklyn.location.jclouds.aws-ec2.extraSshPublicKeyUrls="[ \"http://me.com/public_key\", \"http://me.com/aws_public_key\" ]"

And in the example below, a config key is repeatedly overridden. Deploying location: named:my-extended-aws will result in an aws-ec2 machine in us-west-1 (by inheritance) with VAL6 for KEY:



“Bring-your-own-nodes” mode is useful in production, where machines have been provisioned by someone else, and during testing, to cut down provisioning time.

Your nodes must meet the following prerequisites:

  • A suitable OS must have been installed on all nodes
  • The node must be running sshd (or similar)
  • the brooklyn user must be able to ssh to each node as root or as a user with passwordless sudo permission. (For more information on SSH keys, see here.)

To deploy to machines with known IP’s in a blueprint, use the following syntax:

    user: brooklyn
    privateKeyFile: ~/.ssh/brooklyn.pem

Some of the login properties as described above for jclouds are supported, but not loginUser (as no users are created), and not any of the VM creation parameters such as minRam and imageId. (These clearly do not apply in the same way, and they are not by default treated as constraints, although an entity can confirm these where needed.) As before, if the brooklyn user and its default key are authorized for the hosts, those fields can be omitted.

Named locations can also be configured in your brooklyn.properties, using the format byon:(key=value,key2=value2). For convenience, for hosts wildcard globs are supported.

brooklyn.location.named.On-Prem\ Iron\ Example=byon:(hosts=",,produser2@10.9.2.{10,11,20-29}")
brooklyn.location.named.On-Prem\ Iron\ Example.user=produser1
brooklyn.location.named.On-Prem\ Iron\ Example.privateKeyFile=~/.ssh/produser_id_rsa
brooklyn.location.named.On-Prem\ Iron\ Example.privateKeyPassphrase=s3cr3tpassphrase

Alternatively, you can create a specific BYON location through the location wizard tool available within the web console. This location will be saved as a catalog entry for easy reusability.

For more complex host configuration, one can define custom config values per machine. In the example below, there will be two machines. The first will be a machine reachable on ssh -i ~/.ssh/brooklyn.pem -p 8022 myuser@ The second is a windows machine, reachable over WinRM. Each machine has also has a private address (e.g. for within a private network).

    - ssh:
      privateAddresses: []
      privateKeyFile: ~/.ssh/brooklyn.pem
      user: myuser
    - winrm:
      privateAddresses: []
      password: mypassword
      user: myuser
      osFamily: windows

The BYON location also supports a machine chooser, using the config key byon.machineChooser. This allows one to plugin logic to choose from the set of available machines in the pool. For example, additional config could be supplied for each machine. This could be used (during the call to location.obtain()) to find the config that matches the requirements of the entity being provisioned. See FixedListMachineProvisioningLocation.MACHINE_CHOOSER.

SSH Keys

SSH keys are one of the simplest and most secure ways to access remote servers. They consist of two parts:

  • A private key (e.g. id_rsa) which is known only to one party or group

  • A public key (e.g. id_rsa.pub) which can be given to anyone and everyone, and which can be used to confirm that a party has a private key (or has signed a communication with the private key)

In this way, someone – such as you – can have a private key, and can install a public key on a remote machine (in an authorized_keys file) for secure automated access. Commands such as ssh (and Brooklyn) can log in without revealing the private key to the remote machine, the remote machine can confirm it is you accessing it (if no one else has the private key), and no one snooping on the network can decrypt of any of the traffic.

Creating an SSH Key

If you don’t have an SSH key, create one with:

$ ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

Localhost Setup

If you want to deploy to localhost, ensure that you have a public and private key, and that your key is authorized for ssh access:

# _Appends_ id_rsa.pub to authorized_keys. Other keys are unaffected.
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

Now verify that your setup by running the command: ssh localhost echo hello world

If your setup is correct, you should see hello world printed back at you.

On the first connection, you may see a message similar to this:

The authenticity of host 'localhost (::1)' can't be established.
RSA key fingerprint is 7b:e3:8e:c6:5b:2a:05:a1:7c:8a:cf:d1:6a:83:c2:ad.
Are you sure you want to continue connecting (yes/no)?

Simply answer ‘yes’ and then repeat the command again.

If this isn’t the case, see below.

Potential Problems

  • MacOS user? In addition to the above, enable “Remote Login” in “System Preferences > Sharing”.

  • Got a passphrase? Set brooklyn.location.localhost.privateKeyPassphrase as described here. If you’re not sure, or you don’t know what a passphrase is, you can test this by executing ssh-keygen -y. If it does not ask for a passphrase, then your key has no passphrase. If your key does have a passphrase, you can remove it by running ssh-keygen -p.

  • Check that you have an ~/.ssh/id_rsa file (or id_dsa) and a corresponding public key with a .pub extension; if not, create one as described above

  • ~/.ssh/ or files in that directory may have permissions they shouldn’t: they should be visible only to the user (apart from public keys), both on the source machine and the target machine. You can verify this with ls -l ~/.ssh/: lines should start with -rw------- or -r-------- (or -rwx------ for directories). If it does not, execute chmod go-rwx ~/.ssh ~/.ssh/*.

  • Sometimes machines are configured with different sets of support SSL/TLS versions and ciphers; if command-line ssh and scp work, but Brooklyn/java does not, check the versions enabled in Java and on both servers.

  • Missing entropy: creating and using ssh keys requires randomness available on the servers, usually in /dev/random; see here for more information


If passwordless ssh login to localhost and passwordless sudo is enabled on your machine, you should be able to deploy some blueprints with no special configuration, just by specifying location: localhost in YAML.

If you use a passphrase or prefer a different key, these can be configured as follows:


Alternatively, you can create a specific localhost location through the location wizard tool available within the web console. This location will be saved as a catalog entry for easy reusability.

Passwordless Sudo

If you encounter issues or for more information, see SSH Keys Localhost Setup.

For some blueprints, passwordless sudo is required. (Try executing sudo whoami to see if it prompts for a password. To enable passwordless sudo for your account, a line must be added to the system /etc/sudoers file.
To edit the file, use the visudo command:

sudo visudo

Add this line at the bottom of the file, replacing username with your own user:


If executing the following command does not ask for your password, then sudo has been setup correctly:

sudo whoami

Specialized Locations

Some additional location types are supported for specialized situations:

Single Host

The spec host, taking a string argument (the address) or a map (host, user, password, etc.), provides a convenient syntax when specifying a single host. For example:

location: host:(
- type: org.apache.brooklyn.entity.webapp.jboss.JBoss7Server

Or, in brooklyn.properties, set brooklyn.location.named.host1=host:(

The Multi Location

The spec multi allows multiple locations, specified as targets, to be combined and treated as one location.

Sequential Consumption

In its simplest form, this will use the first target location where possible, and will then switch to the second and subsequent locations when there are no machines available.

In the example below, it provisions the first node to, then it provisions into AWS us-east-1 region (because the bring-your-own-nodes region will have run out of nodes).

    - byon:(hosts=
    - jclouds:aws-ec2:us-east-1
- type: org.apache.brooklyn.entity.group.DynamicCluster
    initialSize: 3
        type: org.apache.brooklyn.entity.machine.MachineEntity
Round-Robin Consumption and Availability Zones for Clustered Applications

A DynamicCluster can be configured to cycle through its deployment targets round-robin when provided with a location that supports the AvailabilityZoneExtension – the multi location supports this extension.

The configuration option dynamiccluster.zone.enable on DynamicCluster tells it to query the given location for AvailabilityZoneExtension support. If the location supports it, then the cluster will query for the list of availability zones (which in this case is simply the list of targets) and deploy to them round-robin.

In the example below, the cluster will request VMs round-robin across three different locations (in this case, the locations were already added to the catalog, or defined in brooklyn.properties).

    - my-location-1
    - my-location-2
    - my-location-3
- type: org.apache.brooklyn.entity.group.DynamicCluster
    dynamiccluster.zone.enable: true
    initialSize: 3
        type: org.apache.brooklyn.entity.machine.MachineEntity

Of course, clusters can also be deployed round-robin to real availability zones offered by cloud providers, as long as their locations support AvailabilityZoneExtension. Currently, only AWS EC2 locations support this feature.

In the example below, the cluster will request VMs round-robin across the availability zones provided by AWS EC2 in the “us-east-1” region.

location: jclouds:aws-ec2:us-east-1
- type: org.apache.brooklyn.entity.group.DynamicCluster
    dynamiccluster.zone.enable: true
    initialSize: 3
        type: org.apache.brooklyn.entity.machine.MachineEntity

For more information about AWS EC2 availability zones, see this guide.

Custom alternatives to round-robin are also possible using the configuration option dynamiccluster.zone.placementStrategy on DynamicCluster.

The Server Pool

The ServerPool (src)

entity type allows defining an entity which becomes available as a location.