# Copyright 2014-2016 Amazon.com, Inc. or its affiliates. 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. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # or in the "license" file accompanying this file. This file 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. require 'yaml' require_relative '../deployment_utils' require_relative 'deployment_activity' require_relative 'deployment_types' # DeploymentWorkflow class defines the workflows for the Deployment sample class DeploymentWorkflow extend AWS::Flow::Workflows # Use the workflow method to define workflow entry point. workflow :deploy do { version: DeploymentUtils::WF_VERSION, default_task_list: DeploymentUtils::WF_TASKLIST, default_execution_start_to_close_timeout: 120, } end # Create an activity client using the activity_client method to schedule # activities activity_client(:client) { { from_class: "DeploymentActivity" } } # This is the entry point for the workflow def deploy(configuration_file) puts "Workflow has started\n" unless is_replaying? puts "Loading deployment configuration\n" unless is_replaying? deployment_config = YAML.load_file configuration_file config = deployment_config["application_stack"]["components"] frontend_config = deployment_config["application_stack"]["frontend"] # Create all components # create databases puts "Building databases\n" unless is_replaying? databases = build_databases(config["database"]) # create app servers puts "Building app servers\n" unless is_replaying? app_servers = build_app_servers(config["app_server"], databases) # create web servers puts "Building web servers\n" unless is_replaying? web_servers = build_web_servers(config["web_server"], databases, app_servers) # create load balancers puts "Building load balancers\n" unless is_replaying? load_balancers = build_load_balancers(config["load_balancer"], web_servers) # Create the frontend components puts "Building frontend\n" unless is_replaying? frontend = build_frontend(frontend_config, load_balancers) components = [databases, app_servers, web_servers, load_balancers] # Create the application stack application_stack = ApplicationStack.new({ components: components.map!(&:values).flatten, frontend: frontend, activity_client: client }) # Deploy the stack application_stack.deploy end # Helper method used to create Database objects from a database config def build_databases databases databases.each_with_object( {} ) do |database, result| result[database["id"].to_sym] = Database.new(database["host"]) end end # Helper method used to create AppServer objects from an app server config def build_app_servers(app_servers, databases) app_servers.each_with_object( {} ) do |app_server, result| result[app_server["id"].to_sym] = AppServer.new( app_server["host"], extract_keys(app_server["database"], databases)) end end # Helper method used to create WebServer objects from web server config def build_web_servers(web_servers, databases, app_servers) web_servers.each_with_object do |web_server, result| result[web_server["id"].to_sym] = WebServer.new( web_server["host"], extract_keys(web_server["database"], databases), extract_keys(web_server["app_server"], app_servers)) end end # Helper method used to create LoadBalancer objects from a load balancer config def build_load_balancers(load_balancers, web_servers) load_balancers.each_with_object( {} ) do |load_balancer, result| result[load_balancer["id"].to_sym] = LoadBalancer.new( load_balancer["host"], extract_keys(load_balancer["web_server"], web_servers)) end end # Helper method used to create frontend from a load balancer config def build_frontend(frontends, load_balancers) extract_keys(frontends, load_balancers) end def extract_keys(components, hash) components.each_with_object( [] ) do |id, values| values << hash[id.to_sym] if hash.key? id.to_sym end end # Helper method to check if Flow is replaying the workflow. This is used to # avoid duplicate log messages def is_replaying? decision_context.workflow_clock.replaying end end # Start a WorkflowWorker to work on the DeploymentWorkflow tasks DeploymentUtils.new.workflow_worker.start if $0 == __FILE__