def test_TagAddition(self): tags = Tags(foo='foo') tags += Tags(bar='bar') tags = tags + Tags(baz='baz') result = [ {'Value': 'foo', 'Key': 'foo'}, {'Value': 'bar', 'Key': 'bar'}, {'Value': 'baz', 'Key': 'baz'}, ] self.assertEqual(tags.to_dict(), result)
def test_Formats(self): result = [ {'Value': 'bar', 'Key': 'bar'}, {'Value': 'baz', 'Key': 'baz'}, {'Value': 'foo', 'Key': 'foo'}, ] tags = Tags(bar='bar', baz='baz', foo='foo') self.assertEqual(tags.to_dict(), result) tags = Tags({'bar': 'bar', 'baz': 'baz', 'foo': 'foo'}) self.assertEqual(tags.to_dict(), result) tags = Tags(**{'bar': 'bar', 'baz': 'baz', 'foo': 'foo'}) self.assertEqual(tags.to_dict(), result) result = [{'Key': 'test-tag', 'Value': '123456'}] tags = Tags({'test-tag': '123456'}) self.assertEqual(tags.to_dict(), result) with self.assertRaises(TypeError): Tags(1) with self.assertRaises(TypeError): Tags("tag") with self.assertRaises(TypeError): Tags("key", "value") with self.assertRaises(TypeError): Tags({}, "key", "value")
def test_Formats(self): result = [ { "Value": "bar", "Key": "bar" }, { "Value": "baz", "Key": "baz" }, { "Value": "foo", "Key": "foo" }, ] tags = Tags(bar="bar", baz="baz", foo="foo") self.assertEqual(tags.to_dict(), result) tags = Tags({"bar": "bar", "baz": "baz", "foo": "foo"}) self.assertEqual(tags.to_dict(), result) tags = Tags(**{"bar": "bar", "baz": "baz", "foo": "foo"}) self.assertEqual(tags.to_dict(), result) result = [{"Key": "test-tag", "Value": "123456"}] tags = Tags({"test-tag": "123456"}) self.assertEqual(tags.to_dict(), result) with self.assertRaises(TypeError): Tags(1) with self.assertRaises(TypeError): Tags("tag") with self.assertRaises(TypeError): Tags("key", "value") with self.assertRaises(TypeError): Tags({}, "key", "value")
def test_Unsortable(self): result = [{'Key': {'Fn::Sub': 'somestring'}, 'Value': 'val'}] tags = Tags({Sub('somestring'): 'val'}) self.assertEqual(tags.to_dict(), result)
Default="m3.medium", ConstraintDescription="must be a valid EC2 instance type.", Type="String", Description="Cluster EC2 instance type", AllowedValues=["m3.medium", "m3.large", "m3.xlarge", "m3.2xlarge", "c4.large", "c4.xlarge", "c4.2xlarge", "c4.4xlarge", "c4.8xlarge", "g2.2xlarge", "r3.large", "r3.xlarge", "r3.2xlarge", "r3.4xlarge", "r3.8xlarge"], )) ### SETUP THE VPC ### AlchemyVPC = t.add_resource(VPC( "AlchemyVPC", EnableDnsSupport="true", EnableDnsHostnames="false", CidrBlock="10.0.0.0/16", Tags=Tags(Name=Join("",[Ref(ClusterName), " VPC"])) )) ### Internet Gateway internetGateway = t.add_resource(InternetGateway( "internetGateway", Tags=Tags(Name=Join("",[Ref(ClusterName), " Internet Gateway"])) )) internetGatewayAttachment = t.add_resource(VPCGatewayAttachment( "internetGatewayAttachment", VpcId=Ref(AlchemyVPC), InternetGatewayId=Ref(internetGateway), ))
# cfn-hup # Start up the cfn-hup daemon to listen for changes to the server metadata 'yum install -y aws-cfn-bootstrap\n', '/opt/aws/bin/cfn-hup || error_exit "Failed to start cfn-hup"', '\n', # cfn-signal '/opt/aws/bin/cfn-signal -e $? ', ' --stack ', Ref('AWS::StackName'), ' --resource DevServer', ' --region ', Ref('AWS::Region'), '\n' ]) ), Tags=Tags( StackName=Ref('AWS::StackName'), Name='dev-server', ) ) ) # outputs template.add_output([ Output('DevServer', Description='EC2 Instance', Value=Ref(ec2_instance)) ]) template_json = template.to_json(indent=4) print(template_json) stack_args = {
def buildInfrastructure(t, args): if (not args.recovery): t.add_resource( kms.Key( 'OpenEMRKey', DeletionPolicy='Retain' if args.recovery else 'Delete' if args.dev else 'Retain', KeyPolicy={ "Version": "2012-10-17", "Id": "key-default-1", "Statement": [{ "Sid": "1", "Effect": "Allow", "Principal": { "AWS": [Join(':', ['arn:aws:iam:', ref_account, 'root'])] }, "Action": "kms:*", "Resource": "*" }] })) t.add_resource( s3.Bucket( 'S3Bucket', DeletionPolicy='Retain', BucketName=Join( '-', ['openemr', Select('2', Split('/', ref_stack_id))]))) t.add_resource( s3.BucketPolicy( 'BucketPolicy', Bucket=Ref('S3Bucket'), PolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Sid": "AWSCloudTrailAclCheck", "Effect": "Allow", "Principal": { "Service": "cloudtrail.amazonaws.com" }, "Action": "s3:GetBucketAcl", "Resource": { "Fn::Join": ["", ["arn:aws:s3:::", { "Ref": "S3Bucket" }]] } }, { "Sid": "AWSCloudTrailWrite", "Effect": "Allow", "Principal": { "Service": "cloudtrail.amazonaws.com" }, "Action": "s3:PutObject", "Resource": { "Fn::Join": [ "", [ "arn:aws:s3:::", { "Ref": "S3Bucket" }, "/AWSLogs/", { "Ref": "AWS::AccountId" }, "/*" ] ] }, "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } } }] })) t.add_resource( cloudtrail.Trail('CloudTrail', DependsOn='BucketPolicy', IsLogging=True, IncludeGlobalServiceEvents=True, IsMultiRegionTrail=True, S3BucketName=Ref('S3Bucket'))) t.add_resource( ec2.SecurityGroup('ApplicationSecurityGroup', GroupDescription='Application Security Group', VpcId=Ref('VPC'), Tags=Tags(Name='Application'))) return t
AZ2 = t.add_parameter(Parameter( "AZ2", Type="AWS::EC2::AvailabilityZone::Name", Description="Please choose AZ2" )) PublicSubnet2RouteTableAssociation = t.add_resource(SubnetRouteTableAssociation( "PublicSubnet2RouteTableAssociation", SubnetId=Ref("PublicSubnet2"), RouteTableId=Ref("PublicRouteTable"), )) InternetGateway = t.add_resource(InternetGateway( "InternetGateway", Tags=Tags( Name=Ref(EnvironmentName), ), )) DefaultPublicRoute = t.add_resource(Route( "DefaultPublicRoute", GatewayId=Ref(InternetGateway), DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref("PublicRouteTable"), DependsOn="InternetGatewayAttachment", )) DefaultPrivateRoute1 = t.add_resource(Route( "DefaultPrivateRoute1", DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref("PrivateRouteTable1"),
from ipaddress import ip_network from troposphere import Ref, Tags, Template from tropopause.ec2 import InternetGatewayVPC from tropopause.ec2 import PublicSubnet, PrivateSubnet, SecureSubnet CidrBlock = '10.10.0.0/20' region = 'us-east-1' subnets = list(ip_network(CidrBlock).subnets(prefixlen_diff=4)) template = Template() template.add_version('2010-09-09') template.add_description('Example VPC') vpc = InternetGatewayVPC('vpc', template, CidrBlock=CidrBlock, Tags=Tags(a='a')) zones = ['a', 'b', 'c'] i = 0 for zone in zones: PublicSubnet('public' + region.replace('-', '') + zone, template, AvailabilityZone=region + zone, CidrBlock=str(subnets[i % len(zones) + 0 * len(zones)]), MapPublicIpOnLaunch=True, VpcId=Ref(vpc)) PrivateSubnet('private' + region.replace('-', '') + zone, template, AvailabilityZone=region + zone, CidrBlock=str(subnets[i % len(zones) + 1 * len(zones)]),
load_balancer_security_group = SecurityGroup( "LoadBalancerSecurityGroup", template=template, GroupDescription="Web load balancer security group.", VpcId=Ref(vpc), SecurityGroupIngress=[ # allow incoming traffic from the public internet to the load balancer # on ports 80 and 443 SecurityGroupRule( IpProtocol="tcp", FromPort=port, ToPort=port, CidrIp="0.0.0.0/0", ) for port in ["80", "443"] ], Tags=Tags(Name=Join("-", [Ref("AWS::StackName"), "elb"]), ), ) # allow traffic from the load balancer subnets to the web workers if USE_ECS or USE_EC2: # if using ECS or EC2, allow traffic to the configured WebWorkerPort web_worker_ports = [Ref("WebWorkerPort")] elif USE_GOVCLOUD: # if using GovCloud (real EC2 instances), allow traffic to the configured # WebWorkerPort and port 443 web_worker_ports = [Ref("WebWorkerPort"), "443"] else: # otherwise, if using Elastic Beanstalk, allow traffic only to EB's default # web worker port (80) web_worker_ports = ["80"]
def build_template(self): t = self._init_template() # ami input + param self.infra.add_var( 'Input{}EC2Ami'.format(self.stack_name), self.ami ) ami_param = t.add_parameter(Parameter( 'Input{}EC2Ami'.format(self.stack_name), Type='String' )) # tag Name tag_name = t.add_parameter(Parameter( "Input{}EC2TagName".format(self.stack_name), Type="String", Default='{}EC2'.format(self.stack_name), Description="Tag name for {} EC2 Stack".format(self.stack_name) )) # instance type instance_type = t.add_parameter( Parameter( "Input{}EC2InstanceType".format( self.stack_name), Type="String", Description="Instance Type for {} EC2 Stack".format( self.stack_name), Default="t2.micro")) # root file size root_device_size = t.add_parameter(Parameter( "Input{}EC2RootDeviceSize".format(self.stack_name), Type="String", Default="20", Description="{} Root Device File Size".format(self.stack_name) )) # root device name root_device_name = t.add_parameter(Parameter( "Input{}EC2RootDeviceName".format(self.stack_name), Type="String", Default="/dev/xvda", Description="{} Root Device Name".format(self.stack_name) )) # root device type root_device_type = t.add_parameter(Parameter( "Input{}EC2RootDeviceType".format(self.stack_name), Type="String", Default="gp2", Description="{} Root Device Type".format(self.stack_name) )) # instance profile instance_profile_param = t.add_parameter(Parameter( self.iam_profile.output_instance_profile(), Type='String' )) # user data params user_data = [] for i in range(0, 4): user_data.append( Ref(t.add_parameter(Parameter( '{}UserData{}'.format(self.stack_name, i), Type='String', Default=' ', Description='{} UserData #{}'.format(self.stack_name, i) ))) ) # subnet if self.private_subnet: subnet = self.vpc.output_private_subnets()[0] else: self.network_interfaces[0].AssociatePublicIpAddress = True subnet = self.vpc.output_public_subnets()[0] subnet_param = t.add_parameter(Parameter( subnet, Type='String', Description='Subnet for ec2 {}'.format(self.stack_name) )) self.network_interfaces[0].SubnetId = Ref(subnet_param) for sg in self.security_groups: sg_param = t.add_parameter(Parameter( sg.output_security_group(), Type='String' )) self.network_interfaces[0].GroupSet.append(Ref(sg_param)) volumes = [] for volume in self.volumes: device_name = t.add_parameter(Parameter( 'Input{}EBSDeviceName'.format(volume.name), Type='String' )) volume_id = t.add_parameter(Parameter( volume.output_volume(), Type="String" )) volumes.append(ec2.MountPoint( VolumeId=Ref(volume_id), Device=Ref(device_name) )) instance = t.add_resource(ec2.Instance( '{}EC2Instance'.format(self.stack_name), Tags=Tags( Name=Ref(tag_name) ), ImageId=Ref(ami_param), Volumes=volumes, InstanceType=Ref(instance_type), IamInstanceProfile=Ref(instance_profile_param), NetworkInterfaces=self.network_interfaces, BlockDeviceMappings=[ ec2.BlockDeviceMapping( DeviceName=Ref(root_device_name), Ebs=ec2.EBSBlockDevice( VolumeSize=Ref(root_device_size), VolumeType=Ref(root_device_type), DeleteOnTermination=True ) ) ], UserData=Base64( Join('', [ "#!/bin/bash\n", "exec > >(tee /var/log/user-data.log|logger ", "-t user-data -s 2>/dev/console) 2>&1\n", ] + user_data )) )) if self.use_key: instance.KeyName = self.use_key if self.eip is not None: eip_ref = ensure_param(t, self.eip.output_allocation_id()) t.add_resource(ec2.EIPAssociation( '{}EIPAssoc'.format(self.stack_name), InstanceId=Ref(instance), AllocationId=Ref(eip_ref) )) t.add_output([ Output( '{}EC2Instance'.format(self.stack_name), Value=Ref(instance) ), Output( "{}TagName".format(self.stack_name), Value=Ref(tag_name) ) ]) return t
CidrIp=Ref(sshlocation_param), ), ], )) eth0 = template.add_resource( ec2.NetworkInterface( "Eth0", Description="eth0", GroupSet=[ Ref(ssh_sg), ], SourceDestCheck=True, SubnetId=Ref(subnetid_param), Tags=Tags( Name="Interface 0", Interface="eth0", ), SecondaryPrivateIpAddressCount=Ref(secondary_ip_param), )) eipassoc1 = template.add_resource( ec2.EIPAssociation( "EIPAssoc1", NetworkInterfaceId=Ref(eth0), AllocationId=GetAtt("EIP1", "AllocationId"), PrivateIpAddress=GetAtt("Eth0", "PrimaryPrivateIpAddress"), )) ec2_instance = template.add_resource( ec2.Instance("EC2Instance", ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"),
"SubnetCIDR", ConstraintDescription=( "must be a valid IP CIDR range of the form x.x.x.x/x."), Description="IP Address range for the VPN connected Subnet", Default="10.1.0.0/24", MinLength="9", AllowedPattern=r"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})", MaxLength="18", Type="String", )) PrivateNetworkAcl = t.add_resource( NetworkAcl("PrivateNetworkAcl", VpcId=Ref("VPC"), Tags=Tags( Application=Ref("AWS::StackName"), Network="Private", ))) PrivateRoute = t.add_resource( Route( "PrivateRoute", GatewayId=Ref("VPNGateway"), DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref("PrivateRouteTable"), )) VPNGatewayAttachment = t.add_resource( VPCGatewayAttachment( "VPNGatewayAttachment", VpcId=Ref("VPC"), VpnGatewayId=Ref("VPNGateway"),
def generate_template(d): # Set template metadata t = Template() t.add_version("2010-09-09") t.set_description(d["cf_template_description"]) # ref_stack_id = Ref('AWS::StackId') # ref_region = Ref('AWS::Region') # ref_stack_name = Ref('AWS::StackName') # Create VPC vpc = t.add_resource( VPC( "VPC", EnableDnsSupport=True, EnableDnsHostnames=True, CidrBlock=d["vpc_cidr_block"], Tags=Tags(d["tags"], {"Name": d["project_name"]}), ) ) # Create Public Subnets public_subnet_count = 1 public_subnets = [] az_count = 0 for public_subnet_cidr_block in d["public_subnet_cidr_blocks"]: public_subnets.append( t.add_resource( Subnet( "PublicSubnet" + str(public_subnet_count), CidrBlock=public_subnet_cidr_block, VpcId=Ref(vpc), AvailabilityZone=d["availability_zones"][az_count], Tags=Tags( d["tags"], { "Name": d["project_name"] + "-public-subnet" + str(public_subnet_count) }, ), ) ) ) public_subnet_count += 1 az_count += 1 # Create Private Subnets private_subnet_count = 1 private_subnets = [] az_count = 0 for private_subnet_cidr_block in d["private_subnet_cidr_blocks"]: private_subnets.append( t.add_resource( Subnet( "PrivateSubnet" + str(private_subnet_count), CidrBlock=private_subnet_cidr_block, VpcId=Ref(vpc), AvailabilityZone=d["availability_zones"][az_count], Tags=Tags( d["tags"], { "Name": d["project_name"] + "-private-subnet" + str(private_subnet_count) }, ), ) ) ) private_subnet_count += 1 az_count += 1 # Create Internet Gateway internetGateway = t.add_resource( InternetGateway( "InternetGateway", Tags=Tags( d["tags"], { "Name": d["project_name"] + "-igw" } ), ) ) # Attach Internet Gateway to VPC t.add_resource( VPCGatewayAttachment( "AttachmentInternetGateway", VpcId=Ref(vpc), InternetGatewayId=Ref(internetGateway), ) ) # Create Two EIP for each Nat Gateway eip_count = 1 for eip in range(2): t.add_resource( EIP( "Eip" + str(eip_count), Domain="vpc", Tags=Tags( d["tags"], { "Name": d["project_name"] + "-eip" + str(eip_count) } ), ) ) eip_count += 1 # Create Public Route Table publicRouteTable = t.add_resource( RouteTable( "PublicRouteTable", VpcId=Ref(vpc), Tags=Tags( d["tags"], { "Name": d["project_name"] + "-public-rtb" } ), ) ) # Create Route to Internet Gateway on Public Route Table t.add_resource( Route( "RouteIgw", DependsOn="AttachmentInternetGateway", GatewayId=Ref("InternetGateway"), DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref(publicRouteTable), ) ) # Create Private Route Table1 PrivateRouteTable1 = t.add_resource( RouteTable( "PrivateRouteTable1", VpcId=Ref(vpc), Tags=Tags( d["tags"], { "Name": d["project_name"] + "-private-rtb1" } ), ) ) # Create Private Route Table2 PrivateRouteTable2 = t.add_resource( RouteTable( "PrivateRouteTable2", VpcId=Ref(vpc), Tags=Tags( d["tags"], { "Name": d["project_name"] + "-private-rtb2" } ), ) ) # Associate Public Subnets with Public Route Table public_subnet_count = 1 for public_subnet in range(len(public_subnets)): t.add_resource( SubnetRouteTableAssociation( "PublicSubnetRouteTableAssociation" + str(public_subnet_count), SubnetId=Ref("PublicSubnet" + str(public_subnet_count)), RouteTableId=Ref(publicRouteTable), ) ) public_subnet_count += 1 # Associate Private Subnet1 with Private Route Table1 t.add_resource( SubnetRouteTableAssociation( "PrivateSubnetPrivateRouteTableAssociation1", SubnetId=Ref("PrivateSubnet1"), RouteTableId=Ref(PrivateRouteTable1), ) ) # Associate Private Subnet2 with Private Route Table2 t.add_resource( SubnetRouteTableAssociation( "PrivateSubnetPrivateRouteTableAssociation2", SubnetId=Ref("PrivateSubnet2"), RouteTableId=Ref(PrivateRouteTable2), ) ) # Create Two Nat Gateways one for each Private Route Table nat_gtw_count = 1 public_subnet_count = 1 for nat_gtw in range(2): t.add_resource( NatGateway( "Nat" + str(nat_gtw_count), AllocationId=GetAtt("Eip" + str(nat_gtw_count), "AllocationId"), SubnetId=Ref("PublicSubnet" + str(public_subnet_count)), Tags=Tags( d["tags"], { "Name": d["project_name"] + "-nat" + str(public_subnet_count) }, ), ) ) nat_gtw_count += 1 public_subnet_count += 1 # Create route in rtb1 to nat1 t.add_resource( Route( "RouteNat1", DependsOn="Nat1", NatGatewayId=Ref("Nat1"), DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref("PrivateRouteTable1"), ) ) # Create route in rtb2 to nat2 t.add_resource( Route( "RouteNat2", DependsOn="Nat2", NatGatewayId=Ref("Nat2"), DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref("PrivateRouteTable2"), ) ) # Outputs t.add_output( Output( "VPCId", Description="VPCId of the newly created VPC", Export=Export(Sub("${AWS::StackName}-VPCId")), Value=Ref(vpc), ) ) public_subnet_count = 1 count = 0 for subnet in public_subnets: t.add_output( Output( "PublicSubnet" + str(public_subnet_count), Description=f"PublicSubnetId{public_subnet_count}for cross reference.", Export=Export( Sub("${AWS::StackName}" + f"-PublicSubnetId{public_subnet_count}") ), Value=Ref(public_subnets[count]), ) ) count += 1 public_subnet_count += 1 private_subnet_count = 1 count = 0 for subnet in private_subnets: t.add_output( Output( "PrivateSubnet" + str(private_subnet_count), Description=f"PrivateSubnetId{private_subnet_count} for cross reference.", Export=Export( Sub("${AWS::StackName}" + f"-PrivateSubnetId{private_subnet_count}") ), Value=Ref(private_subnets[count]), ) ) count += 1 private_subnet_count += 1 return t
)) oam_api_token_param = t.add_parameter(Parameter( 'OAMAPIToken', Type='String', Description='OAM API Token' )) # # VPC # VPC = t.add_resource( ec2.VPC( 'VPC', CidrBlock='10.0.0.0/16', Tags=Tags( Application=ref_stack_id))) subnet = t.add_resource( ec2.Subnet( 'Subnet', AvailabilityZone='us-east-1a', CidrBlock='10.0.0.0/24', VpcId=Ref(VPC), Tags=Tags( Application=ref_stack_id))) internetGateway = t.add_resource( ec2.InternetGateway( 'InternetGateway', Tags=Tags( Application=ref_stack_id)))
def add_resources(self): self.EKSControlPlaneSG = self.template.add_resource( ec2.SecurityGroup( "EKSControlPlaneSG", GroupDescription= "Allow communication between WorkerNodes and EKS", VpcId=Ref(self.SharedServicesVpcId), Tags=self.base_tags + Tags(Name=self.environment_parameters["ClientEnvironmentKey"] + "-SS-EksControlPlane-SG"), )) self.EKSClusterRole = self.template.add_resource( Role( "EKSClusterRole", AssumeRolePolicyDocument=Policy(Statement=[ Statement(Effect=Allow, Action=[AssumeRole], Principal=Principal("Service", ["eks.amazonaws.com"])) ]), ManagedPolicyArns=[ "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy", "arn:aws:iam::aws:policy/AmazonEKSServicePolicy" ], )) self.EKSCluster = self.template.add_resource( eks.Cluster( "EKSCluster", DependsOn=["EKSControlPlaneSG", "EKSClusterRole"], Name=self.environment_parameters["ClientEnvironmentKey"] + "-SS-EKS", RoleArn=GetAtt(self.EKSClusterRole, "Arn"), Version=Ref(self.EksClusterVersion), ResourcesVpcConfig=eks.ResourcesVpcConfig( SecurityGroupIds=[Ref(self.EKSControlPlaneSG)], SubnetIds=[ Ref(self.SharedServicesPubSubnet1), Ref(self.SharedServicesPubSubnet2) ], ), )) self.WorkerNodeEc2SG = self.template.add_resource( ec2.SecurityGroup( "WorkerNodeEc2SG", DependsOn=["EKSCluster"], GroupDescription= "Allow communication between WorkerNodes and EKS", VpcId=Ref(self.SharedServicesVpcId), Tags=self.base_tags + Tags(Name=self.environment_parameters["ClientEnvironmentKey"] + "-SS-EksWorkerNodes-Ec2SG") + Tags({ "kubernetes.io/cluster/" + self.environment_parameters["ClientEnvironmentKey"] + "-SS-EKS": "owned" }), )) self.WorkerNodeInstanceRole = self.template.add_resource( Role( "WorkerNodeInstanceRole", AssumeRolePolicyDocument=Policy(Statement=[ Statement(Effect=Allow, Action=[AssumeRole], Principal=Principal("Service", ["ec2.amazonaws.com"])) ]), ManagedPolicyArns=[ "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy", "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy", "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" ], )) self.WorkerNodeInstanceProfile = self.template.add_resource( InstanceProfile( "WorkerNodeInstanceProfile", Path="/", Roles=[Ref(self.WorkerNodeInstanceRole)], )) self.WorkerNodeEc2SGIngress = self.template.add_resource( ec2.SecurityGroupIngress( "WorkerNodeEc2SGIngress", DependsOn=["WorkerNodeEc2SG"], GroupId=Ref(self.WorkerNodeEc2SG), IpProtocol="-1", FromPort=0, ToPort=65535, SourceSecurityGroupId=Ref(self.WorkerNodeEc2SG), )) self.WorkerNodeEc2SGIngressFromEKSControlPlane = self.template.add_resource( ec2.SecurityGroupIngress( "WorkerNodeEc2SGIngressFromEKSControlPlane", DependsOn=["WorkerNodeEc2SG"], GroupId=Ref(self.WorkerNodeEc2SG), IpProtocol="tcp", FromPort=1025, ToPort=65535, SourceSecurityGroupId=Ref(self.EKSControlPlaneSG), )) self.EksControlPlaneEgressToWorkerNodes = self.template.add_resource( ec2.SecurityGroupEgress( "EksControlPlaneEgressToWorkerNodes", DependsOn=["WorkerNodeEc2SG"], GroupId=Ref(self.EKSControlPlaneSG), IpProtocol="tcp", FromPort=1025, ToPort=65535, DestinationSecurityGroupId=Ref(self.WorkerNodeEc2SG), )) self.WorkerNodeEc2SG443IngressFromEKSControlPlane = self.template.add_resource( ec2.SecurityGroupIngress( "WorkerNodeEc2SG443IngressFromEKSControlPlane", DependsOn=["WorkerNodeEc2SG"], GroupId=Ref(self.WorkerNodeEc2SG), IpProtocol="tcp", FromPort=443, ToPort=443, SourceSecurityGroupId=Ref(self.EKSControlPlaneSG), )) self.EKSControlPlaneSG443IngressFromWorkerNode = self.template.add_resource( ec2.SecurityGroupIngress( "EKSControlPlaneSG443IngressFromWorkerNode", DependsOn=["WorkerNodeEc2SG"], GroupId=Ref(self.EKSControlPlaneSG), IpProtocol="tcp", FromPort=443, ToPort=443, SourceSecurityGroupId=Ref(self.WorkerNodeEc2SG), )) self.EksControlPlane443EgressToWorkerNodes = self.template.add_resource( ec2.SecurityGroupEgress( "EksControlPlane443EgressToWorkerNodes", DependsOn=["WorkerNodeEc2SG"], GroupId=Ref(self.EKSControlPlaneSG), IpProtocol="tcp", FromPort=443, ToPort=443, DestinationSecurityGroupId=Ref(self.WorkerNodeEc2SG), )) self.WorkerNodeLaunchConfiguration = self.template.add_resource( LaunchConfiguration( "WorkerNodeLaunchConfiguration", ImageId=Ref(self.WorkerNodeImageId), InstanceType=Ref(self.WorkerNodeInstanceType), IamInstanceProfile=Ref(self.WorkerNodeInstanceProfile), KeyName=Ref(self.WorkerNodeKeyName), SecurityGroups=[Ref(self.WorkerNodeEc2SG)], UserData=Base64( Join('', [ "#!/bin/bash \n", "set -o xtrace \n" "ClusterName=\"" + self.environment_parameters["ClientEnvironmentKey"] + "-SS-EKS" + "\" \n", "BootstrapArguments=\"" "\" \n", "/etc/eks/bootstrap.sh ${ClusterName} ${BootstrapArguments} \n" ])))) self.WorkerNodeAutoScalingGroup = self.template.add_resource( AutoScalingGroup( "WorkerNodeAutoscalingGroup", AutoScalingGroupName=self. environment_parameters["ClientEnvironmentKey"] + "-SS-EksWorkerNodeAutoScalingGroup", LaunchConfigurationName=Ref( self.WorkerNodeLaunchConfiguration), MaxSize=Ref(self.WorkerNodeASGGroupMaxSize), MinSize=Ref(self.WorkerNodeASGGroupMinSize), DesiredCapacity=Ref(self.WorkerNodeASGGroupDesiredSize), HealthCheckType=Ref(self.WorkerNodeASGHealthCheckType), HealthCheckGracePeriod=Ref( self.WorkerNodeASGHealthCheckGracePeriod), Cooldown=Ref(self.WorkerNodeASGCoolDown), VPCZoneIdentifier=[ Ref(self.SharedServicesPrivSubnet1), Ref(self.SharedServicesPrivSubnet2) ], Tags=[ AutoScalingTag( "Name", self.environment_parameters["ClientEnvironmentKey"] + "-SS-EKS" + "-WorkerNodeGroup-Node", True), AutoScalingTag( "kubernetes.io/cluster/" + self.environment_parameters["ClientEnvironmentKey"] + "-SS-EKS", "owned", True), AutoScalingTag( "Environment", self.environment_parameters["EnvironmentName"], True), AutoScalingTag( "ResourceOwner", self.environment_parameters["ResourceOwner"], True), AutoScalingTag( "ClientCode", self.environment_parameters["ClientEnvironmentKey"], True), ], ))
}] }, )) BatchInstanceProfile = t.add_resource( InstanceProfile( 'BatchInstanceProfile', Path='/', Roles=[Ref(BatchInstanceRole)], )) BatchSecurityGroup = t.add_resource( SecurityGroup('BatchSecurityGroup', VpcId=Ref(Vpc), GroupDescription='Enable access to Batch instances', Tags=Tags(Name='batch-sg'))) BatchComputeEnvironment = t.add_resource( ComputeEnvironment( 'BatchComputeEnvironment', Type='MANAGED', ServiceRole=Ref(BatchServiceRole), ComputeResources=ComputeResources( 'BatchComputeResources', Type='EC2', DesiredvCpus=0, MinvCpus=0, MaxvCpus=10, PlacementGroup="ExampleClusterGroup", InstanceTypes=['m4.large'], LaunchTemplate=LaunchTemplateSpecification(
'3AZCondition', Or(Equals(Ref(param_number_of_azs), '3'), Condition('4AZCondition'))) # # Resources # dhcp_options = t.add_resource( ec2.DHCPOptions('DHCPOptions', DomainNameServers=['AmazonProvidedDNS'])) vpc = t.add_resource( ec2.VPC('VPC', CidrBlock=Ref(param_vpc_cidr), EnableDnsSupport='true', EnableDnsHostnames='true', Tags=Tags(Name=Ref(AWS_STACK_NAME)))) dhcp_association = t.add_resource( ec2.VPCDHCPOptionsAssociation( 'VPCDHCPOptionsAssociation', VpcId=Ref(vpc), DhcpOptionsId=Ref(dhcp_options), )) internet_gateway = t.add_resource( ec2.InternetGateway('InternetGateway', Tags=Tags(Name=Ref(AWS_STACK_NAME)))) gateway_attachment = t.add_resource( ec2.VPCGatewayAttachment( 'VPCGatewayAttachment',
def __init__(self, keypair, availability_zones, vpc_cidr, home_cidrs, public_cidr, jump_image_id, jump_instance_type, nat_image_id, nat_instance_type, public_hosted_zone_name, private_hosted_zone_name, iam_instance_profile_arn, owner_emails, nat_highly_available, ec2_scheduled_shutdown, owner): """ Create a vpc, nat, jumphost, internet gateway, public/private route tables, public/private subnets and collection of Amazonia units AWS CloudFormation - http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html Troposphere - https://github.com/cloudtools/troposphere/blob/master/troposphere/ec2.py :param keypair: ssh keypair to be used throughout stack :param availability_zones: availability zones to use :param vpc_cidr: cidr pattern for vpc :param home_cidrs: a list of tuple objects of 'title'(0) and 'ip'(1) to be used to create ingress rules for ssh to jumpboxes from home/office/company premises :param public_cidr: a cidr to be treated as a public location. (eg 0.0.0.0/0) :param jump_image_id: AMI for jumphost :param jump_instance_type: instance type for jumphost :param nat_image_id: AMI for nat :param nat_instance_type: instance type for nat :param public_hosted_zone_name: A string containing the name of the Route 53 hosted zone to create public record sets in. :param private_hosted_zone_name: name of private hosted zone to create :param iam_instance_profile_arn: the ARN for an IAM instance profile that enables cloudtrail access for logging :param owner_emails: a list of emails for owners of this stack. Used for alerting. :param nat_highly_available: True/False for whether or not to use a series of NAT gateways or a single NAT :param ec2_scheduled_shutdown: True/False for whether to schedule shutdown for EC2 instances outside work hours """ super(Network, self).__init__() # set parameters self.keypair = keypair self.availability_zones = availability_zones self.vpc_cidr = vpc_cidr self.home_cidrs = home_cidrs self.public_cidr = public_cidr self.public_hosted_zone_name = public_hosted_zone_name self.private_hosted_zone_name = private_hosted_zone_name self.jump_image_id = jump_image_id self.jump_instance_type = jump_instance_type self.nat_image_id = nat_image_id self.nat_instance_type = nat_instance_type self.owner_emails = owner_emails if owner_emails else [] self.nat_highly_available = nat_highly_available self.iam_instance_profile_arn = iam_instance_profile_arn self.ec2_scheduled_shutdown = ec2_scheduled_shutdown self.owner = owner # initialize object references self.template = Template() self.private_subnets = [] self.public_subnets = [] self.public_subnet_mapping = {} self.vpc = None self.private_hosted_zone = None self.internet_gateway = None self.gateway_attachment = None self.public_route_table = None self.private_route_tables = {} self.nat = None self.nat_gateways = [] self.jump = None self.private_route = None self.public_route = None self.sns_topic = None # Add VPC and Internet Gateway with Attachment vpc_name = 'Vpc' self.vpc = Ref( self.template.add_resource( ec2.VPC(vpc_name, CidrBlock=self.vpc_cidr['cidr'], EnableDnsSupport='true', EnableDnsHostnames='true', Tags=Tags(Name=Join( '', [Ref('AWS::StackName'), '-', vpc_name]))))) self.private_hosted_zone = HostedZone(self.template, self.private_hosted_zone_name, vpcs=[self.vpc]) ig_name = 'Ig' self.internet_gateway = self.template.add_resource( ec2.InternetGateway( ig_name, Tags=Tags( Name=Join('', [Ref('AWS::StackName'), '-', ig_name])), DependsOn=vpc_name)) self.gateway_attachment = self.template.add_resource( ec2.VPCGatewayAttachment(self.internet_gateway.title + 'Atch', VpcId=self.vpc, InternetGatewayId=Ref( self.internet_gateway), DependsOn=self.internet_gateway.title)) # Add Public Route Table public_rt_name = 'PubRouteTable' self.public_route_table = self.template.add_resource( ec2.RouteTable( public_rt_name, VpcId=self.vpc, Tags=Tags(Name=Join( '', [Ref('AWS::StackName'), '-', public_rt_name])))) # Add Public and Private Subnets and Private Route Table for az in self.availability_zones: private_rt_name = get_cf_friendly_name(az) + 'PriRouteTable' private_route_table = self.template.add_resource( ec2.RouteTable( private_rt_name, VpcId=self.vpc, Tags=Tags(Name=Join( '', [Ref('AWS::StackName'), '-', private_rt_name])))) self.private_route_tables[az] = private_route_table self.private_subnets.append( Subnet(template=self.template, route_table=private_route_table, az=az, vpc=self.vpc, is_public=False, cidr=self.generate_subnet_cidr( is_public=False)).trop_subnet) public_subnet = Subnet( template=self.template, route_table=self.public_route_table, az=az, vpc=self.vpc, is_public=True, cidr=self.generate_subnet_cidr(is_public=True)).trop_subnet self.public_subnets.append(public_subnet) self.public_subnet_mapping[az] = Ref(public_subnet) self.sns_topic = SNS(self.template) for email in self.owner_emails: self.sns_topic.add_subscription(email, 'email') jump_config = SingleInstanceConfig( keypair=self.keypair, si_image_id=self.jump_image_id, si_instance_type=self.jump_instance_type, subnet=self.public_subnet_mapping[availability_zones[0]], vpc=self.vpc, public_hosted_zone_name=self.public_hosted_zone_name, instance_dependencies=self.gateway_attachment.title, iam_instance_profile_arn=self.iam_instance_profile_arn, is_nat=False, sns_topic=self.sns_topic, availability_zone=availability_zones[0], ec2_scheduled_shutdown=self.ec2_scheduled_shutdown, owner=self.owner) # Add Jumpbox and NAT and associated security group ingress and egress rules self.jump = SingleInstance(title='Jump', template=self.template, single_instance_config=jump_config) [ self.jump.add_ingress(sender=home_cidr, port='22') for home_cidr in self.home_cidrs ] self.jump.add_egress(receiver={ 'name': 'PublicIp', 'cidr': '0.0.0.0/0' }, port='-1') if self.nat_highly_available: for public_subnet in self.public_subnets: az = public_subnet.AvailabilityZone ip_address = self.template.add_resource( EIP(get_cf_friendly_name(az) + 'NatGwEip', DependsOn=self.gateway_attachment.title, Domain='vpc')) nat_gateway = self.template.add_resource( NatGateway(get_cf_friendly_name(az) + 'NatGw', AllocationId=GetAtt(ip_address, 'AllocationId'), SubnetId=Ref(public_subnet), DependsOn=self.gateway_attachment.title)) self.nat_gateways.append(nat_gateway) self.template.add_resource( ec2.Route(get_cf_friendly_name(az) + 'PriRoute', NatGatewayId=Ref(nat_gateway), RouteTableId=Ref(self.private_route_tables[az]), DestinationCidrBlock=self.public_cidr['cidr'], DependsOn=self.gateway_attachment.title)) else: nat_config = SingleInstanceConfig( keypair=self.keypair, si_image_id=self.nat_image_id, si_instance_type=self.nat_instance_type, subnet=self.public_subnet_mapping[availability_zones[0]], vpc=self.vpc, is_nat=True, instance_dependencies=self.gateway_attachment.title, iam_instance_profile_arn=self.iam_instance_profile_arn, public_hosted_zone_name=None, sns_topic=self.sns_topic, availability_zone=availability_zones[0], ec2_scheduled_shutdown=self.ec2_scheduled_shutdown, owner=self.owner) self.nat = SingleInstance(title='Nat', template=self.template, single_instance_config=nat_config) self.nat.add_egress(receiver=self.public_cidr, port='-1') self.nat.add_ingress(sender=self.vpc_cidr, port='-1') for az in self.availability_zones: self.template.add_resource( ec2.Route(get_cf_friendly_name(az) + 'PriRoute', InstanceId=Ref(self.nat.single), RouteTableId=Ref(self.private_route_tables[az]), DestinationCidrBlock=self.public_cidr['cidr'], DependsOn=self.gateway_attachment.title)) # Add Public Route self.public_route = self.template.add_resource( ec2.Route('PubRoute', GatewayId=Ref(self.internet_gateway), RouteTableId=Ref(self.public_route_table), DestinationCidrBlock=self.public_cidr['cidr'], DependsOn=self.gateway_attachment.title))
def buildInstance(t, args): t.add_resource( ec2.SecurityGroup('WebserverIngressSG', GroupDescription='Global Webserver Access', VpcId=Ref('VPC'), Tags=Tags(Name='Global Webserver Access'))) t.add_resource( ec2.SecurityGroupIngress('WebserverIngressSG80', GroupId=Ref('WebserverIngressSG'), IpProtocol='tcp', CidrIp='0.0.0.0/0', FromPort='80', ToPort='80')) t.add_resource( ec2.SecurityGroupIngress('WebserverIngress443', GroupId=Ref('WebserverIngressSG'), IpProtocol='tcp', CidrIp='0.0.0.0/0', FromPort='443', ToPort='443')) t.add_resource( ec2.SecurityGroup('SysAdminAccessSG', GroupDescription='System Administrator Access', VpcId=Ref('VPC'), Tags=Tags(Name='System Administrator Access'))) if (args.dev): t.add_resource( ec2.SecurityGroupIngress('DevSysadminIngress22', GroupId=Ref('SysAdminAccessSG'), IpProtocol='tcp', CidrIp='0.0.0.0/0', FromPort='22', ToPort='22')) rolePolicyStatements = [{ "Sid": "Stmt1500699052003", "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": [Join("", ["arn:aws:s3:::", Ref('S3Bucket')])] }, { "Sid": "Stmt1500699052000", "Effect": "Allow", "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject"], "Resource": [Join("", ["arn:aws:s3:::", Ref('S3Bucket'), '/Backup/*'])] }, { "Sid": "Stmt1500612724002", "Effect": "Allow", "Action": ["kms:Encrypt", "kms:Decrypt", "kms:GenerateDataKey*"], "Resource": [OpenEMRKeyARN] }] if (args.recovery): rolePolicyStatements.extend([ { "Sid": "Stmt1500699052004", "Effect": "Allow", "Action": ["s3:ListBucket"], "Resource": [Join( "", ["arn:aws:s3:::", Ref('RecoveryS3Bucket')])] }, { "Sid": "Stmt1500699052005", "Effect": "Allow", "Action": [ "s3:GetObject", ], "Resource": [ Join("", [ "arn:aws:s3:::", Ref('RecoveryS3Bucket'), '/Backup/*' ]) ] }, ]) t.add_resource( iam.ManagedPolicy('WebserverPolicy', Description='Policy for webserver instance', PolicyDocument={ "Version": "2012-10-17", "Statement": rolePolicyStatements })) t.add_resource( iam.Role('WebserverRole', AssumeRolePolicyDocument={ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Service": ["ec2.amazonaws.com"] }, "Action": ["sts:AssumeRole"] }] }, Path='/', ManagedPolicyArns=[Ref('WebserverPolicy')])) t.add_resource( iam.InstanceProfile('WebserverInstanceProfile', Path='/', Roles=[Ref('WebserverRole')])) t.add_resource( ec2.Volume('DockerVolume', DeletionPolicy='Delete' if args.dev else 'Snapshot', Size=Ref('PracticeStorage'), AvailabilityZone=Select("0", GetAZs("")), VolumeType='gp2', Encrypted=True, KmsKeyId=OpenEMRKeyID, Tags=Tags(Name="OpenEMR Practice"))) bootstrapScript = [ "#!/bin/bash -x\n", "exec > /var/log/openemr-cfn-bootstrap 2>&1\n", "cfn-init -v ", " --stack ", ref_stack_name, " --resource WebserverInstance ", " --configsets Setup ", " --region ", ref_region, "\n", "cfn-signal -e $? ", " --stack ", ref_stack_name, " --resource WebserverInstance ", " --region ", ref_region, "\n" ] setupScript = [ "#!/bin/bash -xe\n", "exec > /tmp/cloud-setup.log 2>&1\n", "/root/openemr-devops/packages/standard/ami/ami-configure.sh\n" ] stackPassthroughFile = [ "S3=", Ref('S3Bucket'), "\n", "KMS=", OpenEMRKeyID, "\n" ] if (args.recovery): stackPassthroughFile.extend([ "RECOVERYS3=", Ref('RecoveryS3Bucket'), "\n", "RECOVERY_NEWRDS=", GetAtt('RDSInstance', 'Endpoint.Address'), "\n", ]) if (args.recovery): dockerComposeFile = [ "version: '3.1'\n", "services:\n", " openemr:\n", " restart: always\n", " image: openemr/openemr", docker_version, "\n", " ports:\n", " - 80:80\n", " - 443:443\n", " volumes:\n", " - logvolume01:/var/log\n", " - sitevolume:/var/www/localhost/htdocs/openemr/sites\n", " environment:\n", " MANUAL_SETUP: 1\n", "volumes:\n", " logvolume01: {}\n", " sitevolume: {}\n" ] else: dockerComposeFile = [ "version: '3.1'\n", "services:\n", " openemr:\n", " restart: always\n", " image: openemr/openemr", docker_version, "\n", " ports:\n", " - 80:80\n", " - 443:443\n", " volumes:\n", " - logvolume01:/var/log\n", " - sitevolume:/var/www/localhost/htdocs/openemr/sites\n", " environment:\n", " MYSQL_HOST: '", GetAtt('RDSInstance', 'Endpoint.Address'), "'\n", " MYSQL_ROOT_USER: openemr\n", " MYSQL_ROOT_PASS: '******'RDSPassword'), "'\n", " MYSQL_USER: openemr\n", " MYSQL_PASS: '******'RDSPassword'), "'\n", " OE_USER: admin\n", " OE_PASS: '******'AdminPassword'), "'\n", "volumes:\n", " logvolume01: {}\n", " sitevolume: {}\n" ] bootstrapInstall = cloudformation.InitConfig( files={ "/root/cloud-setup.sh": { "content": Join("", setupScript), "mode": "000500", "owner": "root", "group": "root" }, "/root/cloud-variables": { "content": Join("", stackPassthroughFile), "mode": "000500", "owner": "root", "group": "root" }, "/root/openemr-devops/packages/standard/docker-compose.yaml": { "content": Join("", dockerComposeFile), "mode": "000500", "owner": "root", "group": "root" } }, commands={"01_setup": { "command": "/root/cloud-setup.sh" }}) bootstrapMetadata = cloudformation.Metadata( cloudformation.Init(cloudformation.InitConfigSets(Setup=['Install']), Install=bootstrapInstall)) t.add_resource( ec2.Instance('WebserverInstance', Metadata=bootstrapMetadata, ImageId=FindInMap('RegionData', ref_region, 'OpenEMRMktPlaceAMI'), InstanceType=Ref('WebserverInstanceSize'), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( AssociatePublicIpAddress=True, DeviceIndex="0", GroupSet=[ Ref('ApplicationSecurityGroup'), Ref('WebserverIngressSG'), Ref('SysAdminAccessSG') ], SubnetId=Ref('PublicSubnet1')) ], KeyName=Ref('EC2KeyPair'), IamInstanceProfile=Ref('WebserverInstanceProfile'), Volumes=[{ "Device": "/dev/sdd", "VolumeId": Ref('DockerVolume') }], Tags=Tags(Name='OpenEMR Cloud Standard'), InstanceInitiatedShutdownBehavior='stop', UserData=Base64(Join('', bootstrapScript)), CreationPolicy={"ResourceSignal": { "Timeout": "PT15M" }})) return t
' --region=', Ref('AWS::Region'), '\n', 'runas=root\n', ]), 'mode': '000400', 'owner': 'root', 'group': 'root', }, }, ), ), ), Tags=Tags(Name=Ref("AWS::StackName"), ), )) # Associate the Elastic IP separately, so it doesn't change when the instance changes. eip_assoc = template.add_resource( ec2.EIPAssociation( "EipAssociation", InstanceId=Ref(ec2_instance), EIP=Ref(eip), )) template.add_output([ Output( "PublicIP", Description= "Public IP address of Elastic IP associated with the Dokku instance",
def generate_template(service_name): t = Template() t.add_version('2010-09-09') t.add_description("""\ AWS CloudFormation Template for AWS Exploitation Lab """) t.add_mapping("PublicRegionMap", ami_public_mapping) t.add_mapping("PrivateRegionMap", ami_private_mapping) keyname_param = t.add_parameter( Parameter( 'KeyName', ConstraintDescription= 'must be the name of an existing EC2 KeyPair.', Description= 'Name of an existing EC2 KeyPair to enable SSH access to \ the instance', Type='AWS::EC2::KeyPair::KeyName', )) sshlocation_param = t.add_parameter( Parameter( 'SSHLocation', Description= ' The IP address range that can be used to SSH to the EC2 \ instances', Type='String', MinLength='9', MaxLength='18', Default='0.0.0.0/0', AllowedPattern= "(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})", ConstraintDescription=( "must be a valid IP CIDR range of the form x.x.x.x/x."), )) instanceType_param = t.add_parameter( Parameter( 'InstanceType', Type='String', Description='WebServer EC2 instance type', Default='t2.micro', AllowedValues=[ 't2.micro', 't2.small', 't2.medium', 'm3.medium', 'm3.large', 'm3.xlarge', 'm3.2xlarge', ], ConstraintDescription='must be a valid EC2 instance type.', )) ref_stack_id = Ref('AWS::StackId') ec2_role = t.add_resource( Role("%sEC2Role" % service_name, AssumeRolePolicyDocument=awacs.aws.Policy(Statement=[ awacs.aws.Statement( Effect=awacs.aws.Allow, Action=[awacs.aws.Action("sts", "AssumeRole")], Principal=awacs.aws.Principal("Service", ["ec2.amazonaws.com"])) ]))) ec2_role.ManagedPolicyArns = ["arn:aws:iam::aws:policy/ReadOnlyAccess"] ec2_snapshot_policy_document = awacs.aws.Policy(Statement=[ awacs.aws.Statement(Sid="PermitEC2Snapshots", Effect=awacs.aws.Allow, Action=[ awacs.aws.Action("ec2", "CreateSnapshot"), awacs.aws.Action("ec2", "ModifySnapshotAttribute"), ], Resource=["*"]) ]) ec2_snapshot_policy = Policy(PolicyName="EC2SnapshotPermissions", PolicyDocument=ec2_snapshot_policy_document) priv_ec2_role = t.add_resource( Role("%sPrivEC2Role" % service_name, AssumeRolePolicyDocument=awacs.aws.Policy(Statement=[ awacs.aws.Statement( Effect=awacs.aws.Allow, Action=[awacs.aws.Action("sts", "AssumeRole")], Principal=awacs.aws.Principal("Service", ["ec2.amazonaws.com"])) ]), Policies=[ec2_snapshot_policy])) priv_ec2_role.ManagedPolicyArns = [ "arn:aws:iam::aws:policy/ReadOnlyAccess" ] VPC_ref = t.add_resource( VPC('VPC', CidrBlock='10.0.0.0/16', Tags=Tags(Application=ref_stack_id))) instanceProfile = t.add_resource( InstanceProfile("InstanceProfile", InstanceProfileName="%sInstanceRole" % (service_name), Roles=[Ref(ec2_role)])) privInstanceProfile = t.add_resource( InstanceProfile("PrivInstanceProfile", InstanceProfileName="%sPrivInstanceRole" % (service_name), Roles=[Ref(priv_ec2_role)])) public_subnet = t.add_resource( Subnet('%sSubnetPublic' % service_name, MapPublicIpOnLaunch=True, CidrBlock='10.0.1.0/24', VpcId=Ref(VPC_ref), Tags=Tags(Application=ref_stack_id, Name="%sSubnet_public" % (service_name)))) private_subnet = t.add_resource( Subnet('%sSubnetPrivate' % service_name, MapPublicIpOnLaunch=False, CidrBlock='10.0.2.0/24', VpcId=Ref(VPC_ref), Tags=Tags(Application=ref_stack_id, Name="%sSubnet_private" % (service_name)))) internetGateway = t.add_resource( InternetGateway('InternetGateway', Tags=Tags(Application=ref_stack_id, Name="%sInternetGateway" % service_name))) gatewayAttachment = t.add_resource( VPCGatewayAttachment('AttachGateway', VpcId=Ref(VPC_ref), InternetGatewayId=Ref(internetGateway))) routeTable = t.add_resource( RouteTable('RouteTable', VpcId=Ref(VPC_ref), Tags=Tags(Application=ref_stack_id, Name="%sRouteTable" % service_name))) route = t.add_resource( Route( 'Route', DependsOn='AttachGateway', GatewayId=Ref('InternetGateway'), DestinationCidrBlock='0.0.0.0/0', RouteTableId=Ref(routeTable), )) # Only associate this Route Table with the public subnet subnetRouteTableAssociation = t.add_resource( SubnetRouteTableAssociation( 'SubnetRouteTableAssociation', SubnetId=Ref(public_subnet), RouteTableId=Ref(routeTable), )) instanceSecurityGroup = t.add_resource( SecurityGroup( 'InstanceSecurityGroup', GroupDescription='%sSecurityGroup' % service_name, SecurityGroupIngress=[ SecurityGroupRule(IpProtocol='tcp', FromPort='22', ToPort='22', CidrIp=Ref(sshlocation_param)), SecurityGroupRule(IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp='0.0.0.0/0'), SecurityGroupRule(IpProtocol='tcp', FromPort='1080', ToPort='1080', CidrIp='0.0.0.0/0'), SecurityGroupRule(IpProtocol='tcp', FromPort='443', ToPort='443', CidrIp='0.0.0.0/0'), SecurityGroupRule(IpProtocol='tcp', FromPort='0', ToPort='65535', CidrIp="10.0.0.0/8"), ], VpcId=Ref(VPC_ref), )) public_instance = t.add_resource( Instance( "Public%sInstance" % service_name, ImageId=FindInMap("PublicRegionMap", Ref("AWS::Region"), "AMI"), InstanceType=Ref(instanceType_param), KeyName=Ref(keyname_param), NetworkInterfaces=[ NetworkInterfaceProperty(GroupSet=[Ref(instanceSecurityGroup)], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(public_subnet)) ], UserData=Base64(public_instance_userdata), Tags=Tags(Application=ref_stack_id, Name='%sPublicInstance' % (service_name)))) private_instance = t.add_resource( Instance( "Private%sInstance" % service_name, ImageId=FindInMap("PrivateRegionMap", Ref("AWS::Region"), "AMI"), InstanceType=Ref(instanceType_param), KeyName=Ref(keyname_param), NetworkInterfaces=[ NetworkInterfaceProperty(GroupSet=[Ref(instanceSecurityGroup)], DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(private_subnet)) ], UserData=Base64(private_instance_userdata), Tags=Tags(Application=ref_stack_id, Name='%sPrivateInstance' % (service_name)), IamInstanceProfile="%sPrivInstanceRole" % (service_name))) outputs = [] outputs.append( Output( "PublicIP", Description="IP Address of Public Instance", Value=GetAtt(public_instance, "PublicIp"), )) t.add_output(outputs) # Set up S3 Bucket and CloudTrail S3Bucket = t.add_resource(Bucket("S3Bucket", DeletionPolicy="Retain")) S3PolicyDocument = awacs.aws.PolicyDocument( Id='EnforceServersideEncryption', Version='2012-10-17', Statement=[ awacs.aws.Statement( Sid='PermitCTBucketPut', Action=[s3.PutObject], Effect=awacs.aws.Allow, Principal=awacs.aws.Principal("Service", ["cloudtrail.amazonaws.com"]), Resource=[Join('', [s3.ARN(''), Ref(S3Bucket), "/*"])], ), awacs.aws.Statement( Sid='PermitCTBucketACLRead', Action=[s3.GetBucketAcl], Effect=awacs.aws.Allow, Principal=awacs.aws.Principal("Service", ["cloudtrail.amazonaws.com"]), Resource=[Join('', [s3.ARN(''), Ref(S3Bucket)])], ) ]) S3BucketPolicy = t.add_resource( BucketPolicy("BucketPolicy", PolicyDocument=S3PolicyDocument, Bucket=Ref(S3Bucket), DependsOn=[S3Bucket])) myTrail = t.add_resource( Trail( "CloudTrail", IsLogging=True, S3BucketName=Ref(S3Bucket), DependsOn=["BucketPolicy"], )) myTrail.IsMultiRegionTrail = True myTrail.IncludeGlobalServiceEvents = True return t.to_json()
from troposphere import Parameter, Tags stackconfig = StackConfig() mystack = Stack(stackconfig) mystack.description('ElasticSearch Stack') parameters = { "env": Parameter( "DeploymentEnvironment", Type="String", Default="DEV", Description="Environment you are building (DEV,QA,STG,PROD)", ), "ver": Parameter( "ProductVersion", Type="String", Default="6.1", Description="Version deploying (e.g. 6.1)", ) } common_tags = Tags(env=Ref("DeploymentEnvironment"), Version=Ref("ProductVersion")) for p in parameters.values(): mystack.template.add_parameter(p) mystack.elasticsearch_cluster('elasticsearch')
def create_network(self): t = self.template self.create_gateway() vpc_id = Ref("VPC") t.add_resource(ec2.NetworkAcl('DefaultACL', VpcId=vpc_id)) self.create_nat_security_groups() subnets = {'public': [], 'private': []} net_types = subnets.keys() zones = [] for i in range(self.local_parameters["AZCount"]): az = Select(i, GetAZs("")) zones.append(az) name_suffix = i for net_type in net_types: name_prefix = net_type.capitalize() subnet_name = "%sSubnet%s" % (name_prefix, name_suffix) subnets[net_type].append(subnet_name) t.add_resource(ec2.Subnet( subnet_name, AvailabilityZone=az, VpcId=vpc_id, DependsOn=GW_ATTACH, CidrBlock=Select(i, Ref("%sSubnets" % name_prefix)), Tags=Tags(type=net_type))) route_table_name = "%sRouteTable%s" % (name_prefix, name_suffix) t.add_resource(ec2.RouteTable( route_table_name, VpcId=vpc_id, Tags=[ec2.Tag('type', net_type)])) t.add_resource(ec2.SubnetRouteTableAssociation( "%sRouteTableAssociation%s" % (name_prefix, name_suffix), SubnetId=Ref(subnet_name), RouteTableId=Ref(route_table_name))) if net_type == 'public': # the public subnets are where the NAT instances live, # so their default route needs to go to the AWS # Internet Gateway t.add_resource(ec2.Route( "%sRoute%s" % (name_prefix, name_suffix), RouteTableId=Ref(route_table_name), DestinationCidrBlock="0.0.0.0/0", GatewayId=Ref(GATEWAY))) self.create_nat_instance(i, subnet_name) else: # Private subnets are where actual instances will live # so their gateway needs to be through the nat instances t.add_resource(ec2.Route( '%sRoute%s' % (name_prefix, name_suffix), RouteTableId=Ref(route_table_name), DestinationCidrBlock='0.0.0.0/0', InstanceId=Ref(NAT_INSTANCE_NAME % name_suffix))) for net_type in net_types: t.add_output(Output( "%sSubnets" % net_type.capitalize(), Value=Join(",", [Ref(sn) for sn in subnets[net_type]]))) self.template.add_output(Output( "AvailabilityZones", Value=Join(",", zones)))
Type="String", Default="10.0.12.0/22", AllowedPattern=PRIVATE_IPV4_CIDR_REGEX, ConstraintDescription=PRIVATE_IPV4_CONSTRAINT, ), group="Global", label="Private Subnet B CIDR Block", ) vpc = VPC( "Vpc", template=template, CidrBlock=Ref(vpc_cidr), EnableDnsSupport=True, EnableDnsHostnames=True, Tags=Tags(Name=Join("-", [Ref("AWS::StackName"), "vpc"]), ), ) # Allow outgoing to outside VPC internet_gateway = InternetGateway( "InternetGateway", template=template, Tags=Tags(Name=Join("-", [Ref("AWS::StackName"), "igw"]), ), ) # Attach Gateway to VPC VPCGatewayAttachment( "GatewayAttachement", template=template, VpcId=Ref(vpc), InternetGatewayId=Ref(internet_gateway),
cfg = yaml.load(resource_string('cloudformation.config', 'kinesis_firehose_s3.yml')) STACK_NAME = cfg['stack_name'] template = Template() description = 'Stack containing kinesis and firehose writing to S3' template.add_description(description) # AWSTemplateFormatVersion template.add_version('2010-09-09') kinesis_stream = template.add_resource( kinesis.Stream('DevStream', Name=cfg['kinesis_stream_name'], ShardCount=cfg['kinesis_shard_count'], Tags=Tags( StackName=Ref('AWS::StackName'), Name='DevStream' ) ) ) firehose_delivery_role = template.add_resource( iam.Role( 'FirehoseRole', AssumeRolePolicyDocument={ 'Statement': [{ 'Effect': 'Allow', 'Principal': { 'Service': [ 'firehose.amazonaws.com' ] },
def set_up_stack(self): """Sets up the stack""" if not self.INPUTS or not self.STACK_NAME_PREFIX or not self.HEALTH_ENDPOINT: raise MKInputError( 'Must define INPUTS, STACK_NAME_PREFIX, and HEALTH_ENDPOINT') super(AppServerStack, self).set_up_stack() tags = self.get_input('Tags').copy() self.add_description('{} App Server Stack for Cac'.format( self.STACK_NAME_PREFIX)) assert isinstance(tags, dict), 'tags must be a dictionary' self.availability_zones = get_availability_zones() tags.update({'StackType': 'AppServer'}) self.default_tags = tags self.app_server_instance_type_parameter = self.add_parameter( Parameter( 'AppServerInstanceType', Type='String', Default='t2.medium', Description='NAT EC2 instance type', AllowedValues=EC2_INSTANCE_TYPES, ConstraintDescription='must be a valid EC2 instance type.'), source='AppServerInstanceType') self.param_app_server_iam_profile = self.add_parameter( Parameter('AppServerIAMProfile', Type='String', Description='IAM Profile for instances'), source='AppServerIAMProfile') self.app_server_ami = self.add_parameter(Parameter( 'AppServerAMI', Type='String', Description='{} Server EC2 AMI'.format(self.STACK_NAME_PREFIX)), source='AppServerAMI') self.keyname_parameter = self.add_parameter(Parameter( 'KeyName', Type='String', Default='cac', Description='Name of an existing EC2 key pair'), source='KeyName') self.param_color = self.add_parameter(Parameter( 'StackColor', Type='String', Description='Stack color', AllowedValues=['Blue', 'Green', 'Orange']), source='StackColor') self.param_stacktype = self.add_parameter(Parameter( 'StackType', Type='String', Description='Stack type', AllowedValues=['Development', 'Staging', 'Production']), source='StackType') self.param_public_hosted_zone_name = self.add_parameter( Parameter('PublicHostedZoneName', Type='String', Description='Public hosted zone name'), source='PublicHostedZoneName') self.param_vpc = self.add_parameter(Parameter( 'VpcId', Type='String', Description='Name of an existing VPC'), source='VpcId') self.param_notification_arn = self.add_parameter( Parameter( 'GlobalNotificationsARN', Type='String', Description='Physical resource ID on an AWS::SNS::Topic for ' 'notifications'), source='GlobalNotificationsARN') self.param_ssl_certificate_arn = self.add_parameter( Parameter('SSLCertificateARN', Type='String', Description= 'Physical resource ID on an AWS::IAM::ServerCertificate ' 'for the application server load balancer'), source='SSLCertificateARN') self.param_public_subnets = self.add_parameter( Parameter('PublicSubnets', Type='CommaDelimitedList', Description='A list of public subnets'), source='AppServerPublicSubnets') self.param_private_subnets = self.add_parameter( Parameter('PrivateSubnets', Type='CommaDelimitedList', Description='A list of private subnets'), source='AppServerPrivateSubnets') self.param_bastion_security_group = self.add_parameter( Parameter('BastionSecurityGroup', Type='String', Description='The ID of the bastion security group'), source='BastionSecurityGroup') self.param_database_security_group = self.add_parameter( Parameter('DatabaseSecurityGroup', Type='String', Description='The ID of the database security group'), source='DatabaseSecurityGroup') self.param_nat_security_group = self.add_parameter( Parameter('NATSecurityGroup', Type='String', Description='The ID of the NAT security group'), source='NATSecurityGroup') self.param_min_size = self.add_parameter(Parameter( 'ASGMinSize', Type='Number', Default='1', Description='Min size of ASG'), source='ASGMinSize') self.param_max_size = self.add_parameter(Parameter( 'ASGMaxSize', Type='Number', Default='1', Description='Max size of ASG'), source='ASGMaxSize') self.param_desired_capacity = self.add_parameter( Parameter('ASGDesiredCapacity', Type='Number', Default='1', Description='Desired capacity of ASG'), source='ASGDesiredCapacity') # # Security Group # app_server_load_balancer_security_group = self.add_resource( ec2.SecurityGroup( 'sgAppServerLoadBalancer', GroupDescription= 'Enables access to app servers via a load balancer', VpcId=Ref(self.param_vpc), SecurityGroupIngress=[ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=ALLOW_ALL_CIDR, FromPort=p, ToPort=p) for p in [80, 443] ], Tags=Tags(Name='sgAppServerLoadBalancer', Color=Ref(self.param_color)))) app_server_security_group = self.add_resource( ec2.SecurityGroup( 'sgAppServer', GroupDescription='Enables access to App Servers', VpcId=Ref(self.param_vpc), SecurityGroupIngress=[ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=VPC_CIDR, FromPort=p, ToPort=p) for p in [22, 80, 443] ] + [ ec2.SecurityGroupRule(IpProtocol='tcp', SourceSecurityGroupId=Ref(sg), FromPort=80, ToPort=80) for sg in [app_server_load_balancer_security_group] ] + [ ec2.SecurityGroupRule(IpProtocol='tcp', SourceSecurityGroupId=Ref(sg), FromPort=443, ToPort=443) for sg in [app_server_load_balancer_security_group] ], SecurityGroupEgress=[ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=ALLOW_ALL_CIDR, FromPort=p, ToPort=p) for p in [80, 443, PAPERTRAIL_PORT] ], Tags=Tags(Name='sgAppServer', Color=Ref(self.param_color)))) # ELB to App Server self.add_resource( ec2.SecurityGroupEgress( 'sgEgressELBtoAppHTTP', GroupId=Ref(app_server_load_balancer_security_group), DestinationSecurityGroupId=Ref(app_server_security_group), IpProtocol='tcp', FromPort=80, ToPort=80)) self.add_resource( ec2.SecurityGroupEgress( 'sgEgressELBtoAppHTTPS', GroupId=Ref(app_server_load_balancer_security_group), DestinationSecurityGroupId=Ref(app_server_security_group), IpProtocol='tcp', FromPort=443, ToPort=443)) # Bastion to App Server, app server to db, app server to inet rules = [(self.param_bastion_security_group, app_server_security_group, [80, 443, 22]), (app_server_security_group, self.param_database_security_group, [POSTGRES]), (app_server_security_group, self.param_nat_security_group, [80, 443, 22, 587, PAPERTRAIL_PORT])] for num, (srcsg, destsg, ports) in enumerate(rules): for port in ports: self.add_resource( ec2.SecurityGroupEgress( 'sgEgress{}p{}'.format(num, port), GroupId=Ref(srcsg), DestinationSecurityGroupId=Ref(destsg), IpProtocol='tcp', FromPort=port, ToPort=port)) self.add_resource( ec2.SecurityGroupIngress('sgIngress{}p{}'.format( num, port), GroupId=Ref(destsg), SourceSecurityGroupId=Ref(srcsg), IpProtocol='tcp', FromPort=port, ToPort=port)) # # ELB # app_server_load_balancer = self.add_resource( elb.LoadBalancer( 'elbAppServer', ConnectionDrainingPolicy=elb.ConnectionDrainingPolicy( Enabled=True, Timeout=300), CrossZone=True, SecurityGroups=[Ref(app_server_load_balancer_security_group)], Listeners=[ elb.Listener(LoadBalancerPort='80', Protocol='HTTP', InstancePort='80', InstanceProtocol='HTTP'), elb.Listener(LoadBalancerPort='443', Protocol='HTTPS', InstancePort='443', InstanceProtocol='HTTP', SSLCertificateId=Ref( self.param_ssl_certificate_arn)) ], HealthCheck=elb.HealthCheck( Target=self.HEALTH_ENDPOINT, HealthyThreshold='3', UnhealthyThreshold='2', Interval='30', Timeout='5', ), Subnets=Ref(self.param_public_subnets), Tags=Tags(Name='elbAppServer', Color=Ref(self.param_color)))) self.add_resource( cw.Alarm('alarmAppServerBackend4xx', AlarmActions=[Ref(self.param_notification_arn)], Statistic='Sum', Period=300, Threshold='5', EvaluationPeriods=1, ComparisonOperator='GreaterThanThreshold', MetricName='HTTPCode_Backend_4XX', Namespace='AWS/ELB', Dimensions=[ cw.MetricDimension( 'metricLoadBalancerName', Name='LoadBalancerName', Value=Ref(app_server_load_balancer)) ])) self.add_resource( cw.Alarm('alarmAppServerBackend5xx', AlarmActions=[Ref(self.param_notification_arn)], Statistic='Sum', Period=60, Threshold='0', EvaluationPeriods=1, ComparisonOperator='GreaterThanThreshold', MetricName='HTTPCode_Backend_5XX', Namespace='AWS/ELB', Dimensions=[ cw.MetricDimension( 'metricLoadBalancerName', Name='LoadBalancerName', Value=Ref(app_server_load_balancer)) ])) # # ASG # app_server_launch_config = self.add_resource( asg.LaunchConfiguration( 'lcAppServer', ImageId=Ref(self.app_server_ami), IamInstanceProfile=Ref(self.param_app_server_iam_profile), InstanceType=Ref(self.app_server_instance_type_parameter), KeyName=Ref(self.keyname_parameter), SecurityGroups=[Ref(app_server_security_group)])) autoscaling_group = self.add_resource( asg.AutoScalingGroup( 'asgAppServer', AvailabilityZones=self.get_input( 'AppServerAvailabilityZones').split(','), Cooldown=300, DesiredCapacity=Ref(self.param_desired_capacity), HealthCheckGracePeriod=1000, HealthCheckType='ELB', LaunchConfigurationName=Ref(app_server_launch_config), LoadBalancerNames=[Ref(app_server_load_balancer)], MaxSize=Ref(self.param_max_size), MinSize=Ref(self.param_min_size), NotificationConfigurations=[ asg.NotificationConfigurations( TopicARN=Ref(self.param_notification_arn), NotificationTypes=[ asg.EC2_INSTANCE_LAUNCH, asg.EC2_INSTANCE_LAUNCH_ERROR, asg.EC2_INSTANCE_TERMINATE, asg.EC2_INSTANCE_TERMINATE_ERROR ]) ], VPCZoneIdentifier=Ref(self.param_private_subnets), Tags=[ asg.Tag('Name', '{}Server'.format(self.STACK_NAME_PREFIX), True), asg.Tag('Color', Ref(self.param_color), True) ])) # autoscaling policies autoscaling_policy_add = self.add_resource( asg.ScalingPolicy('scalingPolicyAddAppServer', AdjustmentType='ChangeInCapacity', AutoScalingGroupName=Ref(autoscaling_group), Cooldown=600, ScalingAdjustment='1')) autoscaling_policy_remove = self.add_resource( asg.ScalingPolicy('scalingPolicyRemoveAppServer', AdjustmentType='ChangeInCapacity', AutoScalingGroupName=Ref(autoscaling_group), Cooldown=600, ScalingAdjustment='-1')) if self.STACK_NAME_PREFIX == 'Otp': # trigger scale down if CPU avg usage < 10% for 3 consecutive 5 min periods self.add_resource( cw.Alarm('alarmAppServerLowCPU', AlarmActions=[Ref(autoscaling_policy_remove)], Statistic='Average', Period=300, Threshold='10', EvaluationPeriods=3, ComparisonOperator='LessThanThreshold', MetricName='CPUUtilization', Namespace='AWS/EC2', Dimensions=[ cw.MetricDimension('metricAutoScalingGroupName', Name='AutoScalingGroupName', Value=Ref(autoscaling_group)) ])) # trigger scale up if CPU avg usage >= 30% for a 5 min period self.add_resource( cw.Alarm('alarmAppServerHighCPU', AlarmActions=[ Ref(self.param_notification_arn), Ref(autoscaling_policy_add) ], Statistic='Average', Period=300, Threshold='30', EvaluationPeriods=1, ComparisonOperator='GreaterThanOrEqualToThreshold', MetricName='CPUUtilization', Namespace='AWS/EC2', Dimensions=[ cw.MetricDimension('metricAutoScalingGroupName', Name='AutoScalingGroupName', Value=Ref(autoscaling_group)) ])) else: # scale web servers based on network usage self.add_resource( cw.Alarm('alarmAppServerLowNetworkUsage', AlarmActions=[Ref(autoscaling_policy_remove)], Statistic='Average', Period=300, Threshold='4000000', EvaluationPeriods=3, ComparisonOperator='LessThanThreshold', MetricName='NetworkOut', Namespace='AWS/EC2', Dimensions=[ cw.MetricDimension('metricAutoScalingGroupName', Name='AutoScalingGroupName', Value=Ref(autoscaling_group)) ])) self.add_resource( cw.Alarm('alarmAppServerHighNetworkUsage', AlarmActions=[ Ref(self.param_notification_arn), Ref(autoscaling_policy_add) ], Statistic='Average', Period=300, Threshold='10000000', EvaluationPeriods=1, ComparisonOperator='GreaterThanOrEqualToThreshold', MetricName='NetworkOut', Namespace='AWS/EC2', Dimensions=[ cw.MetricDimension('metricAutoScalingGroupName', Name='AutoScalingGroupName', Value=Ref(autoscaling_group)) ])) # # DNS name # self.create_resource( route53.RecordSetType( 'dnsName', Name=Join('.', [ Ref(self.param_color), Ref(self.param_stacktype), self.STACK_NAME_PREFIX, Ref(self.param_public_hosted_zone_name) ]), Type='A', AliasTarget=route53.AliasTarget( GetAtt(app_server_load_balancer, 'CanonicalHostedZoneNameID'), GetAtt(app_server_load_balancer, 'DNSName')), HostedZoneName=Ref(self.param_public_hosted_zone_name))) self.add_output([ Output('{}ServerLoadBalancerEndpoint'.format( self.STACK_NAME_PREFIX), Description='Application server endpoint', Value=GetAtt(app_server_load_balancer, 'DNSName')), Output('{}ServerLoadBalancerHostedZoneNameID'.format( self.STACK_NAME_PREFIX), Description='ID of canonical hosted zone name for ELB', Value=GetAtt(app_server_load_balancer, 'CanonicalHostedZoneNameID')) ])
def test_tags_from_dict(self): d = {"key1": "value1", "key2": "value2"} expected = [{"Key": k, "Value": v} for k, v in d.items()] tags = Tags.from_dict(**d) self.assertEquals(sorted(expected), sorted(tags.tags))
def test_Unsortable(self): result = [{"Key": {"Fn::Sub": "somestring"}, "Value": "val"}] tags = Tags({Sub("somestring"): "val"}) self.assertEqual(tags.to_dict(), result)