diff --git a/README.md b/README.md index 9d638892..765facc6 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,17 @@ [![Circle CI](https://circleci.com/gh/cloudify-cosmo/cloudify-hello-world-example/tree/master.svg?&style=shield)](https://circleci.com/gh/cloudify-cosmo/cloudify-hello-world-example/tree/master) -This repository contains a Hello World example blueprint based on OpenStack. +This repository contains Hello World example blueprints, for OpenStack, AWS and existing hosts. -This example creates a VM on OpenStack and starts an HTTP server using a bash script. +All blueprints start an HTTP server on a VM: + +* [ec2-blueprint.yaml](ec2-blueprint.yaml) creates a Linux VM on AWS +* [ec2-windows-blueprint.yaml](ec2-windows-blueprint.yaml) creates a Windows VM on AWS +* [openstack-blueprint.yaml](openstack-blueprint.yaml) creates a Linux VM on OpenStack +* [openstack-windows-blueprint.yaml](openstack-windows-blueprint.yaml) creates a Windows VM on OpenStack +* [openstack-windows-winrm-blueprint.yaml](openstack-windows-winrm-blueprint.yaml) creates a Windows VM on OpenStack +* [singlehost-blueprint.yaml](singlehost-blueprint.yaml) creates no infrastructure (installs the app on an existing VM) +* [no-monitoring-singlehost-blueprint.yaml](no-monitoring-singlehost-blueprint.yaml) similar to `singlehost-blueprint.yaml`, + however does not include monitoring configuration If you're only now starting to work with Cloudify see our [Getting Started Guide](http://docs.getcloudify.org/latest/intro/getting-started/). diff --git a/blueprint.yaml b/blueprint.yaml deleted file mode 100644 index 77c112c5..00000000 --- a/blueprint.yaml +++ /dev/null @@ -1,90 +0,0 @@ -tosca_definitions_version: cloudify_dsl_1_3 - -description: > - The blueprint describes an OpenStack vm created using Cloudify's OpenStack plugin - and simple web server started using Cloudify's script plugin. - In addition, an OpenStack floating ip and security group are created and associated with the created vm. - -imports: - - http://www.getcloudify.org/spec/cloudify/4.1m1/types.yaml - - http://www.getcloudify.org/spec/openstack-plugin/2.0.1/plugin.yaml - - http://www.getcloudify.org/spec/diamond-plugin/1.3.5/plugin.yaml - -inputs: - webserver_port: - description: The HTTP web server port - default: 8080 - agent_user: - description: User name used when SSH-ing into the started machine - image: - description: Openstack image name or id to use for the new server - flavor: - description: Openstack flavor name or id to use for the new server - -node_templates: - virtual_ip: - type: cloudify.openstack.nodes.FloatingIP - security_group: - type: cloudify.openstack.nodes.SecurityGroup - properties: - rules: - - remote_ip_prefix: 0.0.0.0/0 - port: { get_property: [ http_web_server, port ] } - vm: - type: cloudify.openstack.nodes.Server - properties: - agent_config: - user: { get_input: agent_user } - image: { get_input: image } - flavor: { get_input: flavor } - relationships: - - type: cloudify.openstack.server_connected_to_floating_ip - target: virtual_ip - - type: cloudify.openstack.server_connected_to_security_group - target: security_group - interfaces: - ########################################################### - # We are infact telling cloudify to install a diamond - # monitoring agent on the server. - # - # (see https://github.com/BrightcoveOS/Diamond) - ########################################################### - cloudify.interfaces.monitoring_agent: - install: - implementation: diamond.diamond_agent.tasks.install - inputs: - diamond_config: - interval: 1 - start: diamond.diamond_agent.tasks.start - stop: diamond.diamond_agent.tasks.stop - uninstall: diamond.diamond_agent.tasks.uninstall - cloudify.interfaces.monitoring: - start: - implementation: diamond.diamond_agent.tasks.add_collectors - inputs: - collectors_config: - CPUCollector: {} - MemoryCollector: {} - LoadAverageCollector: {} - DiskUsageCollector: - config: - devices: x?vd[a-z]+[0-9]*$ - NetworkCollector: {} - http_web_server: - type: cloudify.nodes.WebServer - properties: - port: { get_input: webserver_port } - relationships: - - type: cloudify.relationships.contained_in - target: vm - interfaces: - cloudify.interfaces.lifecycle: - configure: scripts/configure.sh - start: scripts/start.sh - stop: scripts/stop.sh - -outputs: - http_endpoint: - description: Web server external endpoint - value: { concat: ['http://', { get_attribute: [virtual_ip, floating_ip_address] }, - ':', { get_property: [http_web_server, port] }] } diff --git a/include/inputs.yaml b/include/inputs.yaml new file mode 100644 index 00000000..1e0b2a61 --- /dev/null +++ b/include/inputs.yaml @@ -0,0 +1,5 @@ +inputs: + webserver_port: + description: > + The HTTP web server port. + default: 8080 diff --git a/include/openstack-inputs.yaml b/include/openstack-inputs.yaml new file mode 100644 index 00000000..70251f91 --- /dev/null +++ b/include/openstack-inputs.yaml @@ -0,0 +1,29 @@ +inputs: + keystone_username: + type: string + keystone_password: + type: string + keystone_tenant_name: + type: string + keystone_url: + type: string + region: + type: string + floating_network_name: + description: The name of the network to use for allocating a floating ip + image: + description: Openstack image name or id to use for the new server + flavor: + description: Openstack flavor name or id to use for the new server + network_name: + description: Openstack network name the new server will be connected to + agents_security_group_name: + description: Name of security group that enables access to agent hosts + key_pair_name: + default: 'hello-world' + description: Openstack key pair name of the key to associate with the new server + private_key_path: + default: '~/hw.pem' + description: | + Path to the private key which will be used for connecting to the server + on the manager or machine running CLI if running in local mode. diff --git a/include/scaling.yaml b/include/scaling.yaml new file mode 100644 index 00000000..dc7a5515 --- /dev/null +++ b/include/scaling.yaml @@ -0,0 +1,16 @@ +inputs: + default_scale_count: + type: integer + description: Number of scale units to deploy by default + default: 1 + +groups: + vm_and_ip: + members: [vm, public_ip] + +policies: + scale_policy: + type: cloudify.policies.scaling + properties: + default_instances: { get_input: default_scale_count } + targets: [vm_and_ip] diff --git a/no-monitoring-singlehost-blueprint.yaml b/no-monitoring-singlehost-blueprint.yaml index eb621931..bea8d634 100644 --- a/no-monitoring-singlehost-blueprint.yaml +++ b/no-monitoring-singlehost-blueprint.yaml @@ -1,27 +1,31 @@ tosca_definitions_version: cloudify_dsl_1_3 description: > - This blueprint installs a simple web server on the manager VM using Cloudify's script plugin. + This blueprint installs a simple web server on a pre-existing machine. It is similar to the blueprint + "singlehost-blueprint.yaml", except that this one omits the monitoring-related configuration. + IMPORTANT: The VM being used must be associated with a security group (or multiple security groups) + that, cumulatively, allows TCP access via the port specified by the "webserver_port" input (defaults to 8080), + as well as TCP access for the Cloudify Agent installation process. imports: - http://www.getcloudify.org/spec/cloudify/4.1m1/types.yaml - http://www.getcloudify.org/spec/diamond-plugin/1.3.5/plugin.yaml + - include/inputs.yaml inputs: server_ip: description: > - The ip of the server the application will be deployed on. + The ip of the machine that the application will be installed on. agent_user: description: > - User name used when SSH-ing into the started machine. + User account used when SSH-ing into the existing machine for the purpose + of Cloudify Agent installation. agent_private_key_path: description: > - Path to a private key that resides on the management machine. - SSH-ing into agent machines will be done with this key. - webserver_port: - description: > - The HTTP web server port. - default: 8080 + Path to a private key to use when SSH-ing into the existing machine for + agent installation. This path must be available on the machine that is executing the + installation workflow (that is, the Cloudify Manager machine in a managed environment, + or the local machine in a local invocation). node_templates: vm: @@ -31,6 +35,7 @@ node_templates: agent_config: user: { get_input: agent_user } key: { get_input: agent_private_key_path } + http_web_server: type: cloudify.nodes.WebServer properties: diff --git a/openstack-blueprint.yaml b/openstack-blueprint.yaml index 4e709d27..6ac3e44e 100644 --- a/openstack-blueprint.yaml +++ b/openstack-blueprint.yaml @@ -1,62 +1,67 @@ tosca_definitions_version: cloudify_dsl_1_3 description: > - The blueprint describes an OpenStack vm created using Cloudify's OpenStack plugin - and simple web server started using Cloudify's script plugin. - In addition, an OpenStack floating ip and security group are created and associated with the created vm. + The blueprint installs a simple web server on a Linux virtual machine under OpenStack. + Other than a VM, this blueprint creates a keypair, a security group, and a floating IP for the application. + This blueprint assumes that a security group for Cloudify Agents already exists; its name should + be provided for the "agents_security_group" input. imports: - http://www.getcloudify.org/spec/cloudify/4.1m1/types.yaml - http://www.getcloudify.org/spec/openstack-plugin/2.0.1/plugin.yaml - http://www.getcloudify.org/spec/diamond-plugin/1.3.5/plugin.yaml + - include/openstack-inputs.yaml + - include/inputs.yaml + - include/scaling.yaml inputs: - webserver_port: - description: The HTTP web server port - default: 8080 agent_user: - description: User name used when SSH-ing into the started machine - image: - description: Openstack image name or id to use for the new server - flavor: - description: Openstack flavor name or id to use for the new server - network_name: - description: Openstack network name the new server will be connected to - floating_network_id: - description: The id of the network to use for allocating a floating ip - key_pair_name: - description: Openstack key pair name of the key to associate with the new server - private_key_path: - description: | - Path to the private key which will be used for connecting to the server - on the manager or machine running CLI if running in local mode. + description: > + User account used when SSH-ing into the existing machine for the purpose + of Cloudify Agent installation. + +dsl_definitions: + openstack_configuration: &openstack_configuration + username: { get_input: keystone_username } + password: { get_input: keystone_password } + tenant_name: { get_input: keystone_tenant_name } + auth_url: { get_input: keystone_url } + region: { get_input: region } node_templates: - virtual_ip: + public_ip: type: cloudify.openstack.nodes.FloatingIP properties: + openstack_config: *openstack_configuration floatingip: - floating_network_id: { get_input: floating_network_id } + floating_network_name: { get_input: floating_network_name } + + agents_security_group: + type: cloudify.openstack.nodes.SecurityGroup + properties: + openstack_config: *openstack_configuration + use_external_resource: true + resource_id: { get_input: agents_security_group_name } - security_group: + app_security_group: type: cloudify.openstack.nodes.SecurityGroup properties: + openstack_config: *openstack_configuration rules: - port: { get_property: [ http_web_server, port ] } remote_ip_prefix: 0.0.0.0/0 - - port: 22 - remote_ip_prefix: 0.0.0.0/0 keypair: type: cloudify.openstack.nodes.KeyPair properties: - use_external_resource: true + openstack_config: *openstack_configuration resource_id: { get_input: key_pair_name } private_key_path: { get_input: private_key_path } vm: type: cloudify.openstack.nodes.Server properties: + openstack_config: *openstack_configuration agent_config: user: { get_input: agent_user } key: { get_property: [ keypair, private_key_path ] } @@ -67,42 +72,41 @@ node_templates: - type: cloudify.openstack.server_connected_to_keypair target: keypair - type: cloudify.openstack.server_connected_to_floating_ip - target: virtual_ip + target: public_ip + - type: cloudify.openstack.server_connected_to_security_group + target: agents_security_group - type: cloudify.openstack.server_connected_to_security_group - target: security_group + target: app_security_group interfaces: cloudify.interfaces.lifecycle: create: inputs: args: - security_groups: [{ get_attribute: [ security_group, external_name ]}] - ########################################################### - # We are infact telling cloudify to install a diamond - # monitoring agent on the server. - # - # (see https://github.com/BrightcoveOS/Diamond) - ########################################################### + # Needed until JIRA issue OPENSTACK-38 is resolved. + security_groups: + - { get_attribute: [ agents_security_group, external_name ]} + - { get_attribute: [ app_security_group, external_name ]} cloudify.interfaces.monitoring_agent: - install: - implementation: diamond.diamond_agent.tasks.install - inputs: - diamond_config: - interval: 1 - start: diamond.diamond_agent.tasks.start - stop: diamond.diamond_agent.tasks.stop - uninstall: diamond.diamond_agent.tasks.uninstall + install: + implementation: diamond.diamond_agent.tasks.install + inputs: + diamond_config: + interval: 1 + start: diamond.diamond_agent.tasks.start + stop: diamond.diamond_agent.tasks.stop + uninstall: diamond.diamond_agent.tasks.uninstall cloudify.interfaces.monitoring: - start: - implementation: diamond.diamond_agent.tasks.add_collectors - inputs: - collectors_config: - CPUCollector: {} - MemoryCollector: {} - LoadAverageCollector: {} - DiskUsageCollector: - config: - devices: x?vd[a-z]+[0-9]*$ - NetworkCollector: {} + start: + implementation: diamond.diamond_agent.tasks.add_collectors + inputs: + collectors_config: + CPUCollector: {} + MemoryCollector: {} + LoadAverageCollector: {} + DiskUsageCollector: + config: + devices: x?vd[a-z]+[0-9]*$ + NetworkCollector: {} http_web_server: type: cloudify.nodes.WebServer @@ -120,5 +124,5 @@ node_templates: outputs: http_endpoint: description: Web server external endpoint - value: { concat: ['http://', { get_attribute: [virtual_ip, floating_ip_address] }, + value: { concat: ['http://', { get_attribute: [public_ip, floating_ip_address] }, ':', { get_property: [http_web_server, port] }] } diff --git a/openstack-windows-blueprint.yaml b/openstack-windows-blueprint.yaml index 730b0e67..d73eb4af 100644 --- a/openstack-windows-blueprint.yaml +++ b/openstack-windows-blueprint.yaml @@ -1,59 +1,63 @@ tosca_definitions_version: cloudify_dsl_1_3 description: > - The blueprint describes an OpenStack Windows vm created using Cloudify's OpenStack plugin - and simple web server started using Cloudify's script plugin. - In addition, an OpenStack floating ip and security group are created and associated with the created vm. + The blueprint installs a simple web server on a Linux virtual machine under OpenStack. + Other than a VM, this blueprint creates a keypair, a security group, and a floating IP for the application. + This blueprint assumes that a security group for Cloudify Agents already exists; its name should + be provided for the "agents_security_group" input. + The Windows VM's agent installation process uses the "init_script" agent installation method, which uses a built-in + script to install the agent. This script is sufficient in most cases. The advantage here is that WinRM is not being + used at all, which means that the WinRM port is not required to be open on the agent VM. imports: - http://www.getcloudify.org/spec/cloudify/4.1m1/types.yaml - http://www.getcloudify.org/spec/openstack-plugin/2.0.1/plugin.yaml + - include/openstack-inputs.yaml + - include/inputs.yaml + - include/scaling.yaml -inputs: - webserver_port: - description: The HTTP web server port - default: 8080 - image: - description: Openstack image name or id to use for the new server - flavor: - description: Openstack flavor name or id to use for the new server - network_name: - description: Openstack network name the new server will be connected to - floating_network_id: - description: The id of the network to use for allocating a floating ip - key_pair_name: - description: Openstack key pair name of the key to associate with the new server - private_key_path: - description: | - Path to the private key which will be used for decrypting the VMs password - generated by OpenStack. +dsl_definitions: + openstack_configuration: &openstack_configuration + username: { get_input: keystone_username } + password: { get_input: keystone_password } + tenant_name: { get_input: keystone_tenant_name } + auth_url: { get_input: keystone_url } + region: { get_input: region } node_templates: - virtual_ip: + public_ip: type: cloudify.openstack.nodes.FloatingIP properties: + openstack_config: *openstack_configuration floatingip: - floating_network_id: { get_input: floating_network_id } + floating_network_name: { get_input: floating_network_name } - security_group: + agents_security_group: type: cloudify.openstack.nodes.SecurityGroup properties: + openstack_config: *openstack_configuration + use_external_resource: true + resource_id: { get_input: agents_security_group_name } + + app_security_group: + type: cloudify.openstack.nodes.SecurityGroup + properties: + openstack_config: *openstack_configuration rules: - remote_ip_prefix: 0.0.0.0/0 port: { get_property: [ http_web_server, port ] } - - remote_ip_prefix: 0.0.0.0/0 - port: 5985 keypair: type: cloudify.openstack.nodes.KeyPair properties: - use_external_resource: true + openstack_config: *openstack_configuration resource_id: { get_input: key_pair_name } private_key_path: { get_input: private_key_path } vm: type: cloudify.openstack.nodes.WindowsServer properties: + openstack_config: *openstack_configuration agent_config: install_method: init_script image: { get_input: image } @@ -63,15 +67,20 @@ node_templates: - type: cloudify.openstack.server_connected_to_keypair target: keypair - type: cloudify.openstack.server_connected_to_floating_ip - target: virtual_ip + target: public_ip + - type: cloudify.openstack.server_connected_to_security_group + target: app_security_group - type: cloudify.openstack.server_connected_to_security_group - target: security_group + target: agents_security_group interfaces: cloudify.interfaces.lifecycle: create: inputs: args: - security_groups: [{ get_attribute: [ security_group, external_name ]}] + # Needed until JIRA issue OPENSTACK-38 is resolved. + security_groups: + - { get_attribute: [ agents_security_group, external_name ]} + - { get_attribute: [ app_security_group, external_name ]} http_web_server: type: cloudify.nodes.WebServer @@ -101,5 +110,5 @@ node_templates: outputs: http_endpoint: description: Web server external endpoint - value: { concat: ['http://', { get_attribute: [virtual_ip, floating_ip_address] }, + value: { concat: ['http://', { get_attribute: [public_ip, floating_ip_address] }, ':', { get_property: [http_web_server, port] }] } diff --git a/openstack-windows-winrm-blueprint.yaml b/openstack-windows-winrm-blueprint.yaml index e82e763b..13151164 100644 --- a/openstack-windows-winrm-blueprint.yaml +++ b/openstack-windows-winrm-blueprint.yaml @@ -1,45 +1,73 @@ tosca_definitions_version: cloudify_dsl_1_3 description: > - The blueprint describes an OpenStack Windows vm created using Cloudify's OpenStack plugin - and simple web server started using winrm. - In addition, an OpenStack floating ip and security group are created and associated with the created vm. + The blueprint installs a simple web server on a Linux virtual machine under OpenStack. + Other than a VM, this blueprint creates a keypair, a security group, and a floating IP for the application. + This blueprint assumes that a security group for Cloudify Agents already exists; its name should + be provided for the "agents_security_group" input. + The Windows VM's agent installation process is done using WinRM. The userdata passed to the new VM + ensures that WinRM is configured in a way that is compatible with Cloudify's agent installation process. + This approach should only be used in special cases; it is recommended to use the "init_script" approach which + is demonstrated in "openstack-windows-blueprint.yaml". imports: - http://www.getcloudify.org/spec/cloudify/4.1m1/types.yaml - http://www.getcloudify.org/spec/openstack-plugin/2.0.1/plugin.yaml + - include/openstack-inputs.yaml + - include/inputs.yaml + - include/scaling.yaml inputs: - webserver_port: - description: The HTTP web server port - default: 8080 agent_user: description: User name used when SSH-ing into the started machine - image: - description: Openstack image name or id to use for the new server - flavor: - description: Openstack flavor name or id to use for the new server + +dsl_definitions: + openstack_configuration: &openstack_configuration + username: { get_input: keystone_username } + password: { get_input: keystone_password } + tenant_name: { get_input: keystone_tenant_name } + auth_url: { get_input: keystone_url } + region: { get_input: region } node_templates: - virtual_ip: + public_ip: type: cloudify.openstack.nodes.FloatingIP - security_group: + properties: + openstack_config: *openstack_configuration + floatingip: + floating_network_name: { get_input: floating_network_name } + + agents_security_group: + type: cloudify.openstack.nodes.SecurityGroup + properties: + openstack_config: *openstack_configuration + use_external_resource: true + resource_id: { get_input: agents_security_group_name } + + app_security_group: type: cloudify.openstack.nodes.SecurityGroup properties: + openstack_config: *openstack_configuration rules: - remote_ip_prefix: 0.0.0.0/0 port: { get_property: [ http_web_server, port ] } - - remote_ip_prefix: 0.0.0.0/0 - port: 5985 - - remote_ip_prefix: 0.0.0.0/0 - port: 5986 + + keypair: + type: cloudify.openstack.nodes.KeyPair + properties: + openstack_config: *openstack_configuration + resource_id: { get_input: key_pair_name } + private_key_path: { get_input: private_key_path } + vm: type: cloudify.openstack.nodes.WindowsServer properties: + openstack_config: *openstack_configuration agent_config: user: { get_input: agent_user } image: { get_input: image } flavor: { get_input: flavor } + management_network_name: { get_input: network_name } server: userdata: | #ps1_sysnative @@ -51,10 +79,23 @@ node_templates: &netsh advfirewall firewall add rule name="WinRM 5985" protocol=TCP dir=in localport=5985 action=allow &netsh advfirewall firewall add rule name="WinRM 5986" protocol=TCP dir=in localport=5986 action=allow relationships: + - type: cloudify.openstack.server_connected_to_keypair + target: keypair - type: cloudify.openstack.server_connected_to_floating_ip - target: virtual_ip + target: public_ip + - type: cloudify.openstack.server_connected_to_security_group + target: app_security_group - type: cloudify.openstack.server_connected_to_security_group - target: security_group + target: agents_security_group + interfaces: + cloudify.interfaces.lifecycle: + create: + inputs: + args: + # Needed until JIRA issue OPENSTACK-38 is resolved. + security_groups: + - { get_attribute: [ agents_security_group, external_name ]} + - { get_attribute: [ app_security_group, external_name ]} http_web_server: type: cloudify.nodes.WebServer @@ -84,6 +125,5 @@ node_templates: outputs: http_endpoint: description: Web server external endpoint - value: { concat: ['http://', { get_attribute: [virtual_ip, floating_ip_address] }, + value: { concat: ['http://', { get_attribute: [public_ip, floating_ip_address] }, ':', { get_property: [http_web_server, port] }] } - diff --git a/singlehost-blueprint.yaml b/singlehost-blueprint.yaml index d0c324ab..39aac19d 100644 --- a/singlehost-blueprint.yaml +++ b/singlehost-blueprint.yaml @@ -1,27 +1,28 @@ tosca_definitions_version: cloudify_dsl_1_3 description: > - This blueprint installs a simple web server on the manager VM using Cloudify's script plugin. + This blueprint installs a simple web server on a pre-existing machine. + IMPORTANT: The VM being used must be associated with a security group (or multiple security groups) + that, cumulatively, allows TCP access via the port specified by the "webserver_port" input (defaults to 8080), + as well as TCP access for the Cloudify Agent installation process. imports: - http://www.getcloudify.org/spec/cloudify/4.1m1/types.yaml - http://www.getcloudify.org/spec/diamond-plugin/1.3.5/plugin.yaml + - include/inputs.yaml inputs: + agent_user: + description: > + User name used when SSH-ing into the hosting machine for the purpose + of installing the Cloudify Agent. server_ip: description: > The ip of the server the application will be deployed on. - agent_user: - description: > - User name used when SSH-ing into the started machine. agent_private_key_path: description: > Path to a private key that resides on the management machine. SSH-ing into agent machines will be done with this key. - webserver_port: - description: > - The HTTP web server port. - default: 8080 node_templates: vm: @@ -32,12 +33,6 @@ node_templates: user: { get_input: agent_user } key: { get_input: agent_private_key_path } interfaces: - ########################################################### - # We are infact telling cloudify to install a diamond - # monitoring agent on the server. - # - # (see https://github.com/BrightcoveOS/Diamond) - ########################################################### cloudify.interfaces.monitoring_agent: install: implementation: diamond.diamond_agent.tasks.install