def add_resources(self): self.MySQLDBSubnetGroup = self.template.add_resource( rds.DBSubnetGroup( "MySQLDBSubnetGroup", SubnetIds=[Ref(self.Subnet1), Ref(self.Subnet2)], DBSubnetGroupDescription="MySQLDBSubnetGroup", Tags=Tags( Name=Join("-", ["DB-SUB-GRP", Ref(self.Project)]), Environment=Ref(self.Environment), ), )) self.MySQLDatabase = self.template.add_resource( rds.DBInstance("MySQLDatabase", DBInstanceIdentifier=Join( "-", ["rds", Ref(self.Project)]), Engine="MySQL", MultiAZ=Ref(self.MultiAZDatabase), PubliclyAccessible="false", MasterUsername=Ref(self.DBUser), MasterUserPassword=Ref(self.DBPass), VPCSecurityGroups=[Ref(self.RDSSecurityGroup)], AllocatedStorage=Ref(self.DBAllocatedStorage), DBInstanceClass=Ref(self.DBInstanceClass), DBSubnetGroupName=Ref(self.MySQLDBSubnetGroup), DBName=Ref(self.DBName), Tags=Tags( Name=Join("-", ["rds", Ref(self.Project)]), Environment=Ref(self.Environment), Project=Ref(self.Project), )))
def render_rds(context, template): lu = partial(utils.lu, context) # db subnet *group* # it's expected the db subnets themselves are already created within the VPC # you just need to plug their ids into the project file. # not really sure if a subnet group is anything more meaningful than 'a collection of subnet ids' rsn = rds.DBSubnetGroup( DBSUBNETGROUP_TITLE, **{ "DBSubnetGroupDescription": "a group of subnets for this rds instance.", "SubnetIds": lu('project.aws.rds.subnets'), }) # rds security group. uses the ec2 security group vpcdbsg = rds_security(context) # rds parameter group. None or a Ref param_group_ref = rdsdbparams(context, template) # db instance data = { 'DBName': lu('rds_dbname'), # dbname generated from instance id. 'DBInstanceIdentifier': lu('rds_instance_id'), # ll: 'lax-2015-12-31' from 'lax--2015-12-31' 'PubliclyAccessible': False, 'AllocatedStorage': lu('project.aws.rds.storage'), 'StorageType': 'Standard', 'MultiAZ': lu('project.aws.rds.multi-az'), 'VPCSecurityGroups': [Ref(vpcdbsg)], 'DBSubnetGroupName': Ref(rsn), 'DBInstanceClass': lu('project.aws.rds.type'), 'Engine': lu('project.aws.rds.engine'), # something is converting this value to an int from a float :( "EngineVersion": str(lu('project.aws.rds.version')), # 'defaults.aws.rds.storage')), 'MasterUsername': lu('rds_username'), # pillar data is now UNavailable 'MasterUserPassword': lu('rds_password'), 'BackupRetentionPeriod': lu('project.aws.rds.backup-retention'), 'DeletionPolicy': 'Snapshot', "Tags": instance_tags(context), "AllowMajorVersionUpgrade": False, # default? not specified. "AutoMinorVersionUpgrade": True, # default } if param_group_ref: data['DBParameterGroupName'] = param_group_ref rdbi = rds.DBInstance(RDS_TITLE, **data) map(template.add_resource, [rsn, rdbi, vpcdbsg]) outputs = [ mkoutput("RDSHost", "Connection endpoint for the DB cluster", (RDS_TITLE, "Endpoint.Address")), mkoutput("RDSPort", "The port number on which the database accepts connections", (RDS_TITLE, "Endpoint.Port")), ] map(template.add_output, outputs)
def create_database_subnet_group_resource(template, subnets_parameter): return template.add_resource( rds.DBSubnetGroup( 'DatabaseSubnetGroup', DBSubnetGroupDescription='Subnets available for the RDS instance', SubnetIds=Ref(subnets_parameter) ) )
def __init__(self, parameters, vpc, loadbalancer): """ :type parameters Parameters :type vpc VPC :type loadbalancer LoadBalancer """ super(Database, self).__init__() self.db_security_group = ec2.SecurityGroup( "DBSecurityGroup", GroupDescription="Database security group", SecurityGroupIngress=[ ec2.SecurityGroupRule( # rds IpProtocol="tcp", FromPort=3306, ToPort=3306, SourceSecurityGroupId=Ref( loadbalancer.instance_security_group)) ], SecurityGroupEgress=[ # disallow outgoing connections { "CidrIp": "127.0.0.1/32", "IpProtocol": "-1" } ], VpcId=Ref(vpc.vpc), Tags=Tags(Name=Join( "", [Ref("AWS::StackName"), " RDS security group"]), ), ) # rds self.db_subnet_group = rds.DBSubnetGroup( "DBSubnetGroup", DBSubnetGroupDescription="DB Subnet group", SubnetIds=[ Ref(vpc.private_subnet_1), Ref(vpc.private_subnet_2), ], Tags=Tags(Name=Join( "", [Ref("AWS::StackName"), " database subnet group"]), )) self.database = rds.DBInstance( "Database", BackupRetentionPeriod=Ref(parameters.db_backup_retention), AllocatedStorage=Ref(parameters.db_storage_size), DBInstanceClass=Ref(parameters.db_instance_type), DBInstanceIdentifier=Ref("AWS::StackName"), Engine="MySQL", EngineVersion="5.6", MasterUsername="******", MasterUserPassword=Ref(parameters.db_password), StorageType="gp2", DeletionPolicy="Snapshot", DBSubnetGroupName=Ref(self.db_subnet_group), MultiAZ=True, VPCSecurityGroups=[Ref(self.db_security_group)], Tags=Tags(Name=Ref("AWS::StackName")), )
def create_rds_instance(self): rds_security_group_name = 'sgDatabaseServer' rds_security_group = self.add_resource( ec2.SecurityGroup( rds_security_group_name, GroupDescription='Enables access to database servers', VpcId=Ref(self.vpc_id), SecurityGroupIngress=[ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=VPC_CIDR, FromPort=p, ToPort=p) for p in [POSTGRESQL] ], SecurityGroupEgress=[ ec2.SecurityGroupRule(IpProtocol='tcp', CidrIp=VPC_CIDR, FromPort=p, ToPort=p) for p in [POSTGRESQL] ], Tags=self.get_tags(Name=rds_security_group_name))) rds_subnet_group_name = 'dbsngDatabaseServer' rds_subnet_group = self.add_resource( rds.DBSubnetGroup(rds_subnet_group_name, DBSubnetGroupDescription= 'Private subnets for the RDS instances', SubnetIds=Ref(self.private_subnets), Tags=self.get_tags(Name=rds_subnet_group_name))) rds_database_name = 'DatabaseServer' return self.add_resource( rds.DBInstance( rds_database_name, AllocatedStorage=128, AllowMajorVersionUpgrade=False, AutoMinorVersionUpgrade=True, BackupRetentionPeriod=30, DBInstanceClass=Ref(self.rds_instance_type), DBName=Ref(self.rds_db_name), DBParameterGroupName=Ref(self.rds_parameter_group_name), DBSubnetGroupName=Ref(rds_subnet_group), Engine='postgres', EngineVersion='9.6.14', MasterUsername=Ref(self.rds_username), MasterUserPassword=Ref(self.rds_password), MultiAZ=Ref(self.rds_multi_az), PreferredBackupWindow='04:00-04:30', # 12:00AM-12:30AM ET PreferredMaintenanceWindow= 'sun:04:30-sun:05:30', # SUN 12:30AM-01:30AM ET StorageType='gp2', VPCSecurityGroups=[Ref(rds_security_group)], Tags=self.get_tags(Name=rds_database_name)))
def buildMySQL(t, args): t.add_resource( ec2.SecurityGroup('DBSecurityGroup', GroupDescription='Patient Records', VpcId=Ref('VPC'), Tags=Tags(Name='MySQL Access'))) t.add_resource( ec2.SecurityGroupIngress( 'DBSGIngress', GroupId=Ref('DBSecurityGroup'), IpProtocol='-1', SourceSecurityGroupId=Ref('ApplicationSecurityGroup'))) t.add_resource( rds.DBSubnetGroup( 'RDSSubnetGroup', DBSubnetGroupDescription='MySQL node locations', SubnetIds=[Ref('PrivateSubnet1'), Ref('PrivateSubnet2')])) if (args.recovery): t.add_resource( rds.DBInstance('RDSInstance', DeletionPolicy='Delete' if args.dev else 'Snapshot', DBSnapshotIdentifier=Ref('RecoveryRDSSnapshotARN'), DBInstanceClass=Ref('RDSInstanceSize'), PubliclyAccessible=False, DBSubnetGroupName=Ref('RDSSubnetGroup'), VPCSecurityGroups=[Ref('DBSecurityGroup')], MultiAZ=not args.dev, Tags=Tags(Name='Patient Records'))) else: t.add_resource( rds.DBInstance('RDSInstance', DeletionPolicy='Delete' if args.dev else 'Snapshot', DBName='openemr', AllocatedStorage=Ref('PatientRecords'), DBInstanceClass=Ref('RDSInstanceSize'), Engine='MySQL', EngineVersion=FindInMap('RegionData', ref_region, 'MySQLVersion'), MasterUsername='******', MasterUserPassword=Ref('RDSPassword'), PubliclyAccessible=False, DBSubnetGroupName=Ref('RDSSubnetGroup'), VPCSecurityGroups=[Ref('DBSecurityGroup')], KmsKeyId=OpenEMRKeyID, StorageEncrypted=True, MultiAZ=not args.dev, Tags=Tags(Name='Patient Records'))) return t
def _subnet_group(self, t): if self.public: sn_list = self.vpc.output_public_subnets() else: sn_list = self.vpc.output_private_subnets() sn_group = t.add_resource( rds.DBSubnetGroup( '{}RDSSubnetGroup'.format(self.stack_name), DBSubnetGroupDescription='{} Subnet Group'.format( self.stack_name), SubnetIds=subnet_refs)) return sn_group
def add_resources(self): """Add resources to template.""" template = self.template variables = self.get_variables() dbsubnetgroup = template.add_resource( rds.DBSubnetGroup( 'DBSubnetGroup', SubnetIds=variables['PriSubnets'].ref, DBSubnetGroupDescription='RDS SubnetGroup', Tags=Tags(Name=Join( '-', ['RDSSubnet', Ref('EnvironmentName')]), ))) template.add_output( Output(dbsubnetgroup.title, Description='Physical ID of the DB Subnet Group', Value=Ref(dbsubnetgroup)))
def create_template(self): self.vars = self.validate_user_data() t = self.template t.add_description( "Sceptre stack - create an RDS DBInstance in an existing VPC.") self.db_subnet_group = t.add_resource( rds.DBSubnetGroup( "MyDBSubnetGroup", DBSubnetGroupDescription= "Subnets available for the RDS DB Instance", SubnetIds=[s.strip() for s in self.vars['Subnets'].split(',')], )) self.db_instance = t.add_resource( rds.DBInstance( "DBInstance", DBName=self.vars['DBName'], AllocatedStorage=self.vars['DBAllocatedStorage'], DBInstanceClass=self.vars['DBClass'], Engine=self.vars['Engine'], EngineVersion=self.vars['EngineVersion'], MasterUsername=self.vars['DBUser'], MasterUserPassword=self.vars['DBPassword'], DBSubnetGroupName=Ref(self.db_subnet_group), VPCSecurityGroups=self.vars['SecurityGroups'], PubliclyAccessible=self.vars['PubliclyAccessible'], )) t.add_output( Output( "DBEndPoint", Description="RDS DB instance endpoint", Value=GetAtt(self.db_instance, "Endpoint.Address"), )) t.add_output( Output( "DBPort", Description="Network port of the RDS DB instance", Value=GetAtt(self.db_instance, "Endpoint.Port"), ))
CidrIp=container_a_subnet_cidr, ), ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="3306", ToPort="3306", CidrIp=container_b_subnet_cidr, ), ], )) db_subnet_group = template.add_resource( rds.DBSubnetGroup( "DatabaseSubnetGroup", DBSubnetGroupDescription="Subnets available for the RDS DB Instance", SubnetIds=[ ImportValue(Sub(stack_base_name + '-network-ContainerASubnet')), ImportValue(Sub(stack_base_name + '-network-ContainerBSubnet')) ], )) db_instance = template.add_resource( rds.DBInstance( "MySQL", DBName=db_name, AllocatedStorage=db_allocated_storage, DBInstanceClass=db_class, DBInstanceIdentifier=Ref(AWS_STACK_NAME), Engine="MySQL", EngineVersion="5.6", MultiAZ=True, StorageType="gp2",
inrule, outrule = [ get_security_group(n + 'PostgresTcpRule') for n in ('In', 'Out') ] security_group = t.add_resource( ec2.SecurityGroup( "HyP3TCPAll", GroupDescription="Allow for all tcp traffic through port 5432", VpcId=Ref(hyp3_vpc), SecurityGroupIngress=[inrule], SecurityGroupEgress=[outrule])) mydbsubnetgroup = t.add_resource( rds.DBSubnetGroup( "MyDBSubnetGroup", DBSubnetGroupDescription="Subnets available for the RDS DB Instance", SubnetIds=[Ref(subnet) for subnet in get_public_subnets()], )) # Only certain versions of postgres are supported on the smaller instance types # https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html db = rds.DBInstance( "HyP3DB", DBInstanceIdentifier=Sub('${StackName}-hyp3-rds-instance', StackName=Ref('AWS::StackName')), AllocatedStorage="5", DBInstanceClass="db.t2.micro", DBName=Ref(db_name), Engine="postgres", EngineVersion="9.5.10", PubliclyAccessible=True,
GroupDescription="Ghost ECS Security Group.", VpcId=Ref(db_vpc), SecurityGroupIngress=[ ec2.SecurityGroupRule(IpProtocol="tcp", FromPort="2368", ToPort="2368", SourceSecurityGroupId=(GetAtt( alb_security_group, 'GroupId'))), ]) t.add_resource(ghost_host_security_group) # Create the DB Subnet Group dbsubnetgroup = t.add_resource( rds.DBSubnetGroup( "DBSubnetGroup", DBSubnetGroupDescription="Subnets available for the RDS DB Instance", SubnetIds=[Ref(db_subnet), Ref(db_subnet2)], )) # Create the DB's Security group which only allows access to memebers of the Ghost Host SG dbsecuritygroup = t.add_resource( ec2.SecurityGroup("DBSecurityGroup", GroupDescription="Security group for RDS DB Instance.", VpcId=Ref(db_vpc), SecurityGroupIngress=[ ec2.SecurityGroupRule(IpProtocol="tcp", FromPort="3306", ToPort="3306", SourceSecurityGroupId=(GetAtt( ghost_host_security_group, 'GroupId'))),
def build_hook(self): for db_label, db_config in self.config_map.iteritems(): (db_instance_type, db_name, db_user_name, db_user_password) = self.add_parameters(db_label, db_config) subnet_type = self.get_subnet_type(self.subnet_set) subnet_group = self.add_resource( rds.DBSubnetGroup( db_label.lower() + 'RdsSubnetGroup', DBSubnetGroupDescription= 'Subnet group for the RDS instance', SubnetIds=self.subnets[subnet_type][self.subnet_set])) rds_sg = self.add_resource( ec2.SecurityGroup( db_label.lower() + self.tier_name.title() + 'RdsSg', GroupDescription='Security group for %s RDS tier' % self.tier_name.lower(), VpcId=self.vpc_id)) rds_instance = self.add_resource( rds.DBInstance( db_label.lower() + self.tier_name.title() + 'RdsInstance', AllocatedStorage=db_config.get('volume_size', '100'), BackupRetentionPeriod=db_config.get( 'backup_retention_period', '30'), DBInstanceClass=Ref(db_instance_type), DBName=Ref(db_name), VPCSecurityGroups=[Ref(rds_sg)], DBSubnetGroupName=Ref(subnet_group), Engine=db_config.get('rds_engine', 'mysql'), EngineVersion=db_config.get('rds_engine_version', '5.6.19'), MasterUsername=Ref(db_user_name), MasterUserPassword=Ref(db_user_password), PreferredBackupWindow=db_config.get( 'preferred_backup_window', '02:00-02:30'), PreferredMaintenanceWindow=db_config.get( 'preferred_maintenance_window', 'sun:03:00-sun:04:00'), MultiAZ=True)) # Set the snapshot id if provided (and null out the db name to avoid cfn error) if db_config['snapshot_id']: rds_instance.DBSnapshotIdentifier = db_config['snapshot_id'] # DBName must be null when restoring from snapshot rds_instance.DBName = '' # Create the sg ingress rule for whatever port the rds instance needs ingress_rule = ec2.SecurityGroupIngress( db_label.lower() + self.tier_name.title() + 'RdsIngressRule', FromPort=GetAtt(rds_instance, "Endpoint.Port"), ToPort=GetAtt(rds_instance, "Endpoint.Port"), IpProtocol='tcp', GroupId=Ref(rds_sg)) # Set the allowed origin on the ingress rule according the requested connect_from setting # OR vpc_cidr in no other setting provided if self.connect_from_sg: ingress_rule.SourceSecurityGroupId = self.connect_from_sg elif self.connect_from_cidr: ingress_rule.CidrIp = self.connect_from_cidr else: ingress_rule.CidrIp = self.vpc_cidr self.add_resource(ingress_rule) # Add the connection endpoint output self.add_output( Output(db_label.lower() + self.tier_name.title() + 'RdsEndpoint', Value=Join('', [ Ref(db_user_name), '@', GetAtt(rds_instance, "Endpoint.Address"), ':', GetAtt(rds_instance, "Endpoint.Port") ]))) # Add the connection address output self.add_output( Output(db_label.lower() + self.tier_name.title() + 'RdsAddress', Value=GetAtt(rds_instance, "Endpoint.Address"))) self.data[db_label] = { 'rds': rds_instance, 'dbname': Ref(db_name), 'endpoint_address': GetAtt(rds_instance, 'Endpoint.Address'), 'endpoint_port': GetAtt(rds_instance, 'Endpoint.Port'), 'masteruser': Ref(db_user_name), 'masterpassword': Ref(db_user_password), 'securitygroup': rds_sg }
ToPort="5432", CidrIp=container_a_subnet_cidr, ), ec2.SecurityGroupRule( IpProtocol="tcp", FromPort="5432", ToPort="5432", CidrIp=container_b_subnet_cidr, ), ], ) db_subnet_group = rds.DBSubnetGroup( "DatabaseSubnetGroup", template=template, DBSubnetGroupDescription="Subnets available for the RDS DB Instance", SubnetIds=[Ref(container_a_subnet), Ref(container_b_subnet)], ) db_instance = rds.DBInstance( "PostgreSQL", template=template, DBName=Ref(db_name), AllocatedStorage=Ref(db_allocated_storage), DBInstanceClass=Ref(db_class), DBInstanceIdentifier=Ref(AWS_STACK_NAME), Engine="postgres", EngineVersion="9.4.5", MultiAZ=True, StorageType="gp2",
from troposphere import rds, Ref, GetAtt from stacks.parameters import ( subnet_ids, rds_master_password, rds_master_username, rds_db_name, ) from stacks.main.resources.rds_security_group import rds_security_group rds_subnet_group = rds.DBSubnetGroup( "RDSSubnetGroup", DBSubnetGroupDescription="RDS Subnet's Group", SubnetIds=Ref(subnet_ids), ) rds_instance = rds.DBInstance( "RDSInstance", VPCSecurityGroups=[GetAtt(rds_security_group, "GroupId")], DBSubnetGroupName=Ref(rds_subnet_group), AllocatedStorage=5, DBInstanceClass="db.t2.micro", Engine="postgres", MasterUsername=Ref(rds_master_username), MasterUserPassword=Ref(rds_master_password), DBName=Ref(rds_db_name), DeletionPolicy="Delete", )
def __init__(self, title, template, network_config, database_config): """ Class to create an RDS and DB subnet group in a vpc http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-database-instance.html https://github.com/cloudtools/troposphere/blob/master/troposphere/rds.py :param title: Title of the RDS and associated resources to be used in cloud formation :param template: Troposphere stack to append resources to :param network_config: object containing network related variables :param database_config: object containing database related variables """ super(Database, self).__init__(template=template, title=title, vpc=network_config.vpc) self.network_config = network_config self.db_subnet_group_title = title + 'Dsg' self.port = database_config.db_port self.rds_r53 = None # Add Tags tags = Tags(Name=self.db_subnet_group_title) tags += Tags(owner=database_config.owner) self.trop_db_subnet_group = template.add_resource( rds.DBSubnetGroup( self.db_subnet_group_title, DBSubnetGroupDescription=self.db_subnet_group_title, SubnetIds=network_config.private_subnets, Tags=tags)) rds_params = { 'AllocatedStorage': database_config.db_hdd_size, 'AllowMajorVersionUpgrade': True, 'AutoMinorVersionUpgrade': True, 'MultiAZ': True, 'DBInstanceClass': database_config.db_instance_type, 'DBSubnetGroupName': Ref(self.trop_db_subnet_group), 'DBName': database_config.db_name, 'DBInstanceIdentifier': Join('', [Ref('AWS::StackName'), self.title]), 'Engine': database_config.db_engine, 'Port': self.port, 'VPCSecurityGroups': [self.security_group], 'Tags': Tags(Name=Join('', [Ref('AWS::StackName'), '-', self.title])) } # Optional RDS Params opt_rds_params = { 'PreferredBackupWindow': database_config.db_backup_window, 'BackupRetentionPeriod': database_config.db_backup_retention, 'PreferredMaintenanceWindow': database_config.db_maintenance_window, 'StorageType': database_config.db_storage_type, } for k, v in opt_rds_params.items(): if v is not None: rds_params[k] = v # Remove username and password if SnapshotID present if database_config.db_snapshot_id is None: self.username = self.template.add_parameter( Parameter(self.title + 'MasterUsername', Type='String', Description='Master username of {0} RDS'.format( self.title), NoEcho=True)) self.password = self.template.add_parameter( Parameter(self.title + 'MasterPassword', Type='String', Description='Master password of {0} RDS'.format( self.title), NoEcho=True)) rds_params['MasterUsername'] = Ref(self.username) rds_params['MasterUserPassword'] = Ref(self.password) else: rds_params['DBSnapshotIdentifier'] = database_config.db_snapshot_id rds_params['DBName'] = '' # Create RDS self.trop_db = template.add_resource( rds.DBInstance(self.title, **rds_params)) self.create_r53_record()
CidrIp=Ref(param_db_client_location), ), Ref(AWS_NO_VALUE)), If( 'OrcaleCondition', ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='1521', ToPort='1521', CidrIp=Ref(param_db_client_location), ), Ref(AWS_NO_VALUE)), ], )) subnet_group = t.add_resource( rds.DBSubnetGroup('DatabaseSubnetGroup', DBSubnetGroupDescription='RDS subnet group', SubnetIds=Ref(param_subnetids))) param_group = t.add_resource( rds.DBParameterGroup( 'DatabaseParameterGroup', Description='RDS parameter group', Family=Ref(param_db_param_group_family), )) enhanced_monitoring_role = t.add_resource( iam.Role( 'EnhancedMonitoringRole', Condition='EnhancedMonitoringCondition', AssumeRolePolicyDocument=Policy(Statement=[ Statement(Effect=Allow,
), Ref(AWS_NO_VALUE)), If('MysqlCondition', ec2.SecurityGroupRule( IpProtocol='tcp', FromPort='3306', ToPort='3306', CidrIp=Ref(param_db_client_location), ), Ref(AWS_NO_VALUE)), ], )) subnet_group = t.add_resource(rds.DBSubnetGroup( 'DatabaseSubnetGroup', DBSubnetGroupDescription='RDS subnet group', SubnetIds=Ref(param_subnetids) )) rds_cluster = t.add_resource(rds.DBCluster( 'RdsCluster', DeletionPolicy=Delete, # DBSnapshotIdentifier=If('UseSnapshotCondition', Ref(param_db_snapshot), # Ref(AWS_NO_VALUE)), MasterUsername=If('NewDatabaseCondition', Ref(param_db_user), Ref(AWS_NO_VALUE)), MasterUserPassword=If('NewDatabaseCondition', Ref(param_db_password), Ref(AWS_NO_VALUE)), Engine=Ref(param_db_engine),
def build_template(self): t = self._init_template() username = "******" passwd = "rdspasswd" instance_type = t.add_parameter( Parameter("Input{}RDSInstanceType".format(self.stack_name), Type='String', Default='db.t2.medium')) instance_size = t.add_parameter( Parameter("Input{}RDSSize".format(self.stack_name), Type='String', Default='20')) storage_type = t.add_parameter( Parameter("Input{}RDSStorageType".format(self.stack_name), Type='String', Default='gp2')) backup_retention = t.add_parameter( Parameter('InputBackupRetentionPeriod', Type='String', Default='7')) sn_list = self.vpc.output_private_subnets() if self.public: sn_list = self.vpc.output_public_subnets() subnet_refs = [ Ref(t.add_parameter(Parameter(i, Type='String'))) for i in sn_list ] sg_refs = [ Ref( t.add_parameter( Parameter(i.output_security_group(), Type='String'))) for i in self.security_groups ] params = t.add_resource( rds.DBParameterGroup( '{}RDSParamGroup'.format(self.stack_name), Family='{}{}'.format(self.db_type, self.db_version), Description="ParamGroup for {}".format(self.name), Parameters=self.params)) sn_groups = t.add_resource( rds.DBSubnetGroup( '{}RDSSubnetGroup'.format(self.stack_name), DBSubnetGroupDescription='{} Subnet Group'.format( self.stack_name), SubnetIds=subnet_refs)) db = t.add_resource( rds.DBInstance( '{}RDSInstance'.format(self.stack_name), AllocatedStorage=Ref(instance_size), BackupRetentionPeriod=Ref(backup_retention), DBInstanceClass=Ref(instance_type), DBSubnetGroupName=Ref(sn_groups), Engine=self.db_type, EngineVersion=self.db_version, DBParameterGroupName=Ref(params), MasterUsername=username, MasterUserPassword=passwd, MultiAZ=self.multiaz, PubliclyAccessible=self.public, StorageType=Ref(storage_type), VPCSecurityGroups=sg_refs, )) t.add_output([ Output('{}RDSInstance'.format(self.stack_name), Value=Ref(db)), Output('{}Endpoint'.format(self.stack_name), Value=GetAtt(db, 'Endpoint.Address')) ]) return t
def configure(self): rds_metadata = constants.ENVIRONMENTS[self.env]['rds'] self.name = 'rds' self.add_description('Sets up an RDS Instance in a VPC') self.get_standard_parameters() self.get_default_security_groups() for db in rds_metadata: name = self.env + db['name'] # get secrets env_name = "DB_{}_".format(db['name']) db_user = db.get('admin_user', os.environ.get(env_name + "USER", None)) db_pass = db.get('admin_pass', os.environ.get(env_name + "PASS", None)) if (db_user or db_pass) is None: raise KeyError( "Database user or password not set. Please set {0}USER or {0}PASS environment variables" .format(env_name)) if db_user in ("rdsadmin", "admin"): raise ValueError( "Database admin '{}' cannot be used as it is a reserved word used by the engine" .format(db_user)) tags = self.get_tags(service_override=self.name, role_override=db['name']) security_group = self.add_resource( ec2.SecurityGroup( '{}RDSSecurityGroup'.format(name), VpcId=self.vpc_id, GroupDescription='Security Group for {} Access'.format( self.name), SecurityGroupIngress=[{ 'IpProtocol': 'tcp', 'FromPort': 5432, 'ToPort': 5432, 'CidrIp': self.vpc_cidr } # Allow DB access ], Tags=tags)) self.add_security_group(Ref(security_group)) # Default to true for preferred subnet unless using multi_az preferred_only = False if db.get('multi_az') is True else db.get( 'preferred_only', True) rds_subnet_group = self.add_resource( rds.DBSubnetGroup( '{}RDSSubnetGroup'.format(name), DBSubnetGroupDescription='Subnet group for {} RDS'.format( name), SubnetIds=list( map( lambda x: x['SubnetId'], self.get_subnets( 'private', _preferred_only=preferred_only))))) rds_parameter_group = self.add_resource( rds.DBParameterGroup( '{}DBParameterGroup'.format(name), Description='RDS ParameterGroup for {}'.format(name), Family=db.get('engine_family', 'postgres11'), Parameters={ 'log_min_duration_statement': 250, 'max_connections': '{DBInstanceClassMemory/10485760}', 'pg_stat_statements.track': 'all', 'pg_stat_statements.max': db.get('max_logged_statements', '1000') }, Tags=tags)) rds_instance = self.add_resource( rds.DBInstance( '{}RDSInstance'.format(name), AllocatedStorage=db['allocated_storage'], AutoMinorVersionUpgrade=True, BackupRetentionPeriod=7, DBInstanceClass=db['instance_type'], DBInstanceIdentifier=name, DBParameterGroupName=Ref(rds_parameter_group), #DBSnapshotIdentifier=db['snapshot_id'], DBSubnetGroupName=Ref(rds_subnet_group), Engine='postgres', EngineVersion=db.get('engine_version', '11.5'), LicenseModel='postgresql-license', MultiAZ=db.get('multi_az', False), PreferredBackupWindow='06:00-07:00', PreferredMaintenanceWindow='sat:07:00-sat:08:00', PubliclyAccessible=False, StorageEncrypted=True, StorageType='gp2', Tags=tags, VPCSecurityGroups=self.security_groups, MasterUsername=db_user, MasterUserPassword=db_pass, )) if self.get_partition( ) == 'aws': # aws-us-gov and aws-cn may not have route53 public zones hosted_zone = constants.ENVIRONMENTS[self.env]['route53_zone'] self.add_resource( route53.RecordSetGroup( '{}Route53'.format(name), HostedZoneName=hosted_zone, RecordSets=[ route53.RecordSet(Name='{}.rds.{}'.format( db['name'], hosted_zone), ResourceRecords=[ GetAtt( rds_instance, 'Endpoint.Address') ], Type='CNAME', TTL=600) ]))
CidrIp=Ref(private_subnet_a_cidr), ), ec2.SecurityGroupRule( IpProtocol="tcp", FromPort=FindInMap("RdsEngineMap", Ref(db_engine), "Port"), ToPort=FindInMap("RdsEngineMap", Ref(db_engine), "Port"), CidrIp=Ref(private_subnet_b_cidr), ), ], Tags=Tags(Name=Join("-", [Ref("AWS::StackName"), "rds"]), ), ) db_subnet_group = rds.DBSubnetGroup( "DatabaseSubnetGroup", template=template, Condition=db_condition, DBSubnetGroupDescription="Subnets available for the RDS DB Instance", SubnetIds=[Ref(private_subnet_a), Ref(private_subnet_b)], ) db_instance = rds.DBInstance( "DatabaseInstance", template=template, DBName=Ref(db_name), Condition=db_condition, AllocatedStorage=Ref(db_allocated_storage), DBInstanceClass=Ref(db_class), Engine=Ref(db_engine), EngineVersion=Ref(db_engine_version), MultiAZ=Ref(db_multi_az), StorageEncrypted=use_aes256_encryption,
def __init__(self, tags=dict()): super(RDSFactory, self).__init__() self.tags = tags # Largely copied from # https://github.com/cloudtools/troposphere/blob/master/examples/RDS_VPC.py # Each parameter is followed by the resources which depend on it. # VPC and security groups vpcid = Parameter( 'VpcId', Type='String', Description='Id of existing VPC' ) private_hosted_zone_id = Parameter( 'PrivateHostedZoneId', Type='String', Description='Private hosted zone id' ) db_security_group = ec2.SecurityGroup( 'sgDatabase', GroupDescription='Security group for RDS DB Instance.', VpcId=Ref(vpcid), Tags=Tags(Name='Database', **self.tags) ) # Subnets subnets = Parameter( 'AppServerSubnets', Type='CommaDelimitedList', Description='List of SubnetIds spanning at least two AZs in VPC' ) subnet_group = rds.DBSubnetGroup( 'CacDbSubnetGroup', DBSubnetGroupDescription='Subnets available for Cac RDS instance', SubnetIds=Ref(subnets), Tags=Tags(Name='RDSSubnetGroup', **self.tags) ) # Database db_name = Parameter( 'DbName', Description='Name of the database to be created', Type='String', MinLength='5', MaxLength='63', AllowedPattern='[a-zA-Z_][a-zA-Z0-9_]*', ConstraintDescription='Name must begin with a letter and contain only alphanumerics' ) db_user = Parameter( 'DbUser', NoEcho=True, Description='Database admin user account', Type='String', MinLength='5', MaxLength='16', AllowedPattern='[a-zA-Z][a-zA-Z0-9]*', ConstraintDescription='Name must begin with a letter and contain only alphanumerics' ) db_password = Parameter( 'DbPassword', NoEcho=True, Description='Database admin account password', Type='String', MinLength='8', ) db_instance_class = Parameter( 'DbInstanceClass', Default='db.m3.medium', Description='Database instance class', Type='String', AllowedValues=RDS_INSTANCE_TYPES ) db_storage = Parameter( 'DbStorage', Description='Available database storage (GB)', Default='100', Type='Number', MaxValue='1024', ConstraintDescription='Storage space must be less than 1024GB', ) db_dns_name = Parameter( 'DbDNSName', Type='String', Description='Private DNS name for database' ) database = rds.DBInstance( 'CacDb', DBName=Ref(db_name), AllocatedStorage=Ref(db_storage), DBInstanceClass=Ref(db_instance_class), Engine='postgres', EngineVersion='9.3', MasterUsername=Ref(db_user), MasterUserPassword=Ref(db_password), DBSubnetGroupName=Ref(subnet_group), VPCSecurityGroups=[Ref(db_security_group)], MultiAZ=True, Tags=Tags(Name='CacDB', **self.tags) ) db_dns_record = route53.RecordSetType( 'rsDatabase', Name=Ref(db_dns_name), ResourceRecords=[GetAtt('CacDb', 'Endpoint.Address')], TTL=600, Type='CNAME', HostedZoneId=Ref(private_hosted_zone_id), ) # Outputs rds_endpoint = Output( 'CacDbEndpoint', Description='Endpoint to which Postgres clients should connect', Value=GetAtt('CacDb', 'Endpoint.Address') ) database_name = Output( 'CacDbName', Description='Name of database created on Cac RDS instance', Value=Ref(db_name) ) db_sg = Output( 'DatabaseSecurityGroup', Description='Security Group of Database', Value=GetAtt('sgDatabase', 'GroupId') ) self.parameters = [vpcid, private_hosted_zone_id, subnets, db_name, db_user, db_password, db_instance_class, db_storage, db_dns_name] self.resources = [db_security_group, subnet_group, database, db_dns_record] self.outputs = [rds_endpoint, database_name, db_sg]
ec2.SecurityGroupRule( Description='Redis access from the API containers', IpProtocol='tcp', FromPort='6379', ToPort='6379', SourceSecurityGroupName=Ref(api_security_group) ) ] ) ) # Create the RDS instance. database_subnet_group = template.add_resource( rds.DBSubnetGroup( 'DatabaseSubnetGroup', DBSubnetGroupDescription='Subnets available for the RDS instance', SubnetIds=Ref(subnets) ) ) database = template.add_resource( rds.DBInstance( 'Database', DBName=Ref(database_name), AllocatedStorage=Ref(database_allocated_storage), DBInstanceClass=Ref(database_class), Engine='MySQL', EngineVersion='5.7', MasterUsername=Ref(database_username), MasterUserPassword=Ref(database_password), VPCSecurityGroups=[GetAtt(database_security_group, 'GroupId')],
CopyTagsToSnapshot=True, MonitoringInterval=0, EnableIAMDatabaseAuthentication=False, EnablePerformanceInsights=False, DeletionProtection=False, DBSubnetGroupName='default-vpc-0e12e822c1e5549cf', VPCSecurityGroups=['sg-06b6268a569621a85'], MaxAllocatedStorage=1000, DBParameterGroupName='default.mysql5.7', OptionGroupName='default:mysql-5-7', CACertificateIdentifier='rds-ca-2019')) RDSDBSubnetGroup = template.add_resource( rds.DBSubnetGroup( 'RDSDBSubnetGroup', DBSubnetGroupDescription='Created from the RDS Management Console', DBSubnetGroupName='default-vpc-0e12e822c1e5549cf', SubnetIds=['subnet-08d3101feec0e17da', 'subnet-0c86eeb5d3ab2e031'])) RDSDBSecurityGroup = template.add_resource( rds.DBSecurityGroup('RDSDBSecurityGroup', GroupDescription=Ref(ECSCluster))) EC2SecurityGroup = template.add_resource( ec2.SecurityGroup('EC2SecurityGroup', GroupDescription='2020-02-23T21:47:44.823Z', GroupName='ws-cur-1498', VpcId='vpc-0e12e822c1e5549cf', SecurityGroupIngress=[ ec2.SecurityGroupRule(CidrIp='0.0.0.0/0', FromPort=80,