Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
    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")
Exemplo n.º 3
0
    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")
Exemplo n.º 4
0
 def test_Unsortable(self):
     result = [{'Key': {'Fn::Sub': 'somestring'}, 'Value': 'val'}]
     tags = Tags({Sub('somestring'): 'val'})
     self.assertEqual(tags.to_dict(), result)
Exemplo n.º 5
0
    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),
))
Exemplo n.º 6
0
             # 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 = {
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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"),
Exemplo n.º 9
0
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)]),
Exemplo n.º 10
0
    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"]
Exemplo n.º 11
0
    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"),
Exemplo n.º 13
0
        "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"),
Exemplo n.º 14
0
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
Exemplo n.º 15
0
))

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),
                ],
            ))
Exemplo n.º 17
0
            }]
        },
    ))

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',
Exemplo n.º 19
0
    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))
Exemplo n.º 20
0
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
Exemplo n.º 21
0
                                    ' --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",
Exemplo n.º 22
0
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()
Exemplo n.º 23
0
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')
Exemplo n.º 24
0
    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)))
Exemplo n.º 25
0
        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'
                    ]
                },
Exemplo n.º 27
0
    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'))
        ])
Exemplo n.º 28
0
    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))
Exemplo n.º 29
0
 def test_Unsortable(self):
     result = [{"Key": {"Fn::Sub": "somestring"}, "Value": "val"}]
     tags = Tags({Sub("somestring"): "val"})
     self.assertEqual(tags.to_dict(), result)