diff --git a/.gitignore b/.gitignore
index 1c49e77..7acdf1b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ __pycache__/
# Distribution / packaging
.Python
+.vscode
env/
build/
develop-eggs/
diff --git a/cumulus/__init__.py b/cumulus/__init__.py
index 6f50cf1..3648f27 100644
--- a/cumulus/__init__.py
+++ b/cumulus/__init__.py
@@ -1,7 +1,6 @@
-# -*- coding: utf-8 -*-
-
"""Top-level package for Cumulus."""
__author__ = """Brett Swift"""
__email__ = 'brettswift@gmail.com'
__version__ = '0.1.5'
+
diff --git a/cumulus/components/__init__.py b/cumulus/components/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/cumulus/components/userdata/__init__.py b/cumulus/components/userdata/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/cumulus/components/userdata/linux.py b/cumulus/components/userdata/linux.py
new file mode 100644
index 0000000..b5f99f0
--- /dev/null
+++ b/cumulus/components/userdata/linux.py
@@ -0,0 +1,38 @@
+from troposphere import (
+ Ref,
+ Join,
+)
+
+
+def user_data_for_cfn_init(launch_config_name, asg_name, configsets):
+ """
+ :return: A troposphere Join object that contains userdata for use with cfn-init
+
+ :param configsets: The single 'key' value set in the cfn-init Metadata parameter: cloudformation.InitConfigSets
+ :type asg_name: String name of the ASG cloudformation resource
+ :type launch_config_name: String name of the launch config cloudformation resource
+ """
+ default_userdata_asg_signal = (
+ Join('',
+ [
+ "#!/bin/bash -xe\n",
+ "yum update aws-cfn-bootstrap\n",
+ "# Install the files and packages from the metadata\n",
+ "/opt/aws/bin/cfn-init ",
+ " --stack ", Ref("AWS::StackName"),
+ " --resource ", launch_config_name,
+ " --configsets %s " % configsets,
+ " --region ", Ref("AWS::Region"), "\n",
+ # "# Get exit code of cfn init to use in cfn-signal\n",
+ # "export init_status=$?", "\n"
+ # Signal regardless of existence of an update policy.
+ # An error will pop up in the logs but I don't think this causes a problem.
+ "# Signal the ASG we are ready\n\n",
+ "/opt/aws/bin/cfn-signal -e 0",
+ # "/opt/aws/bin/cfn-signal -e $init_status",
+ " --resource %s" % asg_name,
+ " --stack ", Ref("AWS::StackName"),
+ " --region ", Ref("AWS::Region"),
+ "\n"
+ ]))
+ return default_userdata_asg_signal
diff --git a/cumulus/components/userdata/windows.py b/cumulus/components/userdata/windows.py
new file mode 100644
index 0000000..5e751d0
--- /dev/null
+++ b/cumulus/components/userdata/windows.py
@@ -0,0 +1,33 @@
+from troposphere import (
+ Ref,
+ Join,
+)
+
+
+def user_data_for_cfn_init(launch_config_name, asg_name, configsets):
+ """
+ :return: A troposphere Join object that contains userdata for use with cfn-init
+ :param configsets: The single 'key' value set in the cfn-init Metadata parameter: cloudformation.InitConfigSets
+ :type asg_name: String name of the ASG cloudformation resource
+ :type launch_config_name: String name of the launch config cloudformation resource
+ """
+ default_userdata_asg_signal = (
+ Join('',
+ [
+ "\n",
+ "& ", "$env:ProgramFiles\Amazon\cfn-bootstrap\cfn-init.exe",
+ " --stack ", Ref("AWS::StackName"),
+ " --resource ", launch_config_name,
+ " --configsets %s " % configsets,
+ " --region ", Ref("AWS::Region"), "\n",
+ "# Signal the ASG we are ready\n",
+ "&", "$env:ProgramFiles\Amazon\cfn-signal",
+ " -e ",
+ " $LastExitCode",
+ " --resource %s" % asg_name,
+ " --stack ", Ref("AWS::StackName"),
+ " --region ", Ref("AWS::Region"),
+ "\n",
+ ""
+ ]))
+ return default_userdata_asg_signal
diff --git a/cumulus/steps/dev_tools/pipeline.py b/cumulus/steps/dev_tools/pipeline.py
index d73b143..c54103f 100644
--- a/cumulus/steps/dev_tools/pipeline.py
+++ b/cumulus/steps/dev_tools/pipeline.py
@@ -184,10 +184,9 @@ def handle(self, chain_context):
pipeline_policy
]
)
-
generic_pipeline = codepipeline.Pipeline(
"Pipeline",
- # Name=chain_context.instance_name,
+ Name=chain_context.instance_name,
RoleArn=troposphere.GetAtt(pipeline_service_role, "Arn"),
Stages=[],
ArtifactStore=codepipeline.ArtifactStore(
diff --git a/cumulus/steps/ec2/__init__.py b/cumulus/steps/ec2/__init__.py
new file mode 100644
index 0000000..c57aab7
--- /dev/null
+++ b/cumulus/steps/ec2/__init__.py
@@ -0,0 +1,3 @@
+
+META_SECURITY_GROUP_NAME = 'security_group_name'
+META_TARGET_GROUP_NAME = 'target_group_name'
diff --git a/cumulus/steps/ec2/alb.py b/cumulus/steps/ec2/alb.py
new file mode 100644
index 0000000..7a0f47b
--- /dev/null
+++ b/cumulus/steps/ec2/alb.py
@@ -0,0 +1,135 @@
+from cumulus.chain import step
+from troposphere import (
+ Ref, Not, Equals, Join, ec2,
+ If, Output
+)
+from troposphere import elasticloadbalancingv2 as alb
+
+CLUSTER_SG_NAME = "%sSG"
+ALB_SG_NAME = "%sAlbSG"
+ALB_NAME = "%sLoadBalancer"
+TARGET_GROUP_DEFAULT = "DefaultTargetGroup%s"
+
+
+class Alb(step.Step):
+
+ def __init__(self,
+ name
+ ):
+ step.Step.__init__(self)
+
+ self.name = name
+
+ def handle(self, chain_context):
+ self.create_conditions(chain_context.template)
+ self.create_security_groups(chain_context.template)
+ self.create_default_target_group(chain_context.template)
+ self.create_load_balancer_alb(chain_context.template)
+ self.add_listener(chain_context.template)
+
+ def create_conditions(self, template):
+ template.add_condition(
+ "UseSSL",
+ Not(Equals(Ref("ALBCertName"), "")))
+ template.add_condition(
+ "UseIAMCert",
+ Not(Equals(Ref("ALBCertType"), "acm")))
+
+ def create_security_groups(self, template):
+ asg_sg = CLUSTER_SG_NAME % self.name
+ alb_sg = ALB_SG_NAME % self.name
+
+ # TODO: this SG shouldn't be required.. test.
+ template.add_resource(ec2.SecurityGroup(
+ asg_sg,
+ GroupDescription=asg_sg,
+ VpcId=Ref("VpcId")))
+
+ # ALB Security group
+ template.add_resource(
+ ec2.SecurityGroup(
+ alb_sg,
+ GroupDescription=alb_sg,
+ VpcId=Ref("VpcId")
+ ))
+
+ template.add_output(
+ Output("InternalAlbSG", Value=Ref(alb_sg))
+ )
+
+ # TODO: take a list of Cidr's
+ # Allow Internet to connect to ALB
+ template.add_resource(ec2.SecurityGroupIngress(
+ "LocalNetworkTo%sAlbPort443" % self.name,
+ IpProtocol="tcp", FromPort="443", ToPort="443",
+ CidrIp="10.0.0.0/0",
+ GroupId=Ref(alb_sg),
+ ))
+
+ def create_load_balancer_alb(self, template):
+ alb_name = ALB_NAME % self.name
+ alb_sg = ALB_SG_NAME % self.name
+
+ load_balancer = template.add_resource(alb.LoadBalancer(
+ alb_name,
+ # Name=alb_name,
+ Scheme="internal",
+ Subnets=Ref("PrivateSubnets"),
+ SecurityGroups=[Ref(alb_sg)]
+ ))
+
+ template.add_output(
+ Output(
+ "CanonicalHostedZoneID",
+ Value=load_balancer.GetAtt("CanonicalHostedZoneID")
+ )
+ )
+ template.add_output(
+ Output("DNSName", Value=load_balancer.GetAtt("DNSName"))
+ )
+
+ def add_listener(self, template):
+ # Choose proper certificate source ?-> always acm?
+ acm_cert = Join("", [
+ "arn:aws:acm:",
+ Ref("AWS::Region"),
+ ":",
+ Ref("AWS::AccountId"),
+ ":certificate/", Ref("ALBCertName")])
+ # We probably don't need this code for an IAM Cert
+ iam_cert = Join("", [
+ "arn:aws:iam::",
+ Ref("AWS::AccountId"),
+ ":server-certificate/",
+ Ref("ALBCertName")])
+ cert_id = If("UseIAMCert", iam_cert, acm_cert)
+ alb_name = ALB_NAME % self.name
+
+ with_ssl = alb.Listener(
+ "Listener",
+ Port="443",
+ Protocol="HTTPS",
+ LoadBalancerArn=Ref(alb_name),
+ DefaultActions=[alb.Action(
+ Type="forward",
+ TargetGroupArn=Ref(TARGET_GROUP_DEFAULT % self.name)
+ )],
+ Certificates=[alb.Certificate(
+ CertificateArn=cert_id
+ )]
+ )
+
+ template.add_resource(with_ssl)
+
+ template.add_output(
+ Output("IAlbListener", Value=with_ssl.Ref())
+ )
+
+ def create_default_target_group(self, template):
+ template.add_resource(alb.TargetGroup(
+ TARGET_GROUP_DEFAULT % self.name,
+ # Name=TARGET_GROUP_DEFAULT % self.name,
+ Port='80',
+ Protocol="HTTP",
+ VpcId=Ref("VpcId"),
+ ))
diff --git a/cumulus/steps/ec2/alb_port.py b/cumulus/steps/ec2/alb_port.py
new file mode 100644
index 0000000..1dd89fb
--- /dev/null
+++ b/cumulus/steps/ec2/alb_port.py
@@ -0,0 +1,33 @@
+from troposphere import (
+ Ref, ec2, Join)
+from cumulus.chain import step
+from cumulus.steps.ec2 import META_SECURITY_GROUP_NAME
+
+
+class AlbPort(step.Step):
+
+ def __init__(self,
+ port_to_open,
+ alb_sg_name):
+
+ step.Step.__init__(self)
+
+ self.port_to_open = port_to_open
+ self.alb_sg_name = alb_sg_name
+
+ def handle(self, chain_context):
+ template = chain_context.template
+
+ # name = Join('', ['ElbToASGPort"', Ref("stackname"), self.port_to_open])
+
+ name = 'ElbToASGPort'
+
+ template.add_resource(ec2.SecurityGroupIngress(
+ name,
+ IpProtocol="tcp",
+ FromPort=self.port_to_open,
+ ToPort=self.port_to_open,
+ SourceSecurityGroupId=Ref(self.alb_sg_name),
+ GroupId=Ref(chain_context.metadata[META_SECURITY_GROUP_NAME])
+ ))
+
diff --git a/cumulus/steps/ec2/block_device_data.py b/cumulus/steps/ec2/block_device_data.py
new file mode 100644
index 0000000..876664e
--- /dev/null
+++ b/cumulus/steps/ec2/block_device_data.py
@@ -0,0 +1,17 @@
+from cumulus.chain import step
+from cumulus.util.tropo import TemplateQuery
+from troposphere import autoscaling
+
+
+
+class BlockDeviceData(step.Step):
+
+ def __init__(self,
+ volume):
+ step.Step.__init__(self)
+ self.volume = volume
+
+ def handle(self, chain_context):
+ launchConfig = TemplateQuery.get_resource_by_type(template=chain_context.template,
+ type_to_find=autoscaling.LaunchConfiguration)[0]
+ launchConfig.properties['BlockDeviceMappings'] = [self.volume]
diff --git a/cumulus/steps/ec2/dns.py b/cumulus/steps/ec2/dns.py
new file mode 100644
index 0000000..bd61537
--- /dev/null
+++ b/cumulus/steps/ec2/dns.py
@@ -0,0 +1,53 @@
+from troposphere import route53
+from troposphere import (
+ Ref, Join, ec2)
+from cumulus.chain import step
+
+
+class Dns(step.Step):
+
+ def __init__(self,
+ base_domain,
+ hosted_zone_id,
+ dns_name,
+ ):
+
+ step.Step.__init__(self)
+
+ self.base_domain = base_domain
+ self.hosted_zone_id = hosted_zone_id
+ self.dns_name = dns_name
+
+ def handle(self, chain_context):
+ template = chain_context.template
+
+ # ALB_RECORDSET_NAME = "AlbAlias"
+ # name = Join('', [ALB_RECORDSET_NAME, Ref("stackname")]),
+
+ name = 'AlbAlias'
+
+ template.add_resource(route53.RecordSetGroup(
+ "Route53Records",
+ RecordSets=[
+ route53.RecordSet(
+ name,
+ Weight=1,
+ SetIdentifier="original",
+ AliasTarget=route53.AliasTarget(
+ HostedZoneId=self.hosted_zone_id,
+ DNSName=self.dns_name,
+ EvaluateTargetHealth=False,
+ ),
+ Name=Join("", [
+ Ref("stackname"),
+ "-",
+ Ref("namespace"),
+ ".",
+ self.base_domain,
+ "."
+ ]),
+ Type="A",
+ )
+ ],
+ HostedZoneName=Join("", [self.base_domain, "."])
+ ))
diff --git a/cumulus/steps/ec2/ingress_rule.py b/cumulus/steps/ec2/ingress_rule.py
new file mode 100644
index 0000000..45773dc
--- /dev/null
+++ b/cumulus/steps/ec2/ingress_rule.py
@@ -0,0 +1,33 @@
+from troposphere import elasticloadbalancingv2 as alb
+from troposphere import (
+ Ref, ec2)
+import re
+from cumulus.chain import step
+from cumulus.steps.ec2 import META_SECURITY_GROUP_NAME
+
+
+class IngressRule(step.Step):
+
+ def __init__(self,
+ port_to_open,
+ cidr):
+
+ step.Step.__init__(self)
+
+ self.port_to_open = port_to_open
+ self.cidr = cidr
+
+ def handle(self, chain_context):
+ template = chain_context.template
+
+ clean_cidr = re.compile('[\W_]+').sub('', self.cidr)
+
+ template.add_resource(ec2.SecurityGroupIngress(
+ "Cidr%sToASGPort%s" % (clean_cidr, self.port_to_open),
+ IpProtocol="tcp",
+ FromPort=self.port_to_open,
+ ToPort=self.port_to_open,
+ CidrIp=self.cidr,
+ GroupId=Ref(chain_context.metadata[META_SECURITY_GROUP_NAME])
+ ))
+
diff --git a/cumulus/steps/ec2/launch_config.py b/cumulus/steps/ec2/launch_config.py
new file mode 100644
index 0000000..391a037
--- /dev/null
+++ b/cumulus/steps/ec2/launch_config.py
@@ -0,0 +1,81 @@
+from troposphere import autoscaling, Ref, FindInMap, Base64, ec2
+from cumulus.chain import step
+import cumulus.components.userdata.linux
+from cumulus.steps.ec2 import META_SECURITY_GROUP_NAME
+
+
+class LaunchConfig(step.Step):
+
+ def __init__(self,
+ asg_name,
+ launch_config_name,
+ meta_data,
+ instance_profile_name,
+ vpc_id=None,
+ user_data=None, ):
+
+ step.Step.__init__(self)
+
+ self.asg_name = asg_name
+ self.launch_config_name = launch_config_name
+ self.user_data = user_data
+ self.meta_data = meta_data
+ self.instance_profile_name = instance_profile_name
+ self.vpc_id = vpc_id
+
+ def handle(self, chain_context):
+
+ template = chain_context.template
+
+ template.add_resource(ec2.SecurityGroup(
+ "ScalingGroupSecurityGroup",
+ GroupDescription="ScalingGroupSecurityGroup description",
+ **self._get_security_group_parameters()))
+
+ chain_context.metadata[META_SECURITY_GROUP_NAME] = "ScalingGroupSecurityGroup"
+
+ if not self.user_data:
+ user_data = cumulus.components.userdata.linux.user_data_for_cfn_init(
+ launch_config_name=self.launch_config_name,
+ asg_name=self.asg_name,
+ configsets='default', # TODO: Fix this
+ )
+
+ launch_config = autoscaling.LaunchConfiguration(
+ self.launch_config_name,
+ UserData=Base64(user_data),
+ Metadata=self.meta_data,
+ IamInstanceProfile=Ref(self.instance_profile_name),
+ # search the template to find this instead of using name
+ **self._get_launch_configuration_parameters(chain_context)
+ )
+
+ template.add_resource(launch_config)
+
+ def _get_security_group_parameters(self):
+ config = {
+ }
+
+ if self.vpc_id:
+ config['VpcId'] = self.vpc_id
+
+ return config
+
+ def _get_launch_configuration_parameters(self, chain_context):
+
+ asg_sg_list = [self._get_launch_configuration_security_groups(chain_context.metadata[META_SECURITY_GROUP_NAME])]
+
+ parameters = {
+ 'ImageId': FindInMap('AmiMap',
+ Ref("AWS::Region"),
+ Ref('ImageName')),
+ 'InstanceType': Ref("InstanceType"),
+ 'KeyName': Ref("SshKeyName"),
+ 'SecurityGroups': asg_sg_list,
+ }
+
+ return parameters
+
+ @staticmethod
+ def _get_launch_configuration_security_groups(asg_sg_name):
+ return Ref(asg_sg_name)
diff --git a/cumulus/steps/ec2/listener_rule.py b/cumulus/steps/ec2/listener_rule.py
new file mode 100644
index 0000000..33d58ec
--- /dev/null
+++ b/cumulus/steps/ec2/listener_rule.py
@@ -0,0 +1,67 @@
+from troposphere import elasticloadbalancingv2 as alb, route53
+from troposphere import (
+ Ref, Join, ec2)
+from cumulus.chain import step
+from cumulus.steps.ec2 import META_TARGET_GROUP_NAME
+
+
+class ListenerRule(step.Step):
+
+ def __init__(self,
+ base_domain_name,
+ alb_listener_rule,
+ priority,
+ path_pattern=None,
+ host_pattern=None,
+ ):
+
+ step.Step.__init__(self)
+
+ self.path_pattern = path_pattern
+ self.host_pattern = host_pattern
+ self.priority = priority
+ self.base_domain_name = base_domain_name
+ self.alb_listener_rule = alb_listener_rule
+
+ def handle(self, chain_context):
+ ALB_LISTENER_RULE = "ListenerRule"
+
+ template = chain_context.template
+
+ if not (self.path_pattern or self.host_pattern):
+ raise RuntimeError("with_listener_rule() requires one of: path_pattern, host_pattern")
+
+ routing_condition = None
+ if self.path_pattern:
+ routing_condition = alb.Condition(
+ Field="path-pattern",
+ Values=[self.path_pattern],
+ )
+ elif self.host_pattern:
+ routing_condition = alb.Condition(
+ Field="host-header",
+ Values=[
+ Ref("stackname"),
+ "-",
+ Ref("namespace"),
+ ".",
+ self.base_domain_name
+ ]
+ )
+
+ # name = Join('', [Ref("stackname"), ALB_LISTENER_RULE])
+
+ name = "AlbListenerRule"
+
+ listener_rule = alb.ListenerRule(
+ name,
+ ListenerArn=self.alb_listener_rule,
+ Conditions=[routing_condition],
+ Actions=[alb.Action(
+ Type="forward",
+ TargetGroupArn=Ref(chain_context.metadata[META_TARGET_GROUP_NAME])
+ )],
+ Priority=self.priority,
+ )
+
+ template.add_resource(listener_rule)
diff --git a/cumulus/steps/ec2/port.py b/cumulus/steps/ec2/port.py
new file mode 100644
index 0000000..0e5ac9c
--- /dev/null
+++ b/cumulus/steps/ec2/port.py
@@ -0,0 +1,31 @@
+from troposphere import elasticloadbalancingv2 as alb
+from troposphere import (
+ Ref, Join, ec2)
+from cumulus.chain import step
+
+
+class Port(step.Step):
+
+ def __init__(self,
+ name,
+ port_to_open,
+ alb_sg_name,
+ asg_sg_name):
+
+ step.Step.__init__(self)
+
+ self.name = name
+ self.port_to_open = port_to_open
+ self.alb_sg_name = alb_sg_name
+ self.asg_sg_name = asg_sg_name
+
+ def handle(self, chain_context):
+ template = chain_context.template
+
+ template.add_resource(ec2.SecurityGroupIngress(
+ "%sElbToASGPort%s" % (self.name, self.port_to_open),
+ IpProtocol="tcp", FromPort=self.port_to_open, ToPort=self.port_to_open,
+ SourceSecurityGroupId=Ref(self.alb_sg_name),
+ GroupId=Ref(self.asg_sg_name)
+ ))
+
diff --git a/cumulus/steps/ec2/role.py b/cumulus/steps/ec2/role.py
new file mode 100644
index 0000000..db0fb64
--- /dev/null
+++ b/cumulus/steps/ec2/role.py
@@ -0,0 +1,32 @@
+from troposphere import Ref
+
+from cumulus.chain import step
+from troposphere.iam import InstanceProfile
+
+from cumulus.util.tropo import TemplateQuery
+
+
+class Role(step.Step):
+
+ def __init__(self,
+ instance_profile_name,
+ role):
+ step.Step.__init__(self)
+ self.instance_profile_name = instance_profile_name
+ self.role = role
+
+ def handle(self, chain_context):
+ template = chain_context.template
+
+ template.add_resource(self.role)
+
+ try:
+ instanceProfile = TemplateQuery.get_resource_by_title(template, self.instance_profile_name)
+ instanceProfile.properties['Roles'].append(Ref(self.role))
+ except ValueError:
+ print('Adding new Instance Profile')
+ template.add_resource(InstanceProfile(
+ self.instance_profile_name,
+ Roles=[Ref(self.role)]
+ ))
+
diff --git a/cumulus/steps/ec2/scaling_group.py b/cumulus/steps/ec2/scaling_group.py
new file mode 100644
index 0000000..e32d14b
--- /dev/null
+++ b/cumulus/steps/ec2/scaling_group.py
@@ -0,0 +1,66 @@
+from troposphere import Ref, autoscaling, FindInMap, Base64, ec2
+from troposphere.autoscaling import Tag as ASTag
+from troposphere.policies import UpdatePolicy, AutoScalingReplacingUpdate, AutoScalingRollingUpdate
+from cumulus.chain import step
+from cumulus.steps.ec2 import META_SECURITY_GROUP_NAME, META_TARGET_GROUP_NAME
+
+
+class LaunchType:
+ """ enum used by launch configuration or anything OS specific"""
+ LINUX, WINDOWS = range(2)
+
+
+class ScalingGroup(step.Step):
+
+ def __init__(self,
+ asg_name,
+ launch_config_name,
+ use_update_policy=True
+ ):
+ """
+ :type launch_type: LaunchType: the type of the ec2 that will be created
+ """
+ step.Step.__init__(self)
+
+ # Set default resource names for those not injected
+ self.asg_name = asg_name
+ self.launch_config_name = launch_config_name
+ self.use_update_policy = use_update_policy
+
+ def handle(self, chain_context):
+
+ template = chain_context.template
+
+ template.add_resource(autoscaling.AutoScalingGroup(
+ self.asg_name,
+ **self._get_autoscaling_group_parameters(chain_context=chain_context,
+ launch_config_name=self.launch_config_name)))
+
+ def _get_autoscaling_group_parameters(self, chain_context, launch_config_name):
+ config = {
+ 'AvailabilityZones': Ref("AvailabilityZones"), # Not really required in this case (yet)
+ 'LaunchConfigurationName': Ref(launch_config_name),
+ 'MinSize': Ref("MinSize"),
+ 'MaxSize': Ref("MaxSize"),
+ 'VPCZoneIdentifier': Ref("PrivateSubnets"),
+ 'Tags': [ASTag('Name', chain_context.instance_name, True)],
+ }
+
+ if chain_context.metadata[META_TARGET_GROUP_NAME]:
+ config['TargetGroupARNs'] = [Ref(chain_context.metadata[META_TARGET_GROUP_NAME])]
+
+ if self.use_update_policy:
+ update_policy = UpdatePolicy(
+ AutoScalingReplacingUpdate=AutoScalingReplacingUpdate(
+ WillReplace=True,
+ ),
+ AutoScalingRollingUpdate=AutoScalingRollingUpdate(
+ PauseTime='PT5M',
+ MinInstancesInService="1",
+ MaxBatchSize='1',
+ WaitOnResourceSignals=True
+ )
+ )
+ config['UpdatePolicy'] = update_policy
+
+ return config
diff --git a/cumulus/steps/ec2/target_group.py b/cumulus/steps/ec2/target_group.py
new file mode 100644
index 0000000..f66089c
--- /dev/null
+++ b/cumulus/steps/ec2/target_group.py
@@ -0,0 +1,45 @@
+from troposphere import elasticloadbalancingv2 as alb, route53
+from troposphere import (
+ Ref, Join, ec2)
+from cumulus.chain import step
+from cumulus.steps.ec2 import META_TARGET_GROUP_NAME
+
+
+class TargetGroup(step.Step):
+
+ def __init__(self,
+ port,
+ vpc_id
+ ):
+
+ step.Step.__init__(self)
+
+ self.port = port
+ self.vpc_id = vpc_id
+
+ def handle(self, chain_context):
+
+ # todo: why is this not allowing a reference?
+
+ name = 'CumulusTargetGroup'
+
+ # name = Join('', [Ref('stackname'), 'TargetGroup'])
+ # print(name)
+
+ chain_context.metadata[META_TARGET_GROUP_NAME] = name
+ template = chain_context.template
+
+ template.add_resource(alb.TargetGroup(
+ name,
+ HealthCheckPath="/",
+ HealthCheckIntervalSeconds="30",
+ HealthCheckProtocol="HTTP",
+ HealthCheckTimeoutSeconds="10",
+ HealthyThresholdCount="4",
+ Matcher=alb.Matcher(HttpCode="200"),
+ Port=self.port,
+ Protocol="HTTP",
+ UnhealthyThresholdCount="3",
+ VpcId=self.vpc_id
+ ))
+
diff --git a/cumulus/types.py b/cumulus/types.py
new file mode 100644
index 0000000..0983357
--- /dev/null
+++ b/cumulus/types.py
@@ -0,0 +1,3 @@
+class LaunchType:
+ """ enum used by launch configuration or anything OS specific"""
+ LINUX, WINDOWS = range(2)
diff --git a/tests/stacker_test/blueprints/alb.py b/tests/stacker_test/blueprints/alb.py
new file mode 100644
index 0000000..0462d78
--- /dev/null
+++ b/tests/stacker_test/blueprints/alb.py
@@ -0,0 +1,68 @@
+from awacs.aws import Allow, Principal, Policy, Statement
+from awacs.sts import AssumeRole
+from stacker.blueprints.base import Blueprint
+from stacker.blueprints.variables.types import EC2VPCId, EC2SubnetIdList, CFNCommaDelimitedList, CFNString, CFNNumber, \
+ EC2KeyPairKeyName
+from troposphere import cloudformation, ec2, iam
+from troposphere.iam import Role
+from cumulus.chain import chain, chaincontext
+from cumulus.steps.ec2 import scaling_group, launch_config, block_device_data, ingress_rule, target_group, dns, alb
+from cumulus.steps.ec2.role import Role
+
+
+class Alb(Blueprint):
+ VARIABLES = {
+ 'VpcId': {'type': EC2VPCId, 'description': 'Vpc Id'},
+ 'PrivateSubnets': {
+ 'type': EC2SubnetIdList,
+ 'description': 'Subnets to deploy private '
+ 'instances in.'},
+ 'AvailabilityZones': {'type': CFNCommaDelimitedList,
+ 'description': 'Availability Zones to deploy '
+ 'instances in.'},
+ 'InstanceType': {'type': CFNString,
+ 'description': 'EC2 Instance Type',
+ 'default': 't2.micro'},
+ 'MinSize': {'type': CFNNumber,
+ 'description': 'Minimum # of instances.',
+ 'default': '1'},
+ 'MaxSize': {'type': CFNNumber,
+ 'description': 'Maximum # of instances.',
+ 'default': '5'},
+ 'ALBHostName': {
+ 'type': CFNString,
+ 'description': 'A hostname to give to the ALB. If not given '
+ 'no ALB will be created.',
+ 'default': ''},
+ 'ALBCertName': {
+ 'type': CFNString,
+ 'description': 'The SSL certificate name to use on the ALB.',
+ 'default': ''},
+ 'ALBCertType': {
+ 'type': CFNString,
+ 'description': 'The SSL certificate type to use on the ALB.',
+ 'default': 'acm'},
+ }
+
+ def create_template(self):
+
+ instance_profile_name = "InstanceProfile" + self.name
+
+ t = self.template
+ t.add_description("Acceptance Tests for cumulus scaling groups")
+
+ # TODO fix
+ # instance = self.name + self.context.environment['env']
+ # TODO: give to builder
+ the_chain = chain.Chain()
+
+ the_chain.add(alb.Alb(
+ name="cumulusalb",
+ ))
+
+ chain_context = chaincontext.ChainContext(
+ template=t,
+ instance_name=instance_profile_name
+ )
+
+ the_chain.run(chain_context)
diff --git a/tests/stacker_test/blueprints/scaling_group_simple.py b/tests/stacker_test/blueprints/scaling_group_simple.py
new file mode 100644
index 0000000..8785533
--- /dev/null
+++ b/tests/stacker_test/blueprints/scaling_group_simple.py
@@ -0,0 +1,121 @@
+from awacs.aws import Allow, Principal, Policy, Statement
+from awacs.sts import AssumeRole
+from stacker.blueprints.base import Blueprint
+from stacker.blueprints.variables.types import EC2VPCId, EC2SubnetIdList, CFNCommaDelimitedList, CFNString, CFNNumber, \
+ EC2KeyPairKeyName
+from troposphere import cloudformation, ec2, iam
+from troposphere.iam import Role
+from cumulus.chain import chain, chaincontext
+from cumulus.steps.ec2 import scaling_group, launch_config, security_group, block_device_data, ingress_rule
+from cumulus.steps.ec2.role import Role
+
+
+class ScalingGroupSimple(Blueprint):
+ VARIABLES = {
+ 'VpcId': {'type': EC2VPCId,
+ 'description': 'Vpc Id'},
+ 'PrivateSubnets': {'type': EC2SubnetIdList,
+ 'description': 'Subnets to deploy private '
+ 'instances in.'},
+ 'AvailabilityZones': {'type': CFNCommaDelimitedList,
+ 'description': 'Availability Zones to deploy '
+ 'instances in.'},
+ 'InstanceType': {'type': CFNString,
+ 'description': 'EC2 Instance Type',
+ 'default': 't2.micro'},
+ 'MinSize': {'type': CFNNumber,
+ 'description': 'Minimum # of instances.',
+ 'default': '1'},
+ 'MaxSize': {'type': CFNNumber,
+ 'description': 'Maximum # of instances.',
+ 'default': '5'},
+ 'SshKeyName': {'type': EC2KeyPairKeyName},
+ 'ImageName': {
+ 'type': CFNString,
+ 'description': 'The image name to use from the AMIMap (usually '
+ 'found in the config file.)'},
+ }
+
+ def get_metadata(self):
+ metadata = cloudformation.Metadata(
+ cloudformation.Init(
+ cloudformation.InitConfigSets(
+ default=['install_and_run']
+ ),
+ install_and_run=cloudformation.InitConfig(
+ commands={
+ '01-startup': {
+ 'command': 'echo hello world'
+ },
+ }
+ )
+ )
+ )
+ return metadata
+
+ def create_template(self):
+ t = self.template
+ t.add_description("Acceptance Tests for cumulus scaling groups")
+
+ # TODO fix
+ # instance = self.name + self.context.environment['env']
+ instance = "sauterinstance"
+ # TODO: give to builder
+ the_chain = chain.Chain()
+
+ the_chain.add(security_group.SecurityGroup(asg_sg_name="sg1" + self.name,
+ vpc_id="vpc-894b89ef", ))
+
+ the_chain.add(security_group.SecurityGroup(asg_sg_name="sg2" + self.name,
+ vpc_id="vpc-894b89ef", ))
+
+ the_chain.add(ingress_rule.IngressRule(
+ name="SgCidrAccess",
+ port_to_open="22",
+ asg_sg_name="sg1" + self.name,
+ cidr="10.0.0.0/8"
+ ))
+
+ instance_profile_name= "InstanceProfile" + self.name
+
+ the_chain.add(Role(
+ instance_profile_name=instance_profile_name,
+ role=iam.Role(
+ "SomeRoleName1",
+ AssumeRolePolicyDocument=Policy(
+ Statement=[
+ Statement(
+ Effect=Allow,
+ Action=[AssumeRole],
+ Principal=Principal("Service", ["ec2.amazonaws.com", "s3.amazonaws.com"])
+ )
+ ]
+ ),
+ )))
+
+ launchConfigName = 'lc' + self.name
+
+ the_chain.add(launch_config.LaunchConfig(asg_name=self.name,
+ launch_config_name=launchConfigName,
+ meta_data=self.get_metadata(),
+ instance_profile_name=instance_profile_name), )
+
+ the_chain.add(block_device_data.BlockDeviceData(ec2.BlockDeviceMapping(
+ DeviceName="/dev/xvda",
+ Ebs=ec2.EBSBlockDevice(
+ VolumeSize="40"
+ ))))
+
+ the_chain.add(scaling_group.ScalingGroup(
+ name="donkey",
+ asg_name='asg' + self.name,
+ launch_config_name=launchConfigName,
+ use_update_policy=True
+ ))
+
+ chain_context = chaincontext.ChainContext(
+ template=t,
+ instance_name=instance
+ )
+
+ the_chain.run(chain_context)
diff --git a/tests/stacker_test/blueprints/website_simple.py b/tests/stacker_test/blueprints/website_simple.py
new file mode 100644
index 0000000..c3aa178
--- /dev/null
+++ b/tests/stacker_test/blueprints/website_simple.py
@@ -0,0 +1,170 @@
+from awacs.aws import Allow, Principal, Policy, Statement
+from awacs.sts import AssumeRole
+from stacker.blueprints.base import Blueprint
+from stacker.blueprints.variables.types import EC2VPCId, EC2SubnetIdList, CFNCommaDelimitedList, CFNString, CFNNumber, \
+ EC2KeyPairKeyName
+from troposphere import cloudformation, ec2, iam, Ref
+from troposphere.iam import Role
+from cumulus.chain import chain, chaincontext
+from cumulus.steps.ec2 import scaling_group, launch_config, block_device_data, ingress_rule, target_group, dns, \
+ alb_port, listener_rule
+from cumulus.steps.ec2.role import Role
+
+
+class WebsiteSimple(Blueprint):
+ VARIABLES = {
+ 'namespace': {
+ 'type': CFNString,
+ },
+ 'stackname': {
+ 'type': CFNString,
+ 'description': 'Name of the stack',
+ },
+ 'IAlbListener': {
+ 'type': CFNString,
+ 'description': 'From the ALB',
+ },
+ 'AlbCanonicalHostedZoneID': {
+ 'type': CFNString,
+ 'description': 'From the ALB',
+ 'default': 'acm',
+ },
+ 'AlbDNSName': {
+ 'type': CFNString,
+ 'description': 'From the ALB',
+ 'default': 'acm',
+ },
+
+ 'AlbSg': {
+ 'type': CFNString,
+ 'description': 'From the ALB',
+ },
+ 'InstanceType': {'type': CFNString,
+ 'description': 'EC2 Instance Type',
+ 'default': 't2.micro'},
+ 'SshKeyName': {'type': EC2KeyPairKeyName},
+ 'ImageName': {
+ 'type': CFNString,
+ 'description': 'The image name to use from the AMIMap (usually '
+ 'found in the config file.)'},
+ 'BaseDomain': {
+ 'type': CFNString},
+ 'MinSize': {'type': CFNNumber,
+ 'description': 'Minimum # of instances.',
+ 'default': '1'},
+ 'MaxSize': {'type': CFNNumber,
+ 'description': 'Maximum # of instances.',
+ 'default': '5'},
+ 'PrivateSubnets': {'type': EC2SubnetIdList,
+ 'description': 'Subnets to deploy private '
+ 'instances in.'},
+ 'AvailabilityZones': {'type': CFNCommaDelimitedList,
+ 'description': 'Availability Zones to deploy '
+ 'instances in.'},
+ 'VpcId': {'type': CFNString,
+ 'description': 'Vpc Id'},
+ }
+
+ def get_metadata(self):
+ metadata = cloudformation.Metadata(
+ cloudformation.Init(
+ cloudformation.InitConfigSets(
+ default=['install_and_run']
+ ),
+ install_and_run=cloudformation.InitConfig(
+ commands={
+ '01-startup': {
+ 'command': 'nohup python -m SimpleHTTPServer 8000 &'
+ },
+ }
+ )
+ )
+ )
+ return metadata
+
+ def create_template(self):
+ t = self.template
+ t.add_description("Acceptance Tests for cumulus scaling groups")
+
+ # TODO fix
+ # instance = self.name + self.context.environment['env']
+ # TODO: give to builder
+ the_chain = chain.Chain()
+
+ application_port = "8000"
+
+ instance_profile_name = "InstanceProfile" + self.name
+
+ the_chain.add(Role(
+ instance_profile_name=instance_profile_name,
+ role=iam.Role(
+ "SomeRoleName1",
+ AssumeRolePolicyDocument=Policy(
+ Statement=[
+ Statement(
+ Effect=Allow,
+ Action=[AssumeRole],
+ Principal=Principal("Service", ["ec2.amazonaws.com", "s3.amazonaws.com"])
+ )
+ ]
+ ),
+ )))
+
+ launchConfigName = 'lc' + self.name
+
+ the_chain.add(launch_config.LaunchConfig(asg_name=self.name,
+ launch_config_name=launchConfigName,
+ meta_data=self.get_metadata(),
+ instance_profile_name=instance_profile_name,
+ vpc_id=Ref("VpcId")))
+
+ the_chain.add(block_device_data.BlockDeviceData(ec2.BlockDeviceMapping(
+ DeviceName="/dev/xvda",
+ Ebs=ec2.EBSBlockDevice(
+ VolumeSize="40"
+ ))))
+
+ the_chain.add(target_group.TargetGroup(
+ port=application_port,
+ vpc_id=Ref("VpcId")
+ ))
+
+ the_chain.add(scaling_group.ScalingGroup(
+ asg_name='asg' + self.name,
+ launch_config_name=launchConfigName,
+ ))
+
+ the_chain.add(ingress_rule.IngressRule(
+ port_to_open="22",
+ cidr="10.0.0.0/8"
+ ))
+
+ the_chain.add(ingress_rule.IngressRule(
+ port_to_open=application_port,
+ cidr="10.0.0.0/8"
+ ))
+
+ the_chain.add(dns.Dns(
+ base_domain=Ref("BaseDomain"),
+ hosted_zone_id=Ref("AlbCanonicalHostedZoneID"),
+ dns_name=Ref("AlbDNSName"),
+ ))
+
+ the_chain.add(alb_port.AlbPort(
+ port_to_open=application_port,
+ alb_sg_name="AlbSg",
+ ))
+
+ the_chain.add(listener_rule.ListenerRule(
+ base_domain_name=Ref("BaseDomain"),
+ alb_listener_rule=Ref("IAlbListener"),
+ path_pattern="/*",
+ priority="2"
+ ))
+
+ chain_context = chaincontext.ChainContext(
+ template=t,
+ instance_name=instance_profile_name
+ )
+
+ the_chain.run(chain_context)
diff --git a/tests/stacker_test/conf/asgtest.env b/tests/stacker_test/conf/asgtest.env
new file mode 100644
index 0000000..a94a724
--- /dev/null
+++ b/tests/stacker_test/conf/asgtest.env
@@ -0,0 +1,9 @@
+BaseDomain: playpen.dsl.aws.shaw.ca
+stackname: cumulus
+VpcId: vpc-894b89ef
+BaseDomain: playpen.dsl.aws.shaw.ca
+PrivateSubnets: subnet-7b8cba32,subnet-ed041b8a
+SshKeyName: stc-admin-March-2017-PLAYPEN
+ALBCertName: ${ssmstore us-west-2@/simpleweb/bswift/ALBCertName}
+# ALBCertName: 9967b9b9-f046-419a-a496-859bf938acd8
+
diff --git a/tests/stacker_test/dump/stack_templates/cumulus-asgthing-ALB/ALB-e416d7a9.json b/tests/stacker_test/dump/stack_templates/cumulus-asgthing-ALB/ALB-e416d7a9.json
new file mode 100644
index 0000000..fc0d2dc
--- /dev/null
+++ b/tests/stacker_test/dump/stack_templates/cumulus-asgthing-ALB/ALB-e416d7a9.json
@@ -0,0 +1,225 @@
+{
+ "Conditions": {
+ "UseIAMCert": {
+ "Fn::Not": [
+ {
+ "Fn::Equals": [
+ {
+ "Ref": "ALBCertType"
+ },
+ "acm"
+ ]
+ }
+ ]
+ },
+ "UseSSL": {
+ "Fn::Not": [
+ {
+ "Fn::Equals": [
+ {
+ "Ref": "ALBCertName"
+ },
+ ""
+ ]
+ }
+ ]
+ }
+ },
+ "Description": "Acceptance Tests for cumulus scaling groups",
+ "Mappings": {
+ "AmiMap": {
+ "us-west-2": {
+ "amazonLinux2": "ami-a9d09ed1"
+ }
+ }
+ },
+ "Outputs": {
+ "CanonicalHostedZoneID": {
+ "Value": {
+ "Fn::GetAtt": [
+ "cumulusalbLoadBalancer",
+ "CanonicalHostedZoneID"
+ ]
+ }
+ },
+ "DNSName": {
+ "Value": {
+ "Fn::GetAtt": [
+ "cumulusalbLoadBalancer",
+ "DNSName"
+ ]
+ }
+ },
+ "IAlbListener": {
+ "Value": {
+ "Ref": "Listener"
+ }
+ },
+ "InternalAlbSG": {
+ "Value": {
+ "Ref": "cumulusalbAlbSG"
+ }
+ }
+ },
+ "Parameters": {
+ "ALBCertName": {
+ "Default": "",
+ "Description": "The SSL certificate name to use on the ALB.",
+ "Type": "String"
+ },
+ "ALBCertType": {
+ "Default": "acm",
+ "Description": "The SSL certificate type to use on the ALB.",
+ "Type": "String"
+ },
+ "ALBHostName": {
+ "Default": "",
+ "Description": "A hostname to give to the ALB. If not given no ALB will be created.",
+ "Type": "String"
+ },
+ "AvailabilityZones": {
+ "Description": "Availability Zones to deploy instances in.",
+ "Type": "CommaDelimitedList"
+ },
+ "InstanceType": {
+ "Default": "t2.micro",
+ "Description": "EC2 Instance Type",
+ "Type": "String"
+ },
+ "MaxSize": {
+ "Default": "5",
+ "Description": "Maximum # of instances.",
+ "Type": "Number"
+ },
+ "MinSize": {
+ "Default": "1",
+ "Description": "Minimum # of instances.",
+ "Type": "Number"
+ },
+ "PrivateSubnets": {
+ "Description": "Subnets to deploy private instances in.",
+ "Type": "List"
+ },
+ "VpcId": {
+ "Description": "Vpc Id",
+ "Type": "AWS::EC2::VPC::Id"
+ }
+ },
+ "Resources": {
+ "DefaultTargetGroupcumulusalb": {
+ "Properties": {
+ "Port": "80",
+ "Protocol": "HTTP",
+ "VpcId": {
+ "Ref": "VpcId"
+ }
+ },
+ "Type": "AWS::ElasticLoadBalancingV2::TargetGroup"
+ },
+ "Listener": {
+ "Properties": {
+ "Certificates": [
+ {
+ "CertificateArn": {
+ "Fn::If": [
+ "UseIAMCert",
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:iam::",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":server-certificate/",
+ {
+ "Ref": "ALBCertName"
+ }
+ ]
+ ]
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ "arn:aws:acm:",
+ {
+ "Ref": "AWS::Region"
+ },
+ ":",
+ {
+ "Ref": "AWS::AccountId"
+ },
+ ":certificate/",
+ {
+ "Ref": "ALBCertName"
+ }
+ ]
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "DefaultActions": [
+ {
+ "TargetGroupArn": {
+ "Ref": "DefaultTargetGroupcumulusalb"
+ },
+ "Type": "forward"
+ }
+ ],
+ "LoadBalancerArn": {
+ "Ref": "cumulusalbLoadBalancer"
+ },
+ "Port": "443",
+ "Protocol": "HTTPS"
+ },
+ "Type": "AWS::ElasticLoadBalancingV2::Listener"
+ },
+ "LocalNetworkTocumulusalbAlbPort443": {
+ "Properties": {
+ "CidrIp": "10.0.0.0/0",
+ "FromPort": "443",
+ "GroupId": {
+ "Ref": "cumulusalbAlbSG"
+ },
+ "IpProtocol": "tcp",
+ "ToPort": "443"
+ },
+ "Type": "AWS::EC2::SecurityGroupIngress"
+ },
+ "cumulusalbAlbSG": {
+ "Properties": {
+ "GroupDescription": "cumulusalbAlbSG",
+ "VpcId": {
+ "Ref": "VpcId"
+ }
+ },
+ "Type": "AWS::EC2::SecurityGroup"
+ },
+ "cumulusalbLoadBalancer": {
+ "Properties": {
+ "Scheme": "internal",
+ "SecurityGroups": [
+ {
+ "Ref": "cumulusalbAlbSG"
+ }
+ ],
+ "Subnets": {
+ "Ref": "PrivateSubnets"
+ }
+ },
+ "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer"
+ },
+ "cumulusalbSG": {
+ "Properties": {
+ "GroupDescription": "cumulusalbSG",
+ "VpcId": {
+ "Ref": "VpcId"
+ }
+ },
+ "Type": "AWS::EC2::SecurityGroup"
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/stacker_test/somefile.yaml b/tests/stacker_test/somefile.yaml
new file mode 100644
index 0000000..bfdecd7
--- /dev/null
+++ b/tests/stacker_test/somefile.yaml
@@ -0,0 +1,1120 @@
+Description: Acceptance Tests for cumulus scaling groups
+Mappings:
+ AmiMap:
+ us-west-2:
+ amazonLinux2: ami-a9d09ed1
+Resources:
+ InstanceProfilewebsitesimple:
+ Properties:
+ Roles:
+ - !Ref 'SomeRoleName1'
+ Type: AWS::IAM::InstanceProfile
+ Route53Records:
+ Properties:
+ HostedZoneName: !Join
+ - ''
+ - - !Ref 'BaseDomain'
+ - .
+ RecordSets:
+ - AliasTarget:
+ DNSName: !Ref 'ALBDNSName'
+ EvaluateTargetHealth: 'false'
+ HostedZoneId: !Ref 'AlbCanonicalHostedZoneID'
+ Name: !Join
+ - ''
+ - - cumulus
+ - '-'
+ - cumulusdns
+ - .
+ - !Ref 'BaseDomain'
+ - .
+ SetIdentifier: original
+ Type: A
+ Weight: 1
+ Type: AWS::Route53::RecordSetGroup
+ SgCidrAccessCidr100008ToASGPort22:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '22'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '22'
+ Type: AWS::EC2::SecurityGroupIngress
+ SgCidrAccessCidr100008ToASGPort8000:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '8000'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '8000'
+ Type: AWS::EC2::SecurityGroupIngress
+ SomeRoleName1:
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action:
+ - sts:AssumeRole
+ Effect: Allow
+ Principal:
+ Service:
+ - ec2.amazonaws.com
+ - s3.amazonaws.com
+ Type: AWS::IAM::Role
+ asgwebsitesimple:
+ Properties:
+ AvailabilityZones: !Ref 'AvailabilityZones'
+ LaunchConfigurationName: !Ref 'lcwebsitesimple'
+ MaxSize: !Ref 'MaxSize'
+ MinSize: !Ref 'MinSize'
+ Tags:
+ - Key: Name
+ PropagateAtLaunch: true
+ Value: cumulustestscalinggroupInstanceProfilewebsitesimple
+ - Key: CE-OffHours
+ PropagateAtLaunch: true
+ Value: 'off'
+ TargetGroupARNs:
+ - !Ref 'cumulustesttargetgroup'
+ VPCZoneIdentifier: !Ref 'PrivateSubnets'
+ Type: AWS::AutoScaling::AutoScalingGroup
+ UpdatePolicy:
+ AutoScalingReplacingUpdate:
+ WillReplace: 'true'
+ AutoScalingRollingUpdate:
+ MaxBatchSize: '1'
+ MinInstancesInService: '1'
+ PauseTime: PT5M
+ WaitOnResourceSignals: 'true'
+ cumulustesttargetgroup:
+ Properties:
+ HealthCheckIntervalSeconds: '30'
+ HealthCheckPath: /
+ HealthCheckProtocol: HTTP
+ HealthCheckTimeoutSeconds: '10'
+ HealthyThresholdCount: '4'
+ Matcher:
+ HttpCode: '200'
+ Port: 80
+ Protocol: HTTP
+ UnhealthyThresholdCount: '3'
+ VpcId: !Ref 'VpcId'
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
+ lcwebsitesimple:
+ Metadata:
+ AWS::CloudFormation::Init:
+ configSets:
+ default:
+ - install_and_run
+ install_and_run:
+ commands:
+ '01-startup':
+ command: nohup python -m SimpleHTTPServer 8000 &
+ Properties:
+ BlockDeviceMappings:
+ - DeviceName: /dev/xvda
+ Ebs:
+ VolumeSize: '40'
+ IamInstanceProfile: !Ref 'InstanceProfilewebsitesimple'
+ ImageId: !FindInMap
+ - AmiMap
+ - !Ref 'AWS::Region'
+ - !Ref 'ImageName'
+ InstanceType: !Ref 'InstanceType'
+ KeyName: !Ref 'SshKeyName'
+ SecurityGroups:
+ - !Ref 'sg1websitesimple'
+ - !Ref 'sg2websitesimple'
+ UserData: !Base64
+ Fn::Join:
+ - ''
+ - - "#!/bin/bash -xe\n"
+ - "yum update aws-cfn-bootstrap\n"
+ - "# Install the files and packages from the metadata\n"
+ - '/opt/aws/bin/cfn-init '
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --resource '
+ - lcwebsitesimple
+ - ' --configsets default '
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ - "# Signal the ASG we are ready\n\n"
+ - /opt/aws/bin/cfn-signal -e 0
+ - ' --resource websitesimple'
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ Type: AWS::AutoScaling::LaunchConfiguration
+ sg1websitesimple:
+ Properties:
+ GroupDescription: sg1websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+ sg2websitesimple:
+ Properties:
+ GroupDescription: sg2websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+Description: Acceptance Tests for cumulus scaling groups
+Mappings:
+ AmiMap:
+ us-west-2:
+ amazonLinux2: ami-a9d09ed1
+Resources:
+ InstanceProfilewebsitesimple:
+ Properties:
+ Roles:
+ - !Ref 'SomeRoleName1'
+ Type: AWS::IAM::InstanceProfile
+ Route53Records:
+ Properties:
+ HostedZoneName: !Join
+ - ''
+ - - !Ref 'BaseDomain'
+ - .
+ RecordSets:
+ - AliasTarget:
+ DNSName: !Ref 'ALBDNSName'
+ EvaluateTargetHealth: 'false'
+ HostedZoneId: !Ref 'AlbCanonicalHostedZoneID'
+ Name: !Join
+ - ''
+ - - cumulus
+ - '-'
+ - cumulusdns
+ - .
+ - !Ref 'BaseDomain'
+ - .
+ SetIdentifier: original
+ Type: A
+ Weight: 1
+ Type: AWS::Route53::RecordSetGroup
+ SgCidrAccessCidr100008ToASGPort22:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '22'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '22'
+ Type: AWS::EC2::SecurityGroupIngress
+ SgCidrAccessCidr100008ToASGPort8000:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '8000'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '8000'
+ Type: AWS::EC2::SecurityGroupIngress
+ SomeRoleName1:
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action:
+ - sts:AssumeRole
+ Effect: Allow
+ Principal:
+ Service:
+ - ec2.amazonaws.com
+ - s3.amazonaws.com
+ Type: AWS::IAM::Role
+ asgwebsitesimple:
+ Properties:
+ AvailabilityZones: !Ref 'AvailabilityZones'
+ LaunchConfigurationName: !Ref 'lcwebsitesimple'
+ MaxSize: !Ref 'MaxSize'
+ MinSize: !Ref 'MinSize'
+ Tags:
+ - Key: Name
+ PropagateAtLaunch: true
+ Value: cumulustestscalinggroupInstanceProfilewebsitesimple
+ - Key: CE-OffHours
+ PropagateAtLaunch: true
+ Value: 'off'
+ TargetGroupARNs:
+ - !Ref 'cumulustesttargetgroup'
+ VPCZoneIdentifier: !Ref 'PrivateSubnets'
+ Type: AWS::AutoScaling::AutoScalingGroup
+ UpdatePolicy:
+ AutoScalingReplacingUpdate:
+ WillReplace: 'true'
+ AutoScalingRollingUpdate:
+ MaxBatchSize: '1'
+ MinInstancesInService: '1'
+ PauseTime: PT5M
+ WaitOnResourceSignals: 'true'
+ cumulustesttargetgroup:
+ Properties:
+ HealthCheckIntervalSeconds: '30'
+ HealthCheckPath: /
+ HealthCheckProtocol: HTTP
+ HealthCheckTimeoutSeconds: '10'
+ HealthyThresholdCount: '4'
+ Matcher:
+ HttpCode: '200'
+ Port: 80
+ Protocol: HTTP
+ UnhealthyThresholdCount: '3'
+ VpcId: !Ref 'VpcId'
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
+ lcwebsitesimple:
+ Metadata:
+ AWS::CloudFormation::Init:
+ configSets:
+ default:
+ - install_and_run
+ install_and_run:
+ commands:
+ '01-startup':
+ command: nohup python -m SimpleHTTPServer 8000 &
+ Properties:
+ BlockDeviceMappings:
+ - DeviceName: /dev/xvda
+ Ebs:
+ VolumeSize: '40'
+ IamInstanceProfile: !Ref 'InstanceProfilewebsitesimple'
+ ImageId: !FindInMap
+ - AmiMap
+ - !Ref 'AWS::Region'
+ - !Ref 'ImageName'
+ InstanceType: !Ref 'InstanceType'
+ KeyName: !Ref 'SshKeyName'
+ SecurityGroups:
+ - !Ref 'sg1websitesimple'
+ - !Ref 'sg2websitesimple'
+ UserData: !Base64
+ Fn::Join:
+ - ''
+ - - "#!/bin/bash -xe\n"
+ - "yum update aws-cfn-bootstrap\n"
+ - "# Install the files and packages from the metadata\n"
+ - '/opt/aws/bin/cfn-init '
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --resource '
+ - lcwebsitesimple
+ - ' --configsets default '
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ - "# Signal the ASG we are ready\n\n"
+ - /opt/aws/bin/cfn-signal -e 0
+ - ' --resource websitesimple'
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ Type: AWS::AutoScaling::LaunchConfiguration
+ sg1websitesimple:
+ Properties:
+ GroupDescription: sg1websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+ sg2websitesimple:
+ Properties:
+ GroupDescription: sg2websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+Description: Acceptance Tests for cumulus scaling groups
+Mappings:
+ AmiMap:
+ us-west-2:
+ amazonLinux2: ami-a9d09ed1
+Resources:
+ InstanceProfilewebsitesimple:
+ Properties:
+ Roles:
+ - !Ref 'SomeRoleName1'
+ Type: AWS::IAM::InstanceProfile
+ Route53Records:
+ Properties:
+ HostedZoneName: !Join
+ - ''
+ - - !Ref 'BaseDomain'
+ - .
+ RecordSets:
+ - AliasTarget:
+ DNSName: !Ref 'ALBDNSName'
+ EvaluateTargetHealth: 'false'
+ HostedZoneId: !Ref 'AlbCanonicalHostedZoneID'
+ Name: !Join
+ - ''
+ - - cumulus
+ - '-'
+ - cumulusdns
+ - .
+ - !Ref 'BaseDomain'
+ - .
+ SetIdentifier: original
+ Type: A
+ Weight: 1
+ Type: AWS::Route53::RecordSetGroup
+ SgCidrAccessCidr100008ToASGPort22:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '22'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '22'
+ Type: AWS::EC2::SecurityGroupIngress
+ SgCidrAccessCidr100008ToASGPort8000:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '8000'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '8000'
+ Type: AWS::EC2::SecurityGroupIngress
+ SomeRoleName1:
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action:
+ - sts:AssumeRole
+ Effect: Allow
+ Principal:
+ Service:
+ - ec2.amazonaws.com
+ - s3.amazonaws.com
+ Type: AWS::IAM::Role
+ asgwebsitesimple:
+ Properties:
+ AvailabilityZones: !Ref 'AvailabilityZones'
+ LaunchConfigurationName: !Ref 'lcwebsitesimple'
+ MaxSize: !Ref 'MaxSize'
+ MinSize: !Ref 'MinSize'
+ Tags:
+ - Key: Name
+ PropagateAtLaunch: true
+ Value: cumulustestscalinggroupInstanceProfilewebsitesimple
+ - Key: CE-OffHours
+ PropagateAtLaunch: true
+ Value: 'off'
+ TargetGroupARNs:
+ - !Ref 'cumulustesttargetgroup'
+ VPCZoneIdentifier: !Ref 'PrivateSubnets'
+ Type: AWS::AutoScaling::AutoScalingGroup
+ UpdatePolicy:
+ AutoScalingReplacingUpdate:
+ WillReplace: 'true'
+ AutoScalingRollingUpdate:
+ MaxBatchSize: '1'
+ MinInstancesInService: '1'
+ PauseTime: PT5M
+ WaitOnResourceSignals: 'true'
+ cumulustesttargetgroup:
+ Properties:
+ HealthCheckIntervalSeconds: '30'
+ HealthCheckPath: /
+ HealthCheckProtocol: HTTP
+ HealthCheckTimeoutSeconds: '10'
+ HealthyThresholdCount: '4'
+ Matcher:
+ HttpCode: '200'
+ Port: 80
+ Protocol: HTTP
+ UnhealthyThresholdCount: '3'
+ VpcId: !Ref 'VpcId'
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
+ lcwebsitesimple:
+ Metadata:
+ AWS::CloudFormation::Init:
+ configSets:
+ default:
+ - install_and_run
+ install_and_run:
+ commands:
+ '01-startup':
+ command: nohup python -m SimpleHTTPServer 8000 &
+ Properties:
+ BlockDeviceMappings:
+ - DeviceName: /dev/xvda
+ Ebs:
+ VolumeSize: '40'
+ IamInstanceProfile: !Ref 'InstanceProfilewebsitesimple'
+ ImageId: !FindInMap
+ - AmiMap
+ - !Ref 'AWS::Region'
+ - !Ref 'ImageName'
+ InstanceType: !Ref 'InstanceType'
+ KeyName: !Ref 'SshKeyName'
+ SecurityGroups:
+ - !Ref 'sg1websitesimple'
+ - !Ref 'sg2websitesimple'
+ UserData: !Base64
+ Fn::Join:
+ - ''
+ - - "#!/bin/bash -xe\n"
+ - "yum update aws-cfn-bootstrap\n"
+ - "# Install the files and packages from the metadata\n"
+ - '/opt/aws/bin/cfn-init '
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --resource '
+ - lcwebsitesimple
+ - ' --configsets default '
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ - "# Signal the ASG we are ready\n\n"
+ - /opt/aws/bin/cfn-signal -e 0
+ - ' --resource websitesimple'
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ Type: AWS::AutoScaling::LaunchConfiguration
+ sg1websitesimple:
+ Properties:
+ GroupDescription: sg1websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+ sg2websitesimple:
+ Properties:
+ GroupDescription: sg2websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+Description: Acceptance Tests for cumulus scaling groups
+Mappings:
+ AmiMap:
+ us-west-2:
+ amazonLinux2: ami-a9d09ed1
+Resources:
+ InstanceProfilewebsitesimple:
+ Properties:
+ Roles:
+ - !Ref 'SomeRoleName1'
+ Type: AWS::IAM::InstanceProfile
+ Route53Records:
+ Properties:
+ HostedZoneName: !Join
+ - ''
+ - - !Ref 'BaseDomain'
+ - .
+ RecordSets:
+ - AliasTarget:
+ DNSName: !Ref 'ALBDNSName'
+ EvaluateTargetHealth: 'false'
+ HostedZoneId: !Ref 'AlbCanonicalHostedZoneID'
+ Name: !Join
+ - ''
+ - - cumulus
+ - '-'
+ - cumulusdns
+ - .
+ - !Ref 'BaseDomain'
+ - .
+ SetIdentifier: original
+ Type: A
+ Weight: 1
+ Type: AWS::Route53::RecordSetGroup
+ SgCidrAccessCidr100008ToASGPort22:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '22'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '22'
+ Type: AWS::EC2::SecurityGroupIngress
+ SgCidrAccessCidr100008ToASGPort8000:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '8000'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '8000'
+ Type: AWS::EC2::SecurityGroupIngress
+ SomeRoleName1:
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action:
+ - sts:AssumeRole
+ Effect: Allow
+ Principal:
+ Service:
+ - ec2.amazonaws.com
+ - s3.amazonaws.com
+ Type: AWS::IAM::Role
+ asgwebsitesimple:
+ Properties:
+ AvailabilityZones: !Ref 'AvailabilityZones'
+ LaunchConfigurationName: !Ref 'lcwebsitesimple'
+ MaxSize: !Ref 'MaxSize'
+ MinSize: !Ref 'MinSize'
+ Tags:
+ - Key: Name
+ PropagateAtLaunch: true
+ Value: cumulustestscalinggroupInstanceProfilewebsitesimple
+ - Key: CE-OffHours
+ PropagateAtLaunch: true
+ Value: 'off'
+ TargetGroupARNs:
+ - !Ref 'cumulustesttargetgroup'
+ VPCZoneIdentifier: !Ref 'PrivateSubnets'
+ Type: AWS::AutoScaling::AutoScalingGroup
+ UpdatePolicy:
+ AutoScalingReplacingUpdate:
+ WillReplace: 'true'
+ AutoScalingRollingUpdate:
+ MaxBatchSize: '1'
+ MinInstancesInService: '1'
+ PauseTime: PT5M
+ WaitOnResourceSignals: 'true'
+ cumulustesttargetgroup:
+ Properties:
+ HealthCheckIntervalSeconds: '30'
+ HealthCheckPath: /
+ HealthCheckProtocol: HTTP
+ HealthCheckTimeoutSeconds: '10'
+ HealthyThresholdCount: '4'
+ Matcher:
+ HttpCode: '200'
+ Port: 80
+ Protocol: HTTP
+ UnhealthyThresholdCount: '3'
+ VpcId: !Ref 'VpcId'
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
+ lcwebsitesimple:
+ Metadata:
+ AWS::CloudFormation::Init:
+ configSets:
+ default:
+ - install_and_run
+ install_and_run:
+ commands:
+ '01-startup':
+ command: nohup python -m SimpleHTTPServer 8000 &
+ Properties:
+ BlockDeviceMappings:
+ - DeviceName: /dev/xvda
+ Ebs:
+ VolumeSize: '40'
+ IamInstanceProfile: !Ref 'InstanceProfilewebsitesimple'
+ ImageId: !FindInMap
+ - AmiMap
+ - !Ref 'AWS::Region'
+ - !Ref 'ImageName'
+ InstanceType: !Ref 'InstanceType'
+ KeyName: !Ref 'SshKeyName'
+ SecurityGroups:
+ - !Ref 'sg1websitesimple'
+ - !Ref 'sg2websitesimple'
+ UserData: !Base64
+ Fn::Join:
+ - ''
+ - - "#!/bin/bash -xe\n"
+ - "yum update aws-cfn-bootstrap\n"
+ - "# Install the files and packages from the metadata\n"
+ - '/opt/aws/bin/cfn-init '
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --resource '
+ - lcwebsitesimple
+ - ' --configsets default '
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ - "# Signal the ASG we are ready\n\n"
+ - /opt/aws/bin/cfn-signal -e 0
+ - ' --resource websitesimple'
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ Type: AWS::AutoScaling::LaunchConfiguration
+ sg1websitesimple:
+ Properties:
+ GroupDescription: sg1websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+ sg2websitesimple:
+ Properties:
+ GroupDescription: sg2websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+Description: Acceptance Tests for cumulus scaling groups
+Mappings:
+ AmiMap:
+ us-west-2:
+ amazonLinux2: ami-a9d09ed1
+Resources:
+ InstanceProfilewebsitesimple:
+ Properties:
+ Roles:
+ - !Ref 'SomeRoleName1'
+ Type: AWS::IAM::InstanceProfile
+ Route53Records:
+ Properties:
+ HostedZoneName: !Join
+ - ''
+ - - !Ref 'BaseDomain'
+ - .
+ RecordSets:
+ - AliasTarget:
+ DNSName: !Ref 'ALBDNSName'
+ EvaluateTargetHealth: 'false'
+ HostedZoneId: !Ref 'AlbCanonicalHostedZoneID'
+ Name: !Join
+ - ''
+ - - cumulus
+ - '-'
+ - cumulusdns
+ - .
+ - !Ref 'BaseDomain'
+ - .
+ SetIdentifier: original
+ Type: A
+ Weight: 1
+ Type: AWS::Route53::RecordSetGroup
+ SgCidrAccessCidr100008ToASGPort22:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '22'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '22'
+ Type: AWS::EC2::SecurityGroupIngress
+ SgCidrAccessCidr100008ToASGPort8000:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '8000'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '8000'
+ Type: AWS::EC2::SecurityGroupIngress
+ SomeRoleName1:
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action:
+ - sts:AssumeRole
+ Effect: Allow
+ Principal:
+ Service:
+ - ec2.amazonaws.com
+ - s3.amazonaws.com
+ Type: AWS::IAM::Role
+ asgwebsitesimple:
+ Properties:
+ AvailabilityZones: !Ref 'AvailabilityZones'
+ LaunchConfigurationName: !Ref 'lcwebsitesimple'
+ MaxSize: !Ref 'MaxSize'
+ MinSize: !Ref 'MinSize'
+ Tags:
+ - Key: Name
+ PropagateAtLaunch: true
+ Value: cumulustestscalinggroupInstanceProfilewebsitesimple
+ - Key: CE-OffHours
+ PropagateAtLaunch: true
+ Value: 'off'
+ TargetGroupARNs:
+ - !Ref 'cumulustesttargetgroup'
+ VPCZoneIdentifier: !Ref 'PrivateSubnets'
+ Type: AWS::AutoScaling::AutoScalingGroup
+ UpdatePolicy:
+ AutoScalingReplacingUpdate:
+ WillReplace: 'true'
+ AutoScalingRollingUpdate:
+ MaxBatchSize: '1'
+ MinInstancesInService: '1'
+ PauseTime: PT5M
+ WaitOnResourceSignals: 'true'
+ cumulustesttargetgroup:
+ Properties:
+ HealthCheckIntervalSeconds: '30'
+ HealthCheckPath: /
+ HealthCheckProtocol: HTTP
+ HealthCheckTimeoutSeconds: '10'
+ HealthyThresholdCount: '4'
+ Matcher:
+ HttpCode: '200'
+ Port: 80
+ Protocol: HTTP
+ UnhealthyThresholdCount: '3'
+ VpcId: !Ref 'VpcId'
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
+ lcwebsitesimple:
+ Metadata:
+ AWS::CloudFormation::Init:
+ configSets:
+ default:
+ - install_and_run
+ install_and_run:
+ commands:
+ '01-startup':
+ command: nohup python -m SimpleHTTPServer 8000 &
+ Properties:
+ BlockDeviceMappings:
+ - DeviceName: /dev/xvda
+ Ebs:
+ VolumeSize: '40'
+ IamInstanceProfile: !Ref 'InstanceProfilewebsitesimple'
+ ImageId: !FindInMap
+ - AmiMap
+ - !Ref 'AWS::Region'
+ - !Ref 'ImageName'
+ InstanceType: !Ref 'InstanceType'
+ KeyName: !Ref 'SshKeyName'
+ SecurityGroups:
+ - !Ref 'sg1websitesimple'
+ - !Ref 'sg2websitesimple'
+ UserData: !Base64
+ Fn::Join:
+ - ''
+ - - "#!/bin/bash -xe\n"
+ - "yum update aws-cfn-bootstrap\n"
+ - "# Install the files and packages from the metadata\n"
+ - '/opt/aws/bin/cfn-init '
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --resource '
+ - lcwebsitesimple
+ - ' --configsets default '
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ - "# Signal the ASG we are ready\n\n"
+ - /opt/aws/bin/cfn-signal -e 0
+ - ' --resource websitesimple'
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ Type: AWS::AutoScaling::LaunchConfiguration
+ sg1websitesimple:
+ Properties:
+ GroupDescription: sg1websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+ sg2websitesimple:
+ Properties:
+ GroupDescription: sg2websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+Description: Acceptance Tests for cumulus scaling groups
+Mappings:
+ AmiMap:
+ us-west-2:
+ amazonLinux2: ami-a9d09ed1
+Resources:
+ InstanceProfilewebsitesimple:
+ Properties:
+ Roles:
+ - !Ref 'SomeRoleName1'
+ Type: AWS::IAM::InstanceProfile
+ Route53Records:
+ Properties:
+ HostedZoneName: !Join
+ - ''
+ - - !Ref 'BaseDomain'
+ - .
+ RecordSets:
+ - AliasTarget:
+ DNSName: !Ref 'ALBDNSName'
+ EvaluateTargetHealth: 'false'
+ HostedZoneId: !Ref 'AlbCanonicalHostedZoneID'
+ Name: !Join
+ - ''
+ - - cumulus
+ - '-'
+ - cumulusdns
+ - .
+ - !Ref 'BaseDomain'
+ - .
+ SetIdentifier: original
+ Type: A
+ Weight: 1
+ Type: AWS::Route53::RecordSetGroup
+ SgCidrAccessCidr100008ToASGPort22:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '22'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '22'
+ Type: AWS::EC2::SecurityGroupIngress
+ SgCidrAccessCidr100008ToASGPort8000:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '8000'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '8000'
+ Type: AWS::EC2::SecurityGroupIngress
+ SomeRoleName1:
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action:
+ - sts:AssumeRole
+ Effect: Allow
+ Principal:
+ Service:
+ - ec2.amazonaws.com
+ - s3.amazonaws.com
+ Type: AWS::IAM::Role
+ asgwebsitesimple:
+ Properties:
+ AvailabilityZones: !Ref 'AvailabilityZones'
+ LaunchConfigurationName: !Ref 'lcwebsitesimple'
+ MaxSize: !Ref 'MaxSize'
+ MinSize: !Ref 'MinSize'
+ Tags:
+ - Key: Name
+ PropagateAtLaunch: true
+ Value: cumulustestscalinggroupInstanceProfilewebsitesimple
+ - Key: CE-OffHours
+ PropagateAtLaunch: true
+ Value: 'off'
+ TargetGroupARNs:
+ - !Ref 'cumulustesttargetgroup'
+ VPCZoneIdentifier: !Ref 'PrivateSubnets'
+ Type: AWS::AutoScaling::AutoScalingGroup
+ UpdatePolicy:
+ AutoScalingReplacingUpdate:
+ WillReplace: 'true'
+ AutoScalingRollingUpdate:
+ MaxBatchSize: '1'
+ MinInstancesInService: '1'
+ PauseTime: PT5M
+ WaitOnResourceSignals: 'true'
+ cumulustesttargetgroup:
+ Properties:
+ HealthCheckIntervalSeconds: '30'
+ HealthCheckPath: /
+ HealthCheckProtocol: HTTP
+ HealthCheckTimeoutSeconds: '10'
+ HealthyThresholdCount: '4'
+ Matcher:
+ HttpCode: '200'
+ Port: 80
+ Protocol: HTTP
+ UnhealthyThresholdCount: '3'
+ VpcId: !Ref 'VpcId'
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
+ lcwebsitesimple:
+ Metadata:
+ AWS::CloudFormation::Init:
+ configSets:
+ default:
+ - install_and_run
+ install_and_run:
+ commands:
+ '01-startup':
+ command: nohup python -m SimpleHTTPServer 8000 &
+ Properties:
+ BlockDeviceMappings:
+ - DeviceName: /dev/xvda
+ Ebs:
+ VolumeSize: '40'
+ IamInstanceProfile: !Ref 'InstanceProfilewebsitesimple'
+ ImageId: !FindInMap
+ - AmiMap
+ - !Ref 'AWS::Region'
+ - !Ref 'ImageName'
+ InstanceType: !Ref 'InstanceType'
+ KeyName: !Ref 'SshKeyName'
+ SecurityGroups:
+ - !Ref 'sg1websitesimple'
+ - !Ref 'sg2websitesimple'
+ UserData: !Base64
+ Fn::Join:
+ - ''
+ - - "#!/bin/bash -xe\n"
+ - "yum update aws-cfn-bootstrap\n"
+ - "# Install the files and packages from the metadata\n"
+ - '/opt/aws/bin/cfn-init '
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --resource '
+ - lcwebsitesimple
+ - ' --configsets default '
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ - "# Signal the ASG we are ready\n\n"
+ - /opt/aws/bin/cfn-signal -e 0
+ - ' --resource websitesimple'
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ Type: AWS::AutoScaling::LaunchConfiguration
+ sg1websitesimple:
+ Properties:
+ GroupDescription: sg1websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+ sg2websitesimple:
+ Properties:
+ GroupDescription: sg2websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+Description: Acceptance Tests for cumulus scaling groups
+Mappings:
+ AmiMap:
+ us-west-2:
+ amazonLinux2: ami-a9d09ed1
+Resources:
+ InstanceProfilewebsitesimple:
+ Properties:
+ Roles:
+ - !Ref 'SomeRoleName1'
+ Type: AWS::IAM::InstanceProfile
+ Route53Records:
+ Properties:
+ HostedZoneName: !Join
+ - ''
+ - - !Ref 'BaseDomain'
+ - .
+ RecordSets:
+ - AliasTarget:
+ DNSName: !Ref 'AlbDNSName'
+ EvaluateTargetHealth: 'false'
+ HostedZoneId: !Ref 'AlbCanonicalHostedZoneID'
+ Name: !Join
+ - ''
+ - - cumulus
+ - '-'
+ - cumulusdns
+ - .
+ - !Ref 'BaseDomain'
+ - .
+ SetIdentifier: original
+ Type: A
+ Weight: 1
+ Type: AWS::Route53::RecordSetGroup
+ SgCidrAccessCidr100008ToASGPort22:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '22'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '22'
+ Type: AWS::EC2::SecurityGroupIngress
+ SgCidrAccessCidr100008ToASGPort8000:
+ Properties:
+ CidrIp: 10.0.0.0/8
+ FromPort: '8000'
+ GroupId: !Ref 'sg1websitesimple'
+ IpProtocol: tcp
+ ToPort: '8000'
+ Type: AWS::EC2::SecurityGroupIngress
+ SomeRoleName1:
+ Properties:
+ AssumeRolePolicyDocument:
+ Statement:
+ - Action:
+ - sts:AssumeRole
+ Effect: Allow
+ Principal:
+ Service:
+ - ec2.amazonaws.com
+ - s3.amazonaws.com
+ Type: AWS::IAM::Role
+ asgwebsitesimple:
+ Properties:
+ AvailabilityZones: !Ref 'AvailabilityZones'
+ LaunchConfigurationName: !Ref 'lcwebsitesimple'
+ MaxSize: !Ref 'MaxSize'
+ MinSize: !Ref 'MinSize'
+ Tags:
+ - Key: Name
+ PropagateAtLaunch: true
+ Value: cumulustestscalinggroupInstanceProfilewebsitesimple
+ - Key: CE-OffHours
+ PropagateAtLaunch: true
+ Value: 'off'
+ TargetGroupARNs:
+ - !Ref 'cumulustesttargetgroup'
+ VPCZoneIdentifier: !Ref 'PrivateSubnets'
+ Type: AWS::AutoScaling::AutoScalingGroup
+ UpdatePolicy:
+ AutoScalingReplacingUpdate:
+ WillReplace: 'true'
+ AutoScalingRollingUpdate:
+ MaxBatchSize: '1'
+ MinInstancesInService: '1'
+ PauseTime: PT5M
+ WaitOnResourceSignals: 'true'
+ cumulustesttargetgroup:
+ Properties:
+ HealthCheckIntervalSeconds: '30'
+ HealthCheckPath: /
+ HealthCheckProtocol: HTTP
+ HealthCheckTimeoutSeconds: '10'
+ HealthyThresholdCount: '4'
+ Matcher:
+ HttpCode: '200'
+ Port: 80
+ Protocol: HTTP
+ UnhealthyThresholdCount: '3'
+ VpcId: !Ref 'VpcId'
+ Type: AWS::ElasticLoadBalancingV2::TargetGroup
+ lcwebsitesimple:
+ Metadata:
+ AWS::CloudFormation::Init:
+ configSets:
+ default:
+ - install_and_run
+ install_and_run:
+ commands:
+ '01-startup':
+ command: nohup python -m SimpleHTTPServer 8000 &
+ Properties:
+ BlockDeviceMappings:
+ - DeviceName: /dev/xvda
+ Ebs:
+ VolumeSize: '40'
+ IamInstanceProfile: !Ref 'InstanceProfilewebsitesimple'
+ ImageId: !FindInMap
+ - AmiMap
+ - !Ref 'AWS::Region'
+ - !Ref 'ImageName'
+ InstanceType: !Ref 'InstanceType'
+ KeyName: !Ref 'SshKeyName'
+ SecurityGroups:
+ - !Ref 'sg1websitesimple'
+ - !Ref 'sg2websitesimple'
+ UserData: !Base64
+ Fn::Join:
+ - ''
+ - - "#!/bin/bash -xe\n"
+ - "yum update aws-cfn-bootstrap\n"
+ - "# Install the files and packages from the metadata\n"
+ - '/opt/aws/bin/cfn-init '
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --resource '
+ - lcwebsitesimple
+ - ' --configsets default '
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ - "# Signal the ASG we are ready\n\n"
+ - /opt/aws/bin/cfn-signal -e 0
+ - ' --resource websitesimple'
+ - ' --stack '
+ - !Ref 'AWS::StackName'
+ - ' --region '
+ - !Ref 'AWS::Region'
+ - "\n"
+ Type: AWS::AutoScaling::LaunchConfiguration
+ sg1websitesimple:
+ Properties:
+ GroupDescription: sg1websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
+ sg2websitesimple:
+ Properties:
+ GroupDescription: sg2websitesimple
+ VpcId: vpc-894b89ef
+ Type: AWS::EC2::SecurityGroup
diff --git a/tests/stacker_test/stacker.yaml b/tests/stacker_test/stacker.yaml
index 7446967..04fee99 100644
--- a/tests/stacker_test/stacker.yaml
+++ b/tests/stacker_test/stacker.yaml
@@ -1,15 +1,56 @@
# This file is used in an integration test for this project.
-namespace: cumulus-${namespace}
+namespace: cumulus
stacker_bucket: bswift-spike
sys_path: .
+vpc_variables: &vpc_variables
+ VpcId: ${VpcId}
+ AvailabilityZones: us-west-2a,us-west-2b
+ BaseDomain: ${BaseDomain}
+ PrivateSubnets: ${PrivateSubnets}
+
+ # Common variables when using the ALB
+alb_variables: &alb_variables
+ AlbDNSName: ${output ALB::DNSName}
+ AlbCanonicalHostedZoneID: ${output ALB::CanonicalHostedZoneID}
+ IAlbListener: ${output ALB::IAlbListener}
+ AlbSg: ${output ALB::InternalAlbSG}
+
+mappings:
+ AmiMap:
+ us-west-2:
+ amazonLinux2: ami-a9d09ed1
+# ami-31394949
+
# The stacks key accepts a list of stack declarations.
# http://stacker.readthedocs.io/en/latest/config.html#stacks
stacks:
# - name: s3bucket-smoke-test
# class_path: blueprints.s3_bucket.S3Simple
+ - name: ALB
+ class_path: blueprints.alb.Alb
+ variables:
+ << : *vpc_variables # yaml parameter expansion syntax
+ ALBHostName: cumulus-alb-test
+ ALBCertName: ${ALBCertName} # INFO: This is a lookup to the .env file or -e cli param (which you won't use right!)
- name: pipelinesimple
class_path: blueprints.pipeline_simple.PipelineSimple
+ - name: scalinggroupsimple
+ class_path: blueprints.scaling_group_simple.ScalingGroupSimple
+ variables:
+ << : *vpc_variables # yaml parameter expansion syntax
+ ImageName: amazonLinux2
+ SshKeyName: stc-admin-March-2017-PLAYPEN
+ - name: websitesimple
+ class_path: blueprints.website_simple.WebsiteSimple
+ variables:
+ << : *vpc_variables # yaml parameter expansion syntax
+ << : *alb_variables
+ namespace: dev
+ stackname: ${stackname}
+ ImageName: amazonLinux2
+ SshKeyName: stc-admin-March-2017-PLAYPEN
+