def create_nat(self, availability_zone, public_subnet, private_route_table): """Create a NAT instance and attach it to a private subnet with a private route Args: availabilty_zone (AvailabilityZone): where to place the NAT device public_subnet (ec2.Subnet): subnet to place the NAT device private_route_table (ec2.RouteTable): RouteTable to attach NAT device """ nat_device_name = '{}NATDevice'.format(availability_zone.cfn_name) nat_device = self.create_resource( ec2.Instance(nat_device_name, InstanceType=Ref(self.nat_instance_type_parameter), KeyName=Ref(self.keyname_parameter), SourceDestCheck=False, ImageId=Ref(self.nat_instance_ami_parameter), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( Description='ENI for NATDevice', GroupSet=[Ref(self.nat_security_group)], SubnetId=Ref(public_subnet), AssociatePublicIpAddress=True, DeviceIndex=0, DeleteOnTermination=True, ) ], Tags=self.get_tags(Name=nat_device_name))) self.create_resource( ec2.Route('{}PrivateRoute'.format(availability_zone.cfn_name), RouteTableId=Ref(private_route_table), DestinationCidrBlock=ALLOW_ALL_CIDR, InstanceId=Ref(nat_device)))
def agent_instance(self, index): user_data = dedent(''' {common} apt-get -y install gcc apt-get -y install libpcap-dev # install pdk go get -u github.com/pilosa/pdk cd $GOPATH/src/github.com/pilosa/pdk make install # clean up root's mess chown -R {username}:{username} /home/{username} '''[1:]).format(common=self.common_user_data, username=self.username) return ec2.Instance( 'PilosaAgentInstance{}'.format(index), ImageId=Ref(self.ami), InstanceType=Ref(self.agent_instance_type), KeyName=Ref(self.key_pair), IamInstanceProfile=Ref(self.instance_profile), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( GroupSet=[Ref(self.instance_security_group.title)], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(self.subnet))], UserData=Base64(Sub(user_data)), )
def add_resource_and_output(self): """Add resources to template.""" template = self.template variables = self.get_variables() networkinterfaces = [] for di, netintid in variables['NetworkInterfaces'].iteritems(): networkinterfaces.append( ec2.NetworkInterfaceProperty(DeviceIndex=di, NetworkInterfaceId=netintid)) ec2instance = template.add_resource( ec2.Instance( 'PaEc2Instance', DisableApiTermination='true', # s4f # IamInstanceProfile=variables['InstanceProfile'].ref, ImageId=FindInMap('PaAmiRegionMap', Ref('AWS::Region'), 'AMI'), InstanceType=variables['InstanceType'].ref, KeyName=variables['KeyName'].ref, Monitoring=variables['DetailedMonitoring'].ref, NetworkInterfaces=networkinterfaces, Tags=Tags(variables['Tags']), Tenancy=variables['PlacementTenancy'].ref, )) template.add_output( Output('{}Id'.format(ec2instance.title), Description='ID of EC2 Instance created', Export=Export( Sub('${AWS::StackName}-%sId' % ec2instance.title)), Value=Ref(ec2instance)))
def define_network_interface_property(self, _int_config): interface = ec2.NetworkInterfaceProperty(_int_config["name"]) interface.SubnetId = Ref(_int_config["subnet"]) interface.AssociatePublicIpAddress = _int_config["is_public"] interface.DeviceIndex = str(_int_config["index"]) return interface
def create_network_interface(self, assign_public_ip, subnet, security_groups, device_index=0, private_ip=False): """ Creates a network interface :param assign_public_ip: Boolean - whether or not to assign a public address :param subnet: Subnet to associate this interface to :param security_groups: SGs to associate the interface to :param device_index: Device Index, if applicable :param private_ip: Boolean - whether or not to assign a private IP :return: Network Interface CFN object """ network_interface = ec2.NetworkInterfaceProperty( AssociatePublicIpAddress=assign_public_ip, SubnetId=subnet, GroupSet=security_groups, DeviceIndex=device_index, ) if private_ip: network_interface.PrivateIpAddress = private_ip return network_interface
def add_ec2(self, name, subnet, security_groups, keypair, image_id, instance_type, network_interfaces=False, disable_api_termination=False, instance_profile='', userdata='', metadata=False): """ Creates an EC2 instance :param name: Name of the instance :param subnet: Subnet in which to place the instance :param security_groups: SG(s) list to assign :param keypair: Key pair to load onto the EC2 :param image_id: AMI ID to spin it up from :param instance_type: Instance type :param network_interfaces: ENIs (boolean) :param disable_api_termination: Whether or not to enable termination protection :param instance_profile: IAM instance profile :param userdata: Any userdata :param metadata: Any metadata :return: EC2 Instance CFN object """ if not network_interfaces: network_interface_config = [ ec2.NetworkInterfaceProperty( AssociatePublicIpAddress=False, SubnetId=subnet, GroupSet=security_groups, DeviceIndex=0, ) ] else: network_interface_config = network_interfaces instance = ec2.Instance(name, ImageId=image_id, InstanceType=instance_type, DisableApiTermination=disable_api_termination, IamInstanceProfile=instance_profile, KeyName=keypair, NetworkInterfaces=network_interface_config, UserData=userdata, SourceDestCheck=False, Tags=[{ 'Key': 'Name', 'Value': name }]) if metadata: instance.Metadata = metadata self.template.add_resource(instance) return instance
def create_nat(self, availability_zone, public_subnet, private_route_table): # NOQA nat_device_name = '{}NATDevice'.format(availability_zone.cfn_name) nat_device = self.create_resource( ec2.Instance(nat_device_name, InstanceType=Ref(self.nat_instance_type), KeyName=Ref(self.keyname), SourceDestCheck=False, ImageId=Ref(self.nat_instance_ami), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( Description='ENI for NATDevice', GroupSet=[Ref(self.nat_security_group)], SubnetId=Ref(public_subnet), AssociatePublicIpAddress=True, DeviceIndex=0, DeleteOnTermination=True, ) ], Tags=self.get_tags(Name=nat_device_name))) self.create_resource( ec2.Route('{}PrivateRoute'.format(availability_zone.cfn_name), RouteTableId=Ref(private_route_table), DestinationCidrBlock=ALLOW_ALL_CIDR, InstanceId=Ref(nat_device)))
def add_nodes(t, nodes, prefix): nodes_list = [] for x in range(0, nodes): node_name = prefix + "Node" + str((x + 1)) t.add_resource( ec2.Instance(node_name, ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"), InstanceType=Ref("InstanceType"), KeyName=Ref("KeyName"), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( AssociatePublicIpAddress=False, GroupSet=[Ref("QumuloSecurityGroup")], DeviceIndex=0, DeleteOnTermination=True, SubnetId=Ref("SubnetId"), ) ])) nodes_list.append(node_name) # Create a list containing the Private IPs of all nodes. output_ips = [] for i in nodes_list: output_ips.append(GetAtt(i, "PrivateIp")) t.add_output( Output( "ClusterPrivateIPs", Description= "Copy and paste this list into the QF2 Cluster Creation Screen", Value=Join(", ", output_ips), )) t.add_output( Output( "LinkToManagement", Description="Click to launch the QF2 Admin Console", Value=Join( "", ["https://", GetAtt(nodes_list[0], "PrivateIp")]), )) t.add_output( Output( "InstanceId", Description= "Copy and paste this instance ID into the QF2 Cluster Creation Screen.", Value=Ref(prefix + "Node1"), ))
def create_bastion(self): """Create Bastion host and security group Creates a bastion instance and security group to allow access from the office for SSH and monitoring UIs (note: no monitoring UIs yet). Note: Explicit security group egress/ingress rules must be allowed after security groups for the database, web, and batch workers are added """ bastion_security_group = self.create_resource( ec2.SecurityGroup( 'sgBastion', GroupDescription='Enables access to the BastionHost', VpcId=Ref(self.vpc), SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol='tcp', CidrIp=Ref(self.office_cidr_parameter), FromPort=p, ToPort=p) for p in [SSH, KIBANA_PORT, GRAPHITE_PORT] ], Tags=self.get_tags(Name='sgBastion')), output='BastionSecurityGroup') self.add_resource( ec2.Instance('BastionHost', BlockDeviceMappings=[{ "DeviceName": "/dev/sda1", "Ebs": { "VolumeType": "gp2", "VolumeSize": "256" } }], InstanceType=Ref( self.bastion_instance_type_parameter), KeyName=Ref(self.keyname_parameter), ImageId=Ref(self.bastion_host_ami_parameter), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( Description='ENI for BastionHost', GroupSet=[Ref(bastion_security_group)], SubnetId=Ref(self.PUBLIC_SUBNETS[0]), AssociatePublicIpAddress=True, DeviceIndex=0, DeleteOnTermination=True) ], Tags=self.get_tags(Name='BastionHost')))
def create_instance(template, parameters=None, user_data_script=None, assign_public_ip=None, volume=None, profile=None): image_id = parameters['image_id'] key_name = parameters['key_name'] sg_ids = parameters['sg_ids'] instance_type = parameters['instance_type'] subnet_id = parameters['subnet_id'] content = [] user_data = None if user_data_script: with open(user_data_script, 'r') as f: content = f.readlines() user_data = Base64(Join('', content)) ec2_instance = template.add_resource( ec2.Instance("Ec2Instance", ImageId=Ref(image_id), InstanceType=Ref(instance_type), KeyName=Ref(key_name))) if assign_public_ip: ec2_instance.NetworkInterfaces = [ ec2.NetworkInterfaceProperty(AssociatePublicIpAddress=True, DeviceIndex=0, GroupSet=Ref(sg_ids), SubnetId=Ref(subnet_id)) ] else: ec2_instance.SecurityGroupIds = Ref(sg_ids) ec2_instance.SubnetId = Ref(subnet_id) if volume: ec2_instance.BlockDeviceMappings = [ ec2.BlockDeviceMapping(DeviceName='/dev/sda1', Ebs=volume) ] if profile: ec2_instance.IamInstanceProfile = Ref(profile) if user_data: ec2_instance.UserData = user_data
def create_bastion(self): bastion_security_group_name = 'sgBastion' bastion_security_group = self.add_resource( ec2.SecurityGroup( bastion_security_group_name, GroupDescription='Enables access to the BastionHost', VpcId=Ref(self.vpc_id), SecurityGroupIngress=[ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=Ref(self.ip_access), FromPort=p, ToPort=p) for p in [SSH] ], SecurityGroupEgress=[ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=VPC_CIDR, FromPort=p, ToPort=p) for p in [POSTGRESQL, REDIS, SSH] ] + [ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=ALLOW_ALL_CIDR, FromPort=p, ToPort=p) for p in [HTTP, HTTPS] ], Tags=self.get_tags(Name=bastion_security_group_name))) bastion_host_name = 'BastionHost' return self.add_resource( ec2.Instance(bastion_host_name, InstanceType=Ref(self.bastion_instance_type), KeyName=Ref(self.keyname), ImageId=Ref(self.bastion_host_ami), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( Description='ENI for BastionHost', GroupSet=[Ref(bastion_security_group)], SubnetId=Select('0', Ref(self.public_subnets)), AssociatePublicIpAddress=True, DeviceIndex=0, DeleteOnTermination=True) ], Tags=self.get_tags(Name=bastion_host_name)))
def main(): """ Creates a troposphere template and then adds a single s3 bucket """ template = Template() vpc = template.add_resource(ec2.VPC('MyVPC', CidrBlock='10.0.0.0/16')) internet_gateway = template.add_resource(ec2.InternetGateway('MyInternetGateway')) template.add_resource(ec2.VPCGatewayAttachment('MyVPCGatewayAttachment', InternetGatewayId=Ref(internet_gateway), VpcId=Ref(vpc), DependsOn=internet_gateway.title)) security_group = template.add_resource(ec2.SecurityGroup('mySecGroup', GroupDescription='Security group', VpcId=Ref(vpc), )) subnet = template.add_resource(ec2.Subnet('MyPubSub', AvailabilityZone='ap-southeast-2a', VpcId=Ref(vpc), CidrBlock='10.0.1.0/24')) template.add_resource(ec2.Instance( 'myinstance', KeyName='INSERT_YOUR_KEYPAIR_HERE', ImageId='ami-dc361ebf', InstanceType='t2.nano', NetworkInterfaces=[ec2.NetworkInterfaceProperty( GroupSet=[Ref(security_group)], AssociatePublicIpAddress=True, DeviceIndex='0', DeleteOnTermination=True, SubnetId=Ref(subnet))], SourceDestCheck=True, DependsOn=internet_gateway.title )) SNS(template=template) print(template.to_json(indent=2, separators=(',', ': ')))
def __init__(self, stack_name, vpc, iam_profile): """ EC2 Instance stack Args: stack_name (str): Name of the EC2 Stack vpc (:obj:`VPCStack`): The VPC stack the instace will be creeated in iam_profile (:obj:`EC2Profile`): The IAM EC2 Instance profile Attributes: private_subnet (bool): if chosen creates the instance in the first private subnet (usually AZ A ) subnet (vpc_subnet): If a specific subnet is give, overrides the private_subnet property security_groups (list[:obj:`VPC:SecurityGroup`]): List of security groups to attach """ # noqa super(EC2Stack, self).__init__("EC2", 500) self.stack_name = stack_name self.vpc = vpc self.iam_profile = iam_profile self._private_subnet = False self.subnet = False self.security_groups = [] self.use_key = None self.volumes = [] self._ami = None self.eip = None # eth0 is always managed by the stack self.network_interfaces = [ ec2.NetworkInterfaceProperty( Description='ENI for host', DeviceIndex=0, GroupSet=[], DeleteOnTermination=True, ) ]
aws_linux_instance = t.add_resource( ec2.Instance( instance_resource_name, ImageId=FindInMap( 'AWSRegionArch2AMI', Ref(AWS_REGION), FindInMap('AWSInstanceType2Arch', Ref(param_instance_type), 'Arch')), InstanceType=Ref(param_instance_type), KeyName=Ref(param_key_name), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( DeviceIndex='0', GroupSet=[ If('CreateSecurityGroupCondition', Ref(instance_ssh_sg), Ref(param_instance_sg)) ], AssociatePublicIpAddress=Ref(param_associate_public_ip), DeleteOnTermination='true', SubnetId=Ref(param_subnetid), ) ], IamInstanceProfile=If('CreateInstanceProfileCondition', Ref(instance_profile), Ref(param_instance_profile)), Metadata=instance_metadata, UserData=instance_user_data, CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal( Timeout='PT5M')), EbsOptimized=If('DefaultEbsOptimizationCondition', Ref(AWS_NO_VALUE), Ref(param_ebs_optimized)), Monitoring=Ref(param_detailed_monitoring),
def main(): template = Template() vpc = template.add_resource( ec2.VPC('MyVPC', CidrBlock='10.0.0.0/16', EnableDnsSupport='true', EnableDnsHostnames='true')) internet_gateway = template.add_resource( ec2.InternetGateway('MyInternetGateway', Tags=Tags(Name='MyInternetGateway'))) template.add_resource( ec2.VPCGatewayAttachment('MyVPCGatewayAttachment', InternetGatewayId=Ref(internet_gateway), VpcId=Ref(vpc), DependsOn=internet_gateway.title)) security_group = template.add_resource( ec2.SecurityGroup( 'mySecGroup', GroupDescription='Security group', VpcId=Ref(vpc), )) template.add_resource( ec2.SecurityGroupEgress('mySecGroupOut', CidrIp='0.0.0.0/0', IpProtocol='tcp', FromPort='0', ToPort='0', GroupId=Ref(security_group))) template.add_resource( ec2.SecurityGroupIngress('mySecGroupIn', CidrIp='0.0.0.0/0', IpProtocol='tcp', FromPort='0', ToPort='0', GroupId=Ref(security_group))) public_subnets = [ template.add_resource( ec2.Subnet('MyPubSub1', AvailabilityZone='ap-southeast-2a', VpcId=Ref(vpc), CidrBlock='10.0.1.0/24')), template.add_resource( ec2.Subnet('MyPubSub2', AvailabilityZone='ap-southeast-2b', VpcId=Ref(vpc), CidrBlock='10.0.2.0/24')), template.add_resource( ec2.Subnet('MyPubSub3', AvailabilityZone='ap-southeast-2c', VpcId=Ref(vpc), CidrBlock='10.0.3.0/24')) ] template.add_resource( elb.LoadBalancer('myLoadBalancer', CrossZone=True, HealthCheck=elb.HealthCheck( Target='HTTP:80/index.html', HealthyThreshold='10', UnhealthyThreshold='2', Interval='300', Timeout='60'), Listeners=[ elb.Listener(LoadBalancerPort='80', Protocol='HTTP', InstancePort='80', InstanceProtocol='HTTP') ], Scheme='internet-facing', SecurityGroups=[Ref(security_group)], Subnets=[Ref(subnet) for subnet in public_subnets])) template.add_resource( ec2.Instance('myinstance', KeyName='INSERT_YOUR_KEYPAIR_HERE', ImageId='ami-dc361ebf', InstanceType='t2.nano', NetworkInterfaces=[ ec2.NetworkInterfaceProperty( GroupSet=[Ref(security_group)], AssociatePublicIpAddress=True, DeviceIndex='0', DeleteOnTermination=True, SubnetId=Ref(public_subnets[0])) ], SourceDestCheck=True, DependsOn=internet_gateway.title)) HostedZone(template=template, domain='mypublic.hz', vpcs=None) HostedZone(template=template, domain='myprivate.hz', vpcs=[Ref(vpc)]) print(template.to_json(indent=2, separators=(',', ': ')))
def instance(self, index): hosts = ", ".join(["\"node{node}.{stack_name}.{domain}:10101\"".format(node=node, stack_name='${AWS::StackName}', domain=self.domain) for node in range(self.cluster_size)]) internal_hosts = ", ".join(["\"node{node}.{stack_name}.{domain}:12000\"".format(node=node, stack_name='${AWS::StackName}', domain=self.domain) for node in range(self.cluster_size)]) config_file = dedent(''' data-dir = "/home/{username}/pilosa/data1" bind = "node{node}.{stack_name}.{domain}:10101" log-path = "/home/ubuntu/pilosa.log" [cluster] replicas = {replicas} internal-port = 12000 type = "http" hosts = [{hosts}] internal-hosts = [{internal_hosts}] ''')[1:].format(node=index, replicas=self.replicas, stack_name='${AWS::StackName}', domain=self.domain, username=self.username, hosts=hosts, internal_hosts=internal_hosts) user_data = dedent(''' {common} # update open file limits cat >> /etc/security/limits.conf <<- EOF * soft nofile 262144 * hard nofile 262144 * hard memlock unlimited * soft memlock unlimited EOF # install pilosa go get -u github.com/pilosa/pilosa cd $GOPATH/src/github.com/pilosa/pilosa make install # set up pilosa config file cat > /etc/pilosa.cfg <<- EOF {config_file} EOF # clean up root's mess chown -R {username}:{username} /home/{username} # all output should go to pilosa.log - pilosa.out should be empty sudo -u {username} PATH=$PATH nohup pilosa server --config=/etc/pilosa.cfg &> /home/{username}/pilosa.out & '''[1:]).format(config_file=config_file, common=self.common_user_data, username=self.username) return ec2.Instance( 'PilosaInstance{}'.format(index), ImageId = Ref(self.ami), BlockDeviceMappings=[ec2.BlockDeviceMapping( DeviceName="/dev/sda1", Ebs=ec2.EBSBlockDevice(VolumeSize=Ref(self.volume_size), VolumeType=Ref(self.volume_type)) )], InstanceType = Ref(self.instance_type), KeyName = Ref(self.key_pair), IamInstanceProfile=Ref(self.instance_profile), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( GroupSet=[Ref(self.instance_security_group.title)], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(self.subnet))], UserData = Base64(Sub(user_data)), )
def generate_stack_template(): template = Template() generate_description(template) generate_version(template) # ---Parameters------------------------------------------------------------ param_vpc_id = Parameter( 'VpcIdentifer', Description= 'The identity of the VPC (vpc-abcdwxyz) in which this stack shall be created.', Type='AWS::EC2::VPC::Id', ) template.add_parameter(param_vpc_id) param_vpc_security_group = Parameter( 'VpcSecurityGroup', Description= 'The security group (sg-abcdwxyz) to apply to the resources created by this stack.', Type='AWS::EC2::SecurityGroup::Id', ) template.add_parameter(param_vpc_security_group) param_webserver_instance_subnet_id = Parameter( 'VpcSubnetIdentifer', Description= 'The identity of the public subnet (subnet-abcdwxyz) in which the web server shall be created.', Type='AWS::EC2::Subnet::Id', ) template.add_parameter(param_webserver_instance_subnet_id) param_keyname = Parameter( 'PemKeyName', Description= 'Name of an existing EC2 KeyPair file (.pem) to use to create EC2 instances', Type='AWS::EC2::KeyPair::KeyName') template.add_parameter(param_keyname) param_instance_type = Parameter( 'EC2InstanceType', Description= 'EC2 instance type, reference this parameter to insure consistency', Type='String', Default= 't2.medium', # Prices from (2015-12-03) (Windows, us-west (North CA)) AllowedValues=[ # Source : https://aws.amazon.com/ec2/pricing/ 't2.small', # $0.044/hour 't2.micro', # $0.022/hour 't2.medium', # $0.088/hour 't2.large', # $0.166/hour 'm3.medium', # $0.140/hour 'm3.large', # $0.28/hour 'c4.large' # $0.221/hour ], ConstraintDescription='Must be a valid EC2 instance type') template.add_parameter(param_instance_type) #---Mappings--------------------------------------------------------------- mapping_environment_attribute_map = template.add_mapping( 'EnvironmentAttributeMap', { 'ap-southeast-1': { 'WebServerAmi': 'ami-1ddc0b7e' }, 'ap-southeast-2': { 'WebServerAmi': 'ami-0c95b86f' }, 'us-east-1': { 'WebServerAmi': 'ami-a4827dc9' }, 'us-west-1': { 'WebServerAmi': 'ami-f5f41398' } }) # ---Resources------------------------------------------------------------- ref_region = Ref('AWS::Region') ref_stack_name = Ref('AWS::StackName') # Create the metadata for the server instance. name_web_server = 'WebServer' webserver_instance_metadata = cloudformation.Metadata( cloudformation.Init({ 'config': cloudformation.InitConfig( packages={'yum': { 'nginx': [], 'git': [] }}, files=cloudformation.InitFiles({ # cfn-hup.conf initialization '/etc/cfn/authorapp.conf': cloudformation.InitFile(content=Join( '', [ 'server {', '\n', ' listen 3030 ssl http2;', '\n', ' root /var/www/authorapp;', '\n', '\n', ' ssl_certificate /vagrant/ssl/ca.crt;', '\n', ' ssl_certificate_key /vagrant/ssl/ca.key;', '\n', '\n', ' location / {', '\n', ' }', '\n', '\n', ' location /api {', '\n', ' proxy_pass http://10.50.50.1:3000;', '\n', ' }', '\n', '}', '\n', ]), mode='000400', owner='root', group='root'), }), services=dict(sysvinit=cloudformation.InitServices({ # start cfn-hup service - # required for CloudFormation stack update 'cfn-hup': cloudformation.InitService( enabled=True, ensureRunning=True, files=[ '/etc/cfn/cfn-hup.conf', '/etc/cfn/hooks.d/cfn-auto-reloader.conf' ]), # Disable sendmail service - not required. 'sendmail': cloudformation.InitService(enabled=False, ensureRunning=False) }))) })) resource_web_server = ec2.Instance( name_web_server, Metadata=webserver_instance_metadata, ImageId=FindInMap('EnvironmentAttributeMap', ref_region, 'WebServerAmi'), InstanceType=Ref(param_instance_type), KeyName=Ref(param_keyname), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( AssociatePublicIpAddress=str(True), DeleteOnTermination=str(True), Description='Network interface for web server', DeviceIndex=str(0), GroupSet=[Ref(param_vpc_security_group)], SubnetId=Ref(param_webserver_instance_subnet_id), ) ], Tags=Tags(Name=name_web_server, VPC=Ref(param_vpc_id)), UserData=Base64( Join('', [ '#!/bin/bash -xe\n', 'yum update -y aws-cfn-bootstrap\n', 'yum update -y', '\n' '/opt/aws/bin/cfn-init --verbose ', ' --stack ', ref_stack_name, ' --resource %s ' % name_web_server, ' --region ', ref_region, '\n', '/opt/aws/bin/cfn-signal --exit-code $? ', ' --stack ', ref_stack_name, ' --resource ', name_web_server, '\n' ]))) template.add_resource(resource_web_server) template.add_output( Output('WebServer', Description='Web Server', Value=GetAtt(name_web_server, 'PublicIp'))) return template
ud = Base64( Join('\n', [ "#!/bin/bash", "sudo yum install --enablerepo=epel -y nodejs", "wget http://bit.ly/2vESNuc -O /home/ec2-user/helloworld.js", "wget http://bit.ly/2vVvT18 -O /etc/init/helloworld.conf", "start helloworld" ])) t.add_resource( ec2.Instance( "instance", ImageId="ami-e251209a", InstanceType="t2.micro", NetworkInterfaces=[ ec2.NetworkInterfaceProperty(AssociatePublicIpAddress="true", GroupSet=[Ref("SecurityGroup")], SubnetId="subnet-72379639", DeviceIndex="0"), ], KeyName=Ref("KeyPair"), UserData=ud, )) t.add_output( Output( "InstancePublicIp", Description="Public IP of our instance.", Value=GetAtt("instance", "PublicIp"), )) t.add_output( Output(
ImageId=FindInMap("CENTOS7", Ref("AWS::Region"), "AMI"), BlockDeviceMappings=If( "AmbariUseEBSBool", my_block_device_mappings_ebs(ref_disk_ambari_ebs_diskcount,"/dev/sd",ref_disk_ambari_ebs_volumesize,"gp2"), my_block_device_mappings_ephemeral(24,"/dev/sd")), CreationPolicy=CreationPolicy( ResourceSignal=ResourceSignal( Count=1, Timeout="PT60M" )), KeyName=Ref(KeyName), InstanceType=Ref(AmbariInstanceType), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( DeleteOnTermination="true", DeviceIndex="0", SubnetId=Ref(PublicSubnet), GroupSet=[Ref(AmbariSecurityGroup)], AssociatePublicIpAddress="true", ), ], )) t.add_output([ Output( "AmbariURL", Description="URL of Ambari UI", Value=Join("", [ "http://", GetAtt('AmbariNode', 'PublicIp'), ":8080" ]), ), Output(
"tar -xvpf aws-cfn-bootstrap-latest.tar.gz\n", "cd aws-cfn-bootstrap-1.4/\n", "python setup.py build\n", "python setup.py install\n", "ln -s /usr/init/redhat/cfn-hup /etc/init.d/cfn-hup\n", "chmod 775 /usr/init/redhat/cfn-hup\n", "cd /opt\n", "mkdir aws\n", "cd aws\n", "mkdir bin\n", "ln -s /usr/bin/cfn-hup /opt/aws/bin/cfn-hup\n", "yum install -y yum-utils device-mapper-persistent-data lvm2\n", "yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo\n", "yum -y install docker-ce\n", "systemctl start docker\n", "systemctl enable docker\n", "sudo docker run -d --restart always --name MavenRepo -p 8081:8081 -v /opt/artifactory/data:/var/opt/jfrog/artifactory/data -v /opt/artifactory/logs:/var/opt/jfrog/artifactory/logs -v /opt/artifactory/etc:/var/opt/jfrog/artifactory/etc docker.bintray.io/jfrog/artifactory-oss:latest\n" ])) t.add_resource( ec2.Instance("server", ImageId="ami-4bf3d731", InstanceType=Ref("InstanceType"), UserData=ud, KeyName=Ref("KeyPair"), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( GroupSet=[Ref("MavenRepoSecurityGroup")], AssociatePublicIpAddress='false', SubnetId=Select("0", Ref("PrivateSubnet")), DeviceIndex='0', ) ])) print t.to_json()
"yum -y update && yum -y upgrade\n", "/usr/bin/easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz 2>&1 >> /var/log/initial_user-data.log\n", "yum -y install epel-release\n", "yum -y install python-pip\n", "pip install --upgrade pip\n", "pip install docker-compose\n", "yum install -y yum-utils device-mapper-persistent-data lvm2\n", "yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo\n", "yum -y install docker-ce\n", "systemctl start docker\n", "systemctl enable docker\n", "yum -y install git\n", ])) t.add_resource(ec2.Instance( "server", ImageId="ami-4bf3d731", InstanceType=Ref("InstanceType"), UserData=ud, KeyName=Ref("KeyPair"), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( GroupSet=[Ref("SGCentOS7DockerTemplate")], AssociatePublicIpAddress='true', SubnetId=Select("0", Ref("SubnetID")), DeviceIndex='0', )] )) print t.to_json()
t.add_resource( IAMPolicy( "Policy", PolicyName="AllowS3", PolicyDocument=Policy(Statement=[ Statement(Effect=Allow, Action=[Action("s3", "*")], Resource=["*" ]), Statement( Effect=Allow, Action=[Action("logs", "*")], Resource=["*"]) ]), Roles=[Ref("Role")])) t.add_resource( ec2.Instance("KubernetesMaster", ImageId="ami-8ec0e1f4", UserData=ud, InstanceType=Ref("InstanceType"), KeyName=Ref("KeyPair"), IamInstanceProfile=Ref("MasterInstanceProfile"), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( GroupSet=[Ref("MasterNodes")], AssociatePublicIpAddress='false', SubnetId="subnet-d1c1d09a", DeviceIndex='0', ) ])) print t.to_json()
def create_bastion(self): bastion_security_group_name = 'sgBastion' bastion_security_group = self.add_resource( ec2.SecurityGroup( bastion_security_group_name, GroupDescription='Enables access to the BastionHost', VpcId=Ref(self.vpc), SecurityGroupIngress=[ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=Ref(self.ip_access), FromPort=p, ToPort=p) for p in [GRAPHITE_WEB, KIBANA, SSH] ] + [ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=VPC_CIDR, FromPort=p, ToPort=p) for p in [GRAPHITE, RELP, STATSITE] ] + [ ec2.SecurityGroupRule(IpProtocol='udp', CidrIp=VPC_CIDR, FromPort=p, ToPort=p) for p in [STATSITE] ], SecurityGroupEgress=[ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=VPC_CIDR, FromPort=p, ToPort=p) for p in [POSTGRESQL, REDIS, SSH] ] + [ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=ALLOW_ALL_CIDR, FromPort=p, ToPort=p) for p in [HTTP, HTTPS] ], Tags=self.get_tags(Name=bastion_security_group_name))) bastion_host_name = 'BastionHost' bastion_host = self.add_resource( ec2.Instance(bastion_host_name, BlockDeviceMappings=[{ "DeviceName": "/dev/sda1", "Ebs": { "VolumeType": "gp2", "VolumeSize": "256" } }], InstanceType=Ref(self.bastion_instance_type), KeyName=Ref(self.keyname), IamInstanceProfile=Ref(self.bastion_instance_profile), ImageId=Ref(self.bastion_host_ami), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( Description='ENI for BastionHost', GroupSet=[Ref(bastion_security_group)], SubnetId=Ref(self.PUBLIC_SUBNETS[0]), AssociatePublicIpAddress=True, DeviceIndex=0, DeleteOnTermination=True) ], Tags=self.get_tags(Name=bastion_host_name))) return bastion_host, bastion_security_group
def create(): mydb = mysql.connector.connect(host="localhost", user="******", passwd="AmazingTheory62", database="cloud_formation") mycursor = mydb.cursor() mycursor.execute("SELECT * FROM ec2_table") myresult = (mycursor.fetchone()) sname = myresult[0] name = myresult[1] region = myresult[2] itype = myresult[3] vpc1 = myresult[4] subnet1 = myresult[5] #print(type(vpc1)) template = Template() keyname_param = template.add_parameter( Parameter("KeyName", Description="Name of an existing EC2 KeyPair to enable SSH " "access to the instance", Type="String", Default="jayaincentiuskey")) vpcid_param = template.add_parameter( Parameter( "VpcId", Description="VpcId of your existing Virtual Private Cloud (VPC)", Type="String", Default=vpc1)) subnetid_param = template.add_parameter( Parameter( "SubnetId", Description= "SubnetId of an existing subnet (for the primary network) in " "your Virtual Private Cloud (VPC)" "access to the instance", Type="String", Default=subnet1)) secondary_ip_param = template.add_parameter( Parameter( "SecondaryIPAddressCount", Description= "Number of secondary IP addresses to assign to the network " "interface (1-5)", ConstraintDescription="must be a number from 1 to 5.", Type="Number", Default="1", MinValue="1", MaxValue="5", )) sshlocation_param = template.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.")) template.add_mapping('RegionMap', {"us-west-2": {"AMI": region}}) eip1 = template.add_resource(ec2.EIP( "EIP1", Domain="vpc", )) ssh_sg = template.add_resource( ec2.SecurityGroup( "SSHSecurityGroup", VpcId=Ref(vpcid_param), GroupDescription="Enable SSH access via port 22", SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="22", ToPort="22", 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"), InstanceType=itype, KeyName=Ref(keyname_param), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( NetworkInterfaceId=Ref(eth0), DeviceIndex="0", ), ], Tags=Tags(Name=name, ))) template.add_output([ Output( "InstanceId", Description="InstanceId of the newly created EC2 instance", Value=Ref(ec2_instance), ), Output( "EIP1", Description="Primary public IP address for Eth0", Value=Join( " ", ["IP address", Ref(eip1), "on subnet", Ref(subnetid_param)]), ), Output( "PrimaryPrivateIPAddress", Description="Primary private IP address of Eth0", Value=Join(" ", [ "IP address", GetAtt("Eth0", "PrimaryPrivateIpAddress"), "on subnet", Ref(subnetid_param) ]), ), Output( "FirstSecondaryPrivateIPAddress", Description="First secondary private IP address of Eth0", Value=Join(" ", [ "IP address", Select("0", GetAtt("Eth0", "SecondaryPrivateIpAddresses")), "on subnet", Ref(subnetid_param) ]), ), ]) print(template.to_json()) file = open('ec2json.json', 'w') file.write(template.to_json()) file.close() os.system('aws cloudformation create-stack --stack-name ' + sname + ' --template-body file://ec2json.json')
FromPort="443", ToPort="443", CidrIp="0.0.0.0/0", ) ], VpcId=Ref("VpcId"))) t.add_resource( ec2.Instance("server", ImageId="ami-a4e426b2", InstanceType="t2.micro", KeyName=Ref("KeyPair"), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( GroupSet=[Ref("VPNSecurityGroup")], AssociatePublicIpAddress='true', SubnetId=Select("0", Ref("PublicSubnet")), DeviceIndex='0', ) ])) t.add_output( Output("VPNAddress", Description="VPN address", Value=GetAtt("server", "PublicIp"))) t.add_output(Output("VPNUser", Description="VPN username", Value="vpn")) t.add_output( Output("VPNPassword", Description="VPN password", Value=Ref("server"))) t.add_output(
def add_resources(self): self.CassandraPublicLBSG = self.template.add_resource( ec2.SecurityGroup( "CassandraPublicLBSG", GroupDescription= "Loadbalancer Security Group For Cassandra Public LB", VpcId=Ref(self.VpcId), SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol="tcp", FromPort=22, ToPort=22, CidrIp=Ref(self.AdminCidrBlock), ), ], Tags=self.base_tags + Tags(Name=self.environment_parameters["ClientEnvironmentKey"] + "-CassandraPublicLBSG"), )) self.CassandraSG = self.template.add_resource( ec2.SecurityGroup( "CassandraSG", GroupDescription= "Allow communication between Cassandra Seed and Non-Seed Nodes", VpcId=Ref(self.VpcId), SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol="tcp", FromPort=22, ToPort=22, SourceSecurityGroupId=Ref(self.CassandraPublicLBSG), ), ], Tags=self.base_tags + Tags(Name=self.environment_parameters["ClientEnvironmentKey"] + "-CassandraEc2SG"), )) self.CassandraSGInterNodeCommunicationIngress = self.template.add_resource( ec2.SecurityGroupIngress( "CassandraSGInterNodeCommunicationIngress", DependsOn=self.CassandraSG, GroupId=Ref(self.CassandraSG), IpProtocol="tcp", FromPort=7000, ToPort=7001, SourceSecurityGroupId=Ref(self.CassandraSG), )) self.CassandraSeedNetworkInterface = self.template.add_resource( ec2.NetworkInterface( "Eth0", Description="eth0", GroupSet=[Ref(self.CassandraSG)], SubnetId=Ref(self.RESTPrivSubnet1), PrivateIpAddress="10.0.1.132", Tags=self.base_tags + Tags(Name=self.environment_parameters["ClientEnvironmentKey"] + "-CassandraSeedNetworkInterface"), )) self.CassandraSeed1 = self.template.add_resource( ec2.Instance( "CassandraSeed1", ImageId=Ref(self.CassandraImageId), KeyName=Ref(self.CassandraServerKeyName), InstanceType=Ref(self.CassandraServerInstanceType), IamInstanceProfile=Ref(self.CassandraServerIAMInstanceProfile), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( NetworkInterfaceId=Ref( self.CassandraSeedNetworkInterface), DeviceIndex="0", ), ], UserData=Base64( Join('', [ "#!/bin/bash -x\n", "export NODE_IP=`hostname -I`\n", "export SEED_LIST=\"10.0.1.132\"\n", "export CASSANDRA_YML=\"/etc/cassandra/conf/cassandra.yaml\"\n", "export CLUSTER_NAME=\"devops_cluster\"\n", "export SNITCH_TYPE=\"Ec2Snitch\"\n", "sed -i \"/cluster_name:/c\\cluster_name: \\'${CLUSTER_NAME}\\'\" ${CASSANDRA_YML}\n", "sed -i \"/- seeds:/c\\ - seeds: \\\"${SEED_LIST}\\\"\" ${CASSANDRA_YML}\n", "sed -i \"/listen_address:/c\\listen_address: ${NODE_IP}\" ${CASSANDRA_YML}\n", "sed -i \"/rpc_address:/c\\rpc_address: ${NODE_IP}\" ${CASSANDRA_YML}\n", "sed -i \"/endpoint_snitch:/c\\endpoint_snitch: ${SNITCH_TYPE}\" ${CASSANDRA_YML}\n", "sed -i \"/authenticator: AllowAllAuthenticator/c\\authenticator: PasswordAuthenticator\" ${CASSANDRA_YML}\n" "echo 'auto_bootstrap: false' >> ${CASSANDRA_YML}\n", "service cassandra start\n" ])), Tags=self.base_tags + Tags(Name=self.environment_parameters["ClientEnvironmentKey"] + "-CassandraSeed-1-Ec2"), )) self.CassandraPublicLoadBalancer = self.template.add_resource( elb.LoadBalancer( "CassandraPublicLoadBalancer", LoadBalancerName=self. environment_parameters["ClientEnvironmentKey"] + "-CassandraNonSeedPubLB", Scheme="internet-facing", Listeners=[ elb.Listener( LoadBalancerPort="22", InstancePort="22", Protocol="TCP", InstanceProtocol="TCP", ) ], Instances=[], SecurityGroups=[Ref(self.CassandraPublicLBSG)], Subnets=[Ref(self.RESTPubSubnet1)], Tags=self.base_tags + Tags(Name=self.environment_parameters["ClientEnvironmentKey"] + "-CassandraNonSeedPubLB"), )) self.CassandraNonSeedLaunchConfiguration = self.template.add_resource( LaunchConfiguration( "CassandraNonSeedLaunchConfiguration", ImageId=Ref(self.CassandraImageId), InstanceType=Ref(self.CassandraServerInstanceType), IamInstanceProfile=Ref(self.CassandraServerIAMInstanceProfile), KeyName=Ref(self.CassandraServerKeyName), SecurityGroups=[Ref(self.CassandraSG)], UserData=Base64( Join('', [ "#!/bin/bash -x\n", "export NODE_IP=`hostname -I`\n", "export SEED_LIST=\"10.0.1.132\"\n", "export CASSANDRA_YML=\"/etc/cassandra/conf/cassandra.yaml\"\n", "export CLUSTER_NAME=\"devoops_cluster\"\n", "export SNITCH_TYPE=\"Ec2Snitch\"\n", "sed -i \"/cluster_name:/c\\cluster_name: \\'${CLUSTER_NAME}\\'\" ${CASSANDRA_YML}\n", "sed -i \"/- seeds:/c\\ - seeds: \\\"${SEED_LIST}\\\"\" ${CASSANDRA_YML}\n", "sed -i \"/listen_address:/c\\listen_address: ${NODE_IP}\" ${CASSANDRA_YML}\n", "sed -i \"/rpc_address:/c\\rpc_address: ${NODE_IP}\" ${CASSANDRA_YML}\n", "sed -i \"/endpoint_snitch:/c\\endpoint_snitch: ${SNITCH_TYPE}\" ${CASSANDRA_YML}\n", "sed -i \"/authenticator: AllowAllAuthenticator/c\\authenticator: PasswordAuthenticator\" ${CASSANDRA_YML}\n", "echo 'auto_bootstrap: false' >> ${CASSANDRA_YML}\n", "service cassandra start\n" ])), )) self.CassandraNonSeedAutoScalingGroup = self.template.add_resource( AutoScalingGroup( "CassandraNonSeedAutoscalingGroup", AutoScalingGroupName=self. environment_parameters["ClientEnvironmentKey"] + "-CassandraNonSeedAutoScalingGroup", LaunchConfigurationName=Ref( self.CassandraNonSeedLaunchConfiguration), LoadBalancerNames=[Ref(self.CassandraPublicLoadBalancer)], MaxSize="1", MinSize="1", DesiredCapacity="1", VPCZoneIdentifier=[Ref(self.RESTPrivSubnet1)], Tags=[ AutoScalingTag( "Name", self.environment_parameters["ClientEnvironmentKey"] + "-CassandraNonSeedEc2", True), AutoScalingTag( "Environment", self.environment_parameters["EnvironmentName"], True), AutoScalingTag( "ResourceOwner", self.environment_parameters["ResourceOwner"], True), AutoScalingTag( "ClientCode", self.environment_parameters["ClientEnvironmentKey"], True), ], ))
def add_instance(self, stack_name, template, provision_refs, instance_num, version=None): instance = ec2.Instance(f'node{instance_num}') instance.IamInstanceProfile = Ref(provision_refs.instance_profile) instance.ImageId = self.app.config.get('provision', 'aws_ec2_ami_id') instance.InstanceType = self.app.config.get('provision', 'aws_ec2_instance_type') instance.KeyName = self.app.config.get('provision', 'aws_ec2_key_name') instance.NetworkInterfaces = [ ec2.NetworkInterfaceProperty(GroupSet=[ provision_refs.security_group_ec2, ], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=provision_refs.random_subnet) ] instance.EbsOptimized = 'true' if 'i3' not in instance.InstanceType: instance.BlockDeviceMappings = [ # Set root volume size to 500gb ec2.BlockDeviceMapping(DeviceName='/dev/sda1', Ebs=ec2.EBSBlockDevice(VolumeSize='500', VolumeType='io1', Iops='1000')) ] instance.Tags = Tags(Name=f'{stack_name}-node{instance_num}') version_flag = f' --version={version}' if version else '' join_network_arguments = f'--name={stack_name}{version_flag} --set-default --install --no-configure' instance.UserData = Base64( Join( '', [ '#!/bin/bash -xe\n', 'apt update -y -q\n', 'UCF_FORCE_CONFOLD=1 DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -qq -y install python3-pip\n', 'apt install -y -q htop tmux zsh jq libssl-dev libleveldb-dev || true\n', 'ln -s /usr/lib/x86_64-linux-gnu/libleveldb.so /usr/lib/x86_64-linux-gnu/libleveldb.so.1\n', 'mkdir /data\n', ] + ([ # If type i3, mount NVMe drive at /data 'DEV=/dev/$(lsblk | grep nvme | awk \'{print $1}\')\n', 'mkfs -t xfs $DEV\n', 'UUID=$(blkid -s UUID -o value $DEV)\n', 'echo "UUID=$UUID /data xfs defaults 0 0" >> /etc/fstab\n', 'mount -a\n' ] if 'i3' in instance.InstanceType else []) + [ # Install hydra 'pip3 install cement colorlog\n', f'pip3 install {self.app.config.get("provision", "pip_install") % self.app.config["hydra"]}\n', 'chown ubuntu:ubuntu /data\n', 'su -l -c "hydra info" ubuntu\n', # Generate default hydra.yml "sed -i 's/workdir: .*/workdir: \\/data/' /home/ubuntu/.hydra.yml\n", # Change workdir to /data f'su -l -c "hydra client join-network {join_network_arguments}" ubuntu\n' ])) template.add_resource(instance) template.add_output([ Output( f"ID{instance_num}", Description="InstanceId of the newly created EC2 instance", Value=Ref(instance), ), Output( f"IP{instance_num}", Description= "Public IP address of the newly created EC2 instance", Value=GetAtt(instance, "PublicIp"), ), ]) return instance
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
USER_DATA_MASTER.replace("[ipPrivateList]", ipPrivateList).replace( "[CloudWatchIdentifier]", cloudWatchIdentifier).replace( "[nameMaster]", f.ec2.name)), Tags=Tags(Name=environmentString + f.ec2.name, Stack=Ref("AWS::StackName")), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( DeleteOnTermination="true", Description="Primary network interface", DeviceIndex="0", SubnetId=Ref(f.instance), AssociatePublicIpAddress="true", PrivateIpAddresses=[ ec2.PrivateIpAddressSpecification( "PrivateIpAddress", Primary="true", PrivateIpAddress=f.ec2.ip) ], GroupSet=[Ref(instanceSecurityGroup)]) ], )) f.ec2.instance = instance alarmMaster = template.add_resource( Alarm("AlarmRecovery" + f.ec2.name, AlarmDescription="Recovery " + f.ec2.name, Namespace="AWS/EC2", MetricName="StatusCheckFailed_System", Dimensions=[
def buildInstance(t, args): t.add_resource( ec2.SecurityGroup('WebserverSG', GroupDescription='Global Webserver Access', VpcId=Ref('VPC'), Tags=Tags(Name='Global Webserver Access'))) t.add_resource( ec2.SecurityGroupIngress('WebserverSGIngress1', GroupId=Ref('WebserverSG'), IpProtocol='tcp', CidrIp='0.0.0.0/0', FromPort='22', ToPort='22')) t.add_resource( ec2.SecurityGroupIngress('WebserverSGIngress2', GroupId=Ref('WebserverSG'), IpProtocol='tcp', CidrIp='0.0.0.0/0', FromPort='80', ToPort='80')) t.add_resource( ec2.SecurityGroupIngress('WebserverSGIngress3', GroupId=Ref('WebserverSG'), IpProtocol='tcp', CidrIp='0.0.0.0/0', FromPort='443', ToPort='443')) 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] }] 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 > /tmp/part-001.log 2>&1\n", "apt-get -y update\n", "apt-get -y install python-pip\n", "pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\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", "DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\" --force-yes\n", "mkfs -t ext4 /dev/xvdd\n", "mkdir /mnt/docker\n", "cat /root/fstab.append >> /etc/fstab\n", "mount /mnt/docker\n", "ln -s /mnt/docker /var/lib/docker\n", "apt-get -y install python-boto awscli\n", "S3=", Ref('S3Bucket'), "\n", "KMS=", OpenEMRKeyID, "\n", "touch /root/cloud-backups-enabled\n", "echo $S3 > /root/.cloud-s3.txt\n", "echo $KMS > /root/.cloud-kms.txt\n", "touch /tmp/mypass\n", "chmod 500 /tmp/mypass\n", "openssl rand -base64 32 >> /tmp/mypass\n", "aws s3 cp /tmp/mypass s3://$S3/Backup/passphrase.txt --sse aws:kms --sse-kms-key-id $KMS\n", "rm /tmp/mypass\n", "curl -L https://raw.githubusercontent.com/openemr/openemr-devops/master/packages/lightsail/launch.sh > /root/launch.sh\n", "chmod +x /root/launch.sh && /root/launch.sh -s 0\n" ] fstabFile = ["/dev/xvdd /mnt/docker ext4 defaults,nofail 0 0\n"] bootstrapInstall = cloudformation.InitConfig( files={ "/root/cloud-setup.sh": { "content": Join("", setupScript), "mode": "000500", "owner": "root", "group": "root" }, "/root/fstab.append": { "content": Join("", fstabFile), "mode": "000400", "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, 'UbuntuAMI'), InstanceType=Ref('InstanceSize'), NetworkInterfaces=[ ec2.NetworkInterfaceProperty( AssociatePublicIpAddress=True, DeviceIndex="0", GroupSet=[Ref('WebserverSG')], SubnetId=Ref('PublicSubnet1')) ], KeyName=Ref('EC2KeyPair'), IamInstanceProfile=Ref('WebserverInstanceProfile'), Volumes=[{ "Device": "/dev/sdd", "VolumeId": Ref('DockerVolume') }], Tags=Tags(Name='OpenEMR Express Plus'), InstanceInitiatedShutdownBehavior='stop', UserData=Base64(Join('', bootstrapScript)), CreationPolicy={"ResourceSignal": { "Timeout": "PT25M" }})) return t