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 test_replica_settings_are_inherited(self): rds_instance = rds.DBInstance( "SomeTitle", AllocatedStorage=1, DBInstanceClass="db.m1.small", Engine="MySQL", SourceDBInstanceIdentifier="SomeSourceDBInstanceIdentifier", BackupRetentionPeriod="1", DBName="SomeName", MasterUsername="******", MasterUserPassword="******", PreferredBackupWindow="10:00-11:00", MultiAZ=True, DBSnapshotIdentifier="SomeDBSnapshotIdentifier", ) with self.assertRaisesRegex( ValueError, "BackupRetentionPeriod, DBName, DBSnapshotIdentifier, " "MasterUserPassword, MasterUsername, " "MultiAZ, PreferredBackupWindow " "properties can't be provided when " "SourceDBInstanceIdentifier is present " "AWS::RDS::DBInstance.", ): rds_instance.to_dict()
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 test_replica_settings_are_inherited(self): rds_instance = rds.DBInstance( 'SomeTitle', AllocatedStorage=1, DBInstanceClass='db.m1.small', Engine='MySQL', SourceDBInstanceIdentifier='SomeSourceDBInstanceIdentifier', BackupRetentionPeriod="1", DBName="SomeName", MasterUsername="******", MasterUserPassword="******", PreferredBackupWindow="10:00-11:00", MultiAZ=True, DBSnapshotIdentifier="SomeDBSnapshotIdentifier", ) with self.assertRaisesRegexp( ValueError, 'BackupRetentionPeriod, DBName, DBSnapshotIdentifier, ' 'MasterUserPassword, MasterUsername, ' 'MultiAZ, PreferredBackupWindow ' 'properties can\'t be provided when ' 'SourceDBInstanceIdentifier is present ' 'AWS::RDS::DBInstance.'): rds_instance.JSONrepr()
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 __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 test_it_allows_an_rds_replica(self): rds_instance = rds.DBInstance( 'SomeTitle', AllocatedStorage=1, DBInstanceClass='db.m1.small', Engine='MySQL', SourceDBInstanceIdentifier='SomeSourceDBInstanceIdentifier') rds_instance.JSONrepr()
def test_it_allows_an_rds_instance_with_master_username_and_password(self): rds_instance = rds.DBInstance('SomeTitle', AllocatedStorage=1, DBInstanceClass='db.m1.small', Engine='MySQL', MasterUsername='******', MasterUserPassword='******') rds_instance.JSONrepr()
def test_it_allows_an_rds_instance_created_from_a_snapshot(self): rds_instance = rds.DBInstance( 'SomeTitle', AllocatedStorage=100, DBInstanceClass='db.m1.small', Engine='MySQL', DBSnapshotIdentifier='SomeSnapshotIdentifier') rds_instance.JSONrepr()
def test_io1_storage_type_and_iops(self): i = rds.DBInstance("NoAZAndMultiAZ", MasterUsername="******", MasterUserPassword="******", AllocatedStorage=10, DBInstanceClass="db.m1.small", Engine="postgres", StorageType='io1') with self.assertRaisesRegexp(ValueError, "Must specify Iops if "): i.JSONrepr()
def test_it_allows_an_rds_instance_created_from_a_snapshot(self): rds_instance = rds.DBInstance( "SomeTitle", AllocatedStorage=100, DBInstanceClass="db.m1.small", Engine="MySQL", DBSnapshotIdentifier="SomeSnapshotIdentifier", ) rds_instance.to_dict()
def test_snapshot(self): i = rds.DBInstance( 'MyDB', DBName='test', AllocatedStorage=25, DBInstanceClass='db.m4.large', DBSubnetGroupName='default', DBSnapshotIdentifier='id', ) i.JSONrepr()
def test_snapshot(self): i = rds.DBInstance( "MyDB", DBName="test", AllocatedStorage=25, DBInstanceClass="db.m4.large", DBSubnetGroupName="default", DBSnapshotIdentifier="id", ) i.to_dict()
def test_it_allows_an_rds_replica(self): rds_instance = rds.DBInstance( "SomeTitle", AllocatedStorage=1, DBInstanceClass="db.m1.small", Engine="MySQL", SourceDBInstanceIdentifier="SomeSourceDBInstanceIdentifier", ) rds_instance.to_dict()
def test_no_snapshot_or_engine(self): i = rds.DBInstance( "MyDB", DBName="test", AllocatedStorage=25, DBInstanceClass="db.m4.large", DBSubnetGroupName="default", ) with self.assertRaisesRegex(ValueError, "Resource Engine is required"): i.to_dict()
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 test_no_snapshot_or_engine(self): i = rds.DBInstance( 'MyDB', DBName='test', AllocatedStorage=25, DBInstanceClass='db.m4.large', DBSubnetGroupName='default', ) with self.assertRaisesRegexp(ValueError, "Resource Engine is required"): i.JSONrepr()
def test_fail_az_and_multiaz(self): i = rds.DBInstance("NoAZAndMultiAZ", MasterUsername="******", MasterUserPassword="******", AllocatedStorage=10, DBInstanceClass="db.m1.small", Engine="postgres", AvailabilityZone="us-east-1", MultiAZ=True) with self.assertRaisesRegexp(ValueError, "if MultiAZ is set to "): i.JSONrepr()
def test_snapshot_and_engine(self): i = rds.DBInstance( 'MyDB', DBName='test', AllocatedStorage=25, DBInstanceClass='db.m4.large', DBSubnetGroupName='default', DBSnapshotIdentifier='id', Engine="postgres", ) i.to_dict()
def test_it_allows_an_rds_instance_with_master_username_and_password(self): rds_instance = rds.DBInstance( "SomeTitle", AllocatedStorage=1, DBInstanceClass="db.m1.small", Engine="MySQL", MasterUsername="******", MasterUserPassword="******", ) rds_instance.to_dict()
def test_it_rds_instances_require_either_a_snapshot_or_credentials(self): rds_instance = rds.DBInstance('SomeTitle', AllocatedStorage=1, DBInstanceClass='db.m1.small', Engine='MySQL') with self.assertRaisesRegexp( ValueError, 'Either \(MasterUsername and MasterUserPassword\) or' ' DBSnapshotIdentifier are required'): rds_instance.JSONrepr()
def test_it_allows_an_rds_instance_with_iops(self): rds_instance = rds.DBInstance( "SomeTitle", AllocatedStorage=200, DBInstanceClass="db.m1.small", Engine="MySQL", MasterUsername="******", MasterUserPassword="******", StorageType="io1", Iops=2000, ) rds_instance.to_dict()
def create_read_only_database_resource(template, database_class_parameter, database_resource, read_only_database_security_group_resource): return template.add_resource( rds.DBInstance( 'ReadOnlyDatabase', DBInstanceClass=Ref(database_class_parameter), Engine='MySQL', EngineVersion='5.7', SourceDBInstanceIdentifier=Ref(database_resource), VPCSecurityGroups=[ GetAtt(read_only_database_security_group_resource, 'GroupId')], PubliclyAccessible=True ) )
def test_it_allows_an_rds_instance_with_iops(self): rds_instance = rds.DBInstance( 'SomeTitle', AllocatedStorage=200, DBInstanceClass='db.m1.small', Engine='MySQL', MasterUsername='******', MasterUserPassword='******', StorageType='io1', Iops=2000, ) rds_instance.to_dict()
def test_it_rds_instances_require_either_a_snapshot_or_credentials(self): rds_instance = rds.DBInstance( "SomeTitle", AllocatedStorage=1, DBInstanceClass="db.m1.small", Engine="MySQL", ) with self.assertRaisesRegex( ValueError, r"Either \(MasterUsername and MasterUserPassword\) or" r" DBSnapshotIdentifier are required", ): rds_instance.to_dict()
def test_az_and_multiaz_funcs(self): db_az = "us-east-1" db_multi_az = Parameter("dbmultiaz", Type="String") i = rds.DBInstance( "NoAZAndMultiAZ", MasterUsername="******", MasterUserPassword="******", AllocatedStorage=10, DBInstanceClass="db.m1.small", Engine="postgres", AvailabilityZone=If("db_az", Ref(db_az), Ref(AWS_NO_VALUE)), MultiAZ=Ref(db_multi_az), ) i.validate()
def test_it_allows_an_rds_instance_with_iops(self): # ensure troposphere works with longs and ints long_number = 2**100 rds_instance = rds.DBInstance( 'SomeTitle', AllocatedStorage=1, DBInstanceClass='db.m1.small', Engine='MySQL', MasterUsername='******', MasterUserPassword='******', StorageType='io1', Iops=long_number, ) rds_instance.JSONrepr()
def test_it_rds_instances_require_encryption_if_kms_key_provided(self): rds_instance = rds.DBInstance( 'SomeTitle', AllocatedStorage=1, DBInstanceClass='db.m1.small', Engine='MySQL', MasterUsername='******', MasterUserPassword='******', KmsKeyId='arn:aws:kms:us-east-1:123456789012:key/' '12345678-1234-1234-1234-123456789012') with self.assertRaisesRegexp( ValueError, 'If KmsKeyId is provided, StorageEncrypted is required'): rds_instance.JSONrepr()
def rds_adder(self, instance_identifier, allocated_storage, db_subnet_group, rds_group, db_size, db_name='MyDB', storage_type='gp2', engine_version='5.5.40a', storage_engine='MySQL', publicly_accessible=False): db_names = '' db_asf = (db_name.upper(), 'DNS') if publicly_accessible is False: publicly_accessible = "false" else: publicly_accessible = "true" dbinstance = rds.DBInstance( db_name, DBInstanceIdentifier=instance_identifier, Engine=storage_engine, EngineVersion=engine_version, MasterUsername=If("NotRestoringFromSnapshot", Ref("RDSDBUser"), Ref("AWS::NoValue")), MasterUserPassword=If("NotRestoringFromSnapshot", Ref("RDSDBPassword"), Ref("AWS::NoValue")), AllocatedStorage=allocated_storage, DBSnapshotIdentifier=If("NotRestoringFromSnapshot", Ref("AWS::NoValue"), Ref("RDSSnapshot")), StorageType=storage_type, DBSubnetGroupName=db_subnet_group, PubliclyAccessible=publicly_accessible, VPCSecurityGroups=rds_group, DBInstanceClass=db_size, StorageEncrypted=If("NotRestoringFromSnapshot", True, Ref("AWS::NoValue"))) dbdnsrecord = RecordSetType( db_names.join(db_asf), HostedZoneName=Join("", [Ref("RDSDNSDomain"), "."]), Name=Join("", [Ref("RDSDNSName"), ".", Ref("RDSDNSDomain"), "."]), Type="CNAME", TTL="900", ResourceRecords=[GetAtt(dbinstance, "Endpoint.Address")], ) self.template.add_resource(dbinstance) self.template.add_resource(dbdnsrecord)
def test_it_rds_instances_require_encryption_if_kms_key_provided(self): rds_instance = rds.DBInstance( "SomeTitle", AllocatedStorage=1, DBInstanceClass="db.m1.small", Engine="MySQL", MasterUsername="******", MasterUserPassword="******", KmsKeyId="arn:aws:kms:us-east-1:123456789012:key/" "12345678-1234-1234-1234-123456789012", ) with self.assertRaisesRegex( ValueError, "If KmsKeyId is provided, StorageEncrypted is required" ): rds_instance.to_dict()