diff --git a/.gitignore b/.gitignore
index 9c9642b1d..c0d72a23e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,27 @@ target/*
.idea
*.iml
/target
+
+*/vendor-cookbooks
+*.tar.gz
+
+*~
+*#
+.#*
+\#*#
+.*.sw[a-z]
+*.un~
+pkg/
+
+# Berkshelf
+.vagrant
+Berksfile.lock
+
+# Bundler
+Gemfile.lock
+bin/*
+.bundle/*
+
+.coverage/*
+.kitchen/
+.kitchen.local.yml
diff --git a/cookbooks/asf-webapp-demo/Berksfile b/cookbooks/asf-webapp-demo/Berksfile
new file mode 100644
index 000000000..0ac9b78cf
--- /dev/null
+++ b/cookbooks/asf-webapp-demo/Berksfile
@@ -0,0 +1,3 @@
+source "https://supermarket.getchef.com"
+
+metadata
diff --git a/cookbooks/asf-webapp-demo/README.md b/cookbooks/asf-webapp-demo/README.md
new file mode 100644
index 000000000..f8570b04a
--- /dev/null
+++ b/cookbooks/asf-webapp-demo/README.md
@@ -0,0 +1,68 @@
+asf-webapp-demo Cookbook
+========================
+TODO: Enter the cookbook description here.
+
+e.g.
+This cookbook makes your favorite breakfast sandwich.
+
+Requirements
+------------
+TODO: List your cookbook requirements. Be sure to include any requirements this cookbook has on platforms, libraries, other cookbooks, packages, operating systems, etc.
+
+e.g.
+#### packages
+- `toaster` - asf-webapp-demo needs toaster to brown your bagel.
+
+Attributes
+----------
+TODO: List your cookbook attributes here.
+
+e.g.
+#### asf-webapp-demo::default
+
+
+ Key |
+ Type |
+ Description |
+ Default |
+
+
+ ['asf-webapp-demo']['bacon'] |
+ Boolean |
+ whether to include bacon |
+ true |
+
+
+
+Usage
+-----
+#### asf-webapp-demo::default
+TODO: Write usage instructions for each cookbook.
+
+e.g.
+Just include `asf-webapp-demo` in your node's `run_list`:
+
+```json
+{
+ "name":"my_node",
+ "run_list": [
+ "recipe[asf-webapp-demo]"
+ ]
+}
+```
+
+Contributing
+------------
+TODO: (optional) If this is a public cookbook, detail the process for contributing. If this is a private cookbook, remove this section.
+
+e.g.
+1. Fork the repository on Github
+2. Create a named feature branch (like `add_component_x`)
+3. Write your change
+4. Write tests for your change (if applicable)
+5. Run the tests, ensuring they all pass
+6. Submit a Pull Request using Github
+
+License and Authors
+-------------------
+Authors: TODO: List authors
diff --git a/cookbooks/asf-webapp-demo/Vagrantfile b/cookbooks/asf-webapp-demo/Vagrantfile
new file mode 100644
index 000000000..0ee3023be
--- /dev/null
+++ b/cookbooks/asf-webapp-demo/Vagrantfile
@@ -0,0 +1,47 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+Vagrant.configure('2') do |config|
+ config.omnibus.chef_version = '11.4.2'
+ config.berkshelf.enabled = true
+
+ config.vm.provider "virtualbox" do |v, override|
+ override.vm.box = 'centos-6.5'
+ override.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_#{override.vm.box}_chef-provisionerless.box"
+ config.vm.hostname = 'cicd-infrastructure'
+
+ config.cache.scope = :box
+ config.cache.auto_detect = true
+
+ v.memory = 1024
+ v.cpus = 2
+ end
+
+ config.vm.provider "aws" do |aws, override|
+ override.vm.box = "aws-dummy"
+ override.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
+ aws.instance_type = "m3.medium"
+ aws.access_key_id = ENV["AWS_ACCESS_KEY"]
+ aws.secret_access_key = ENV["AWS_SECRET_KEY"]
+ aws.keypair_name = "-53b42275e4b0aaf59b4b1459"
+ aws.ami = "ami-52009e3b"
+ aws.security_groups = "default"
+ aws.user_data = "#!/bin/bash
+ echo 'Defaults:ec2-user !requiretty' > \
+ /etc/sudoers.d/999-vagrant-cloud-init-requiretty
+ chmod 440 /etc/sudoers.d/999-vagrant-cloud-init-requiretty
+ mkdir -p /etc/chef/ohai/hints
+ touch /etc/chef/ohai/hints/ec2.json"
+ aws.tags = {
+ 'application_name' => 'asf-webapp-demo',
+ }
+ override.ssh.username = "ec2-user"
+ override.ssh.private_key_path = ENV["AWS_SSH_KEY"]
+ end
+
+ config.vm.provision :chef_solo do |chef|
+ chef.run_list = [
+ 'recipe[asf-webapp-demo::default]'
+ ]
+ end
+end
diff --git a/cookbooks/asf-webapp-demo/attributes/default.rb b/cookbooks/asf-webapp-demo/attributes/default.rb
new file mode 100644
index 000000000..d4faea283
--- /dev/null
+++ b/cookbooks/asf-webapp-demo/attributes/default.rb
@@ -0,0 +1,22 @@
+# Encoding: utf-8
+#
+# Cookbook Name:: asf-webapp-demo
+# Attributes:: default
+#
+# Copyright 2014, Copyright (c) 2014 Grid Dynamics International, Inc. All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+default['asf-webapp-demo']['url'] = nil
+default['asf-webapp-demo']['checksum'] = nil
diff --git a/cookbooks/asf-webapp-demo/chefignore b/cookbooks/asf-webapp-demo/chefignore
new file mode 100644
index 000000000..138a808b6
--- /dev/null
+++ b/cookbooks/asf-webapp-demo/chefignore
@@ -0,0 +1,94 @@
+# Put files/directories that should be ignored in this file when uploading
+# or sharing to the community site.
+# Lines that start with '# ' are comments.
+
+# OS generated files #
+######################
+.DS_Store
+Icon?
+nohup.out
+ehthumbs.db
+Thumbs.db
+
+# SASS #
+########
+.sass-cache
+
+# EDITORS #
+###########
+\#*
+.#*
+*~
+*.sw[a-z]
+*.bak
+REVISION
+TAGS*
+tmtags
+*_flymake.*
+*_flymake
+*.tmproj
+.project
+.settings
+mkmf.log
+
+## COMPILED ##
+##############
+a.out
+*.o
+*.pyc
+*.so
+*.com
+*.class
+*.dll
+*.exe
+*/rdoc/
+
+# Testing #
+###########
+.watchr
+.rspec
+spec/*
+spec/fixtures/*
+test/*
+features/*
+Guardfile
+Procfile
+
+# SCM #
+#######
+.git
+*/.git
+.gitignore
+.gitmodules
+.gitconfig
+.gitattributes
+.svn
+*/.bzr/*
+*/.hg/*
+*/.svn/*
+
+# Berkshelf #
+#############
+cookbooks/*
+tmp
+
+# Cookbooks #
+#############
+CONTRIBUTING
+CHANGELOG*
+
+# Strainer #
+############
+Colanderfile
+Strainerfile
+.colander
+.strainer
+
+# Vagrant #
+###########
+.vagrant
+Vagrantfile
+
+# Travis #
+##########
+.travis.yml
diff --git a/cookbooks/asf-webapp-demo/metadata.rb b/cookbooks/asf-webapp-demo/metadata.rb
new file mode 100644
index 000000000..1b2efa2bd
--- /dev/null
+++ b/cookbooks/asf-webapp-demo/metadata.rb
@@ -0,0 +1,10 @@
+# Encoding: utf-8
+name 'asf-webapp-demo'
+maintainer 'Copyright (c) 2014 Grid Dynamics International, Inc. All Rights Reserved'
+maintainer_email 'nyurin@griddynamics.com'
+license 'Apache 2.0'
+description 'Installs/Configures asf-webapp-demo'
+long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
+version '0.1.0'
+
+depends 'yum-epel'
\ No newline at end of file
diff --git a/cookbooks/asf-webapp-demo/recipes/default.rb b/cookbooks/asf-webapp-demo/recipes/default.rb
new file mode 100644
index 000000000..c328f6610
--- /dev/null
+++ b/cookbooks/asf-webapp-demo/recipes/default.rb
@@ -0,0 +1,58 @@
+# Encoding: utf-8
+#
+# Cookbook Name:: asf-webapp-demo
+# Recipe:: default
+#
+# Copyright 2014, Copyright (c) 2014 Grid Dynamics International, Inc. All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+include_recipe 'yum-epel'
+
+package 'tomcat' do
+ action :install
+end
+
+execute 'fix tomcat.conf' do
+ command 'sed \'s/JAVA_HOME=.*/JAVA_HOME=\/usr\/lib\/jvm\/java/\' /etc/tomcat/tomcat.conf'
+ user 'root'
+ action :run
+end
+
+service 'tomcat' do
+ supports :status => true, :restart => true, :reload => true
+ action [ :enable, :start ]
+end
+
+remote_file '/var/lib/tomcat/webapps/asf-webapp-demo.war' do
+ owner 'tomcat'
+ group 'tomcat'
+ mode 0644
+ source node['asf-webapp-demo']['url']
+ checksum node['asf-webapp-demo']['checksum']
+ notifies :restart, 'service[tomcat]'
+end
+
+ruby_block 'waiting for asf-webapp-demo' do
+ block do
+ require 'net/https'
+ require 'uri'
+ uri = URI('http://localhost:8080/asf-webapp-demo')
+ 10.times {
+ sleep(30)
+ break if Net::HTTP.get_response(uri) == '302'
+ }
+ end
+end
+
diff --git a/manifests/asf-webapp-demo.yaml b/manifests/asf-webapp-demo.yaml
new file mode 100644
index 000000000..ed89b0cf6
--- /dev/null
+++ b/manifests/asf-webapp-demo.yaml
@@ -0,0 +1,104 @@
+# Encoding: utf-8
+#
+# Application: ASF Webapp Demo
+# Component: Main
+#
+# Copyright 2014, Copyright (c) 2014 Grid Dynamics International, Inc. All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+application:
+ configuration:
+ input.artifact_url: "http://gd-asf.s3.amazonaws.com/petclinic.war"
+ input.artifact_checksum: "f1c52bc5b995618593855b8718ed0edbc42451a47a1154ba6236bbd2741372d0"
+ input.cookbooks_url: "http://gd-asf.s3.amazonaws.com/webapp_cookbooks.tar.gz"
+ interfaces:
+ input:
+ artifact_url: "bind(workflow#input.artifact_url)"
+ artifact_checksum: "bind(workflow#input.artifact_checksum)"
+ cookbooks_url: "bind(workflow#input.cookbooks_url)"
+ output:
+ webapp_endpoint: "bind(workflow#result.webapp_endpoint)"
+ webapp_host_ip: "bind(workflow#result.webapp_host_ip)"
+ components:
+ workflow:
+ type: workflow.Instance
+ interfaces:
+ input:
+ artifact_url:
+ type: configuration(string)
+ name: Artifact File URL
+ artifact_checksum:
+ type: configuration(string)
+ name: Artifact File Checksum
+ cookbooks_url:
+ type: configuration(string)
+ name: Cookbooks Tarball URL
+ result:
+ webapp_endpoint:
+ type: publish-signal(string)
+ name: Webapp Endpoint
+ webapp_host_ip:
+ type: publish-signal(string)
+ name: Instance IP
+ keypair-store:
+ get-keypair: "send-command(string id => object privateKey)"
+
+ configuration:
+ configuration.triggers: {}
+ configuration.workflows:
+ launch:
+ steps:
+ - start_vm:
+ action: provisionVms
+ parameters:
+ roleName: webapp
+ hardwareId: m1.small
+ quantity: 1
+ retryCount: 1
+ jcloudsProvider: aws-ec2
+ jcloudsEndpoint: https://ec2.us-east-1.amazonaws.com
+ jcloudsRegions: us-east-1
+ jcloudsNodeNamePrefix: asf-webapp-demo
+ vmIdentity: ec2-user
+ imageId: us-east-1/ami-d41689bd
+ ec2SecurityGroup: default
+ providerSettings:
+ userData: "#!/bin/bash\nmkdir -p /etc/chef/ohai/hints\ntouch /etc/chef/ohai/hints/ec2.json"
+ output:
+ webapp_host_ip: ips
+
+ - deploy_webapp:
+ action: chefsolo
+ precedingPhases: [ start_vm ]
+ parameters:
+ roles: [ webapp ]
+ recipeUrl: "{$.cookbooks_url}"
+ runList: [ "recipe[asf-webapp-demo]" ]
+ version: "11.8.2"
+ jattrs:
+ asf-webapp-demo:
+ url: "{$.artifact_url}"
+ checksum: "{$.artifact_checksum}"
+
+ return:
+ webapp_endpoint:
+ value: "http://{$.webapp_host_ip[0]}:8080/asf-webapp-demo"
+ webapp_host_ip:
+ value: "{$.webapp_host_ip[0]}"
+
+ destroy:
+ steps:
+ - destroy:
+ action: undeployEnv