Skip to content
This repository was archived by the owner on Jul 7, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions stacker_blueprints/rds/aurora/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ class Cluster(Blueprint):
"default": "",
"description": "Internal domain name, if you have one."
},
"AllowedCIDRs": {
"type": list,
"description": "List of CIDRs to allow for DB ingress",
"default": []
}
}

def engine(self):
Expand Down Expand Up @@ -179,6 +184,18 @@ def create_security_group(self):
)
)
self.security_group = Ref(sg)

if variables["AllowedCIDRs"]:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we tend to do this in a separate stack @ Remind - we found that we wanted to update security rules more often than databases themselves, so it felt safer. It also meant we could use the full security group rule stack, which can build just about any sort of rule (we tend to use SecurityGroups as the source of the rules, not CIDR). I think this also gets trickier when you start working with Aurora, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have a good point, this isn't really that flexible. Would you find the TroposphereType to be a good middle ground, as you mentioned in the other issue? I find having seperate stacks for the SGs a bit cumbersome and usually avoid it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually - there's an issue with that, in that the rules wouldn't have a SecurityGroup attribute, which is required for the SecurityGroupIngress type. That would normally be set to the SG that is created here. Though didn't you just add a feature to TroposphereType that allows for modifying the resource after the fact, not requiring immediate validation? If so, then that'd work with this. Otherwise you could do what we did in the security_rules.py blueprint and just accept a dict, then use from_dict after you've added the SecurityGroup attribute.

for i, cidr in enumerate(variables["AllowedCIDRs"]):
t.add_resource(
ec2.SecurityGroupIngress(
'DBSecurityGroupIngress{}'.format(i + 1),
IpProtocol='tcp',
FromPort=self.port(),
ToPort=self.port(),
CidrIp=cidr,
GroupId=Ref(sg)))

t.add_output(Output("SecurityGroup", Value=self.security_group))

def get_master_endpoint(self):
Expand Down Expand Up @@ -270,3 +287,6 @@ def create_template(self):
class AuroraCluster(Cluster):
def engine(self):
return "aurora"

def port(self):
return 3306
44 changes: 36 additions & 8 deletions stacker_blueprints/rds/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

RDS_ENGINES = ["MySQL", "oracle-se1", "oracle-se", "oracle-ee", "sqlserver-ee",
"sqlserver-se", "sqlserver-ex", "sqlserver-web", "postgres",
"aurora"]
"aurora", "mariadb"]

# Resource name constants
SUBNET_GROUP = "RDSSubnetGroup"
Expand Down Expand Up @@ -163,6 +163,11 @@ class BaseRDS(Blueprint):
"database instance.",
"default": {}
},
"AllowedCIDRs": {
"type": list,
"description": "List of CIDRs to allow for DB ingress",
"default": []
}
}

def engine(self):
Expand Down Expand Up @@ -231,6 +236,17 @@ def create_security_group(self):
)
)
self.security_group = Ref(sg)

if variables["AllowedCIDRs"]:
for i, cidr in enumerate(variables["AllowedCIDRs"]):
t.add_resource(
ec2.SecurityGroupIngress(
'DBSecurityGroupIngress{}'.format(i + 1),
IpProtocol='tcp',
FromPort=self.port(),
ToPort=self.port(),
CidrIp=cidr,
GroupId=Ref(sg)))
t.add_output(Output("SecurityGroup", Value=self.security_group))

def get_db_endpoint(self):
Expand Down Expand Up @@ -267,6 +283,15 @@ def create_option_group(self):
)
)

def get_settings_attrs(self):
attrs = {}
if "OptionGroup" in self.template.resources:
attrs["OptionGroupName"] = Ref("OptionGroup")
if "ParameterGroup" in self.template.resources:
attrs["DBParameterGroupName"] = Ref("ParameterGroup")

return attrs

def create_rds(self):
t = self.template
variables = self.get_variables()
Expand Down Expand Up @@ -390,15 +415,14 @@ def defined_variables(self):
"type": bool,
"description": "Set to 'false' to disable encrypted storage.",
"default": True,
},

}
}
variables.update(additional)
return variables

def get_common_attrs(self):
variables = self.get_variables()
return {
attrs = {
"AllocatedStorage": variables["AllocatedStorage"],
"AllowMajorVersionUpgrade": variables["AllowMajorVersionUpgrade"],
"AutoMinorVersionUpgrade": variables["AutoMinorVersionUpgrade"],
Expand All @@ -407,7 +431,6 @@ def get_common_attrs(self):
"DBInstanceClass": variables["InstanceType"],
"DBInstanceIdentifier": variables["DBInstanceIdentifier"],
"DBSnapshotIdentifier": self.get_db_snapshot_identifier(),
"DBParameterGroupName": Ref("ParameterGroup"),
"DBSubnetGroupName": Ref(SUBNET_GROUP),
"Engine": self.engine() or variables["Engine"],
"EngineVersion": variables["EngineVersion"],
Expand All @@ -416,14 +439,15 @@ def get_common_attrs(self):
"MasterUsername": variables["MasterUser"],
"MasterUserPassword": Ref("MasterUserPassword"),
"MultiAZ": variables["MultiAZ"],
"OptionGroupName": Ref("OptionGroup"),
"PreferredBackupWindow": variables["PreferredBackupWindow"],
"PreferredMaintenanceWindow":
variables["PreferredMaintenanceWindow"],
"StorageEncrypted": variables["StorageEncrypted"],
"VPCSecurityGroups": [self.security_group, ],
"Tags": self.get_tags(),
}
attrs.update(self.get_settings_attrs())
return attrs


class ReadReplica(BaseRDS):
Expand Down Expand Up @@ -459,7 +483,7 @@ def defined_variables(self):
def get_common_attrs(self):
variables = self.get_variables()

return {
attrs = {
"SourceDBInstanceIdentifier": variables["MasterDatabaseId"],
"AllocatedStorage": variables["AllocatedStorage"],
"AllowMajorVersionUpgrade": variables["AllowMajorVersionUpgrade"],
Expand All @@ -475,6 +499,8 @@ def get_common_attrs(self):
"VPCSecurityGroups": [self.security_group, ],
"Tags": self.get_tags(),
}
attrs.update(self.get_settings_attrs())
return attrs


class ClusterInstance(BaseRDS):
Expand All @@ -494,7 +520,7 @@ def create_subnet_group(self):
def get_common_attrs(self):
variables = self.get_variables()

return {
attrs = {
"DBClusterIdentifier": variables["DBClusterIdentifier"],
"AllowMajorVersionUpgrade": variables["AllowMajorVersionUpgrade"],
"AutoMinorVersionUpgrade": variables["AutoMinorVersionUpgrade"],
Expand All @@ -506,3 +532,5 @@ def get_common_attrs(self):
"LicenseModel": Ref("AWS::NoValue"),
"Tags": self.get_tags(),
}
attrs.update(self.get_settings_attrs())
return attrs
17 changes: 17 additions & 0 deletions stacker_blueprints/rds/mariadb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from .base import MasterInstance, ReadReplica


class MariaDBMixin(object):
def engine(self):
return "mariadb"

def port(self):
return 3306


class MasterInstance(MariaDBMixin, MasterInstance):
pass


class ReadReplica(MariaDBMixin, ReadReplica):
pass
3 changes: 3 additions & 0 deletions stacker_blueprints/rds/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ class MySQLMixin(object):
def engine(self):
return "MySQL"

def port(self):
return 3306


class MasterInstance(MySQLMixin, MasterInstance):
pass
Expand Down
3 changes: 3 additions & 0 deletions stacker_blueprints/rds/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ class PostgresMixin(object):
def engine(self):
return "postgres"

def port(self):
return 5432


class MasterInstance(PostgresMixin, MasterInstance):
pass
Expand Down