Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RDS: Add DBSubnet resource, VPC security groups #13

Closed
wants to merge 9 commits into from

Conversation

RaitoBezarius
Copy link
Member

@RaitoBezarius RaitoBezarius commented Oct 30, 2019

This commit enables EC2 RDS resource to use:

  • DBSubnets
  • VPC security groups

As a result, it adds a DBSubnet resource which consists of at least 2
VPC subnets containing at least each AZ of your region.

It enables support of RDS in a VPC.

This makes it possible to use RDS in a VPC setup, i.e. in EC2-VPC.

Will fix #6.

This commit enables EC2 RDS resource to use:

- DBSubnets
- VPC security groups

As a result, it adds a DBSubnet resource which consists of at least 2
VPC subnets containing at least each AZ of your region.

It enables support of RDS in a VPC.

This makes it possible to use RDS in a VPC setup, i.e. in EC2-VPC.
@AmineChikhaoui
Copy link
Member

Hi @RaitoBezarius , would you mind adding a working example under examples/ ?

@RaitoBezarius
Copy link
Member Author

@AmineChikhaoui Sure, will do in some minutes.

@RaitoBezarius
Copy link
Member Author

It has been 300 minutes but it's done :) @AmineChikhaoui

@AmineChikhaoui
Copy link
Member

No worries @RaitoBezarius , thanks !
I'll try to play with it later this evening.

Comment on lines 23 to 32
region = mkOption {
type = types.str;
description = "Amazon RDS DB subnet group region.";
};

accessKeyId = mkOption {
default = "";
type = types.str;
description = "The AWS Access Key ID.";
};
Copy link
Contributor

Choose a reason for hiding this comment

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

u can use imports = [ ./common-ec2-auth-options.nix ]; for these options like we do in the other modules for example

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure.

default = [];
type = types.listOf (types.either types.str (resource "vpc-subnet"));
apply = map (x: if builtins.isString x then x else "res-" + x._name + "." + x._type + ".subnetId");
description = "List of VPC subnets to use for this DB subnet group (must contain at least a subnet for each AZ), it can be a VPC Subnet resource or a string representing the ID of the VPC Subnet.";
Copy link
Contributor

Choose a reason for hiding this comment

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

break into multiple lines.

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay!

@PsyanticY
Copy link
Contributor

Update this line to if dbinstance.status not in {'creating', 'backing-up', 'available', 'modifying', 'configuring-enhanced-monitoring'}:

engine = "postgres";
dbName = "testNixOps";
multiAZ = true;
vpcSecurityGroups = [ resources.ec2SecurityGroups.database ];
Copy link
Contributor

@PsyanticY PsyanticY Nov 1, 2019

Choose a reason for hiding this comment

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

should be vpcSecurityGroupIds

I also needed to add securityGroups = []; for it to work.
@AmineChikhaoui what about removing support for ec2 classic altogether ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Right!

@RaitoBezarius
Copy link
Member Author

Update this line to if dbinstance.status not in {'creating', 'backing-up', 'available', 'modifying', 'configuring-enhanced-monitoring'}:

Why this change?

type = types.nullOr (types.either types.str (resource "ec2-rds-db-subnet-group"));
apply = group: if (builtins.isString group || group == null) then group else "res-" + group._name;
description = ''
A name for a DBSubnetGroup, they must contain at least one subnet in each availability zone in the AWS region.
Copy link
Contributor

Choose a reason for hiding this comment

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

multi lines

@PsyanticY
Copy link
Contributor

PsyanticY commented Nov 1, 2019

Thanks @RaitoBezarius

Tested deploying the example after some minor changes. and it worked fine. We have an error in destroying the example since nixops do not wait for the rds to finalize termination and fail when destroying the security group cause it is still attached to the delete in progress rds.

[nix-shell:~/rds/nixops]$ nixops destroy -d rds-test
warning: are you sure you want to destroy RDS instance ‘test-multi-az’? (y/N) y
test-rds-instance> deleting RDS instance `test-multi-az'...
test-rds-instance> saving final snapshot as test-multi-az-final-snapshot-535c8be39f404c32aa949bb5de2ea1e1
db-subnet........> destroying rds db subnet group nixops-c6b58b14-fcba-11e9-b33e-0ae168952ac0-db-subnet
database.........> deleting EC2 security group `charon-c6b58b14-fcba-11e9-b33e-0ae168952ac0-database' ID `sg-05e1714ce3a1603e7'...
error: Multiple exceptions (2): 
  * database: EC2ResponseError: 400 Bad Request
<?xml version="1.0" encoding="UTF-8"?>
<Response><Errors><Error><Code>DependencyViolation</Code><Message>resource sg-05e1714ce3a1603e7 has a dependent object</Message></Error></Errors><RequestID>1f56d3bf-0b36-4064-bf5a-eb5215bcc515</RequestID></Response>
  * db-subnet: An error occurred (InvalidDBSubnetGroupStateFault) when calling the DeleteDBSubnetGroup operation: Cannot delete the subnet group 'nixops-c6b58b14-fcba-11e9-b33e-0ae168952ac0-db-subnet' because at least one database instance: test-multi-az is still using it.

We should adress this. also I think we need to add the backup functionality to RDS module as well as remove automatically taking final snapshot (make a prompt or an argument).
@AmineChikhaoui

@RaitoBezarius
Copy link
Member Author

Tested deploying the example after some minor changes. and it worked fine. We have an error in destroying the example since nixops do not wait for the rds to finalize termination and fail when destroying the security group cause it is still attached to the delete in progress rds.

[nix-shell:~/rds/nixops]$ nixops destroy -d rds-test
warning: are you sure you want to destroy RDS instance ‘test-multi-az’? (y/N) y
test-rds-instance> deleting RDS instance `test-multi-az'...
test-rds-instance> saving final snapshot as test-multi-az-final-snapshot-535c8be39f404c32aa949bb5de2ea1e1
db-subnet........> destroying rds db subnet group nixops-c6b58b14-fcba-11e9-b33e-0ae168952ac0-db-subnet
database.........> deleting EC2 security group `charon-c6b58b14-fcba-11e9-b33e-0ae168952ac0-database' ID `sg-05e1714ce3a1603e7'...
error: Multiple exceptions (2): 
  * database: EC2ResponseError: 400 Bad Request
<?xml version="1.0" encoding="UTF-8"?>
<Response><Errors><Error><Code>DependencyViolation</Code><Message>resource sg-05e1714ce3a1603e7 has a dependent object</Message></Error></Errors><RequestID>1f56d3bf-0b36-4064-bf5a-eb5215bcc515</RequestID></Response>
  * db-subnet: An error occurred (InvalidDBSubnetGroupStateFault) when calling the DeleteDBSubnetGroup operation: Cannot delete the subnet group 'nixops-c6b58b14-fcba-11e9-b33e-0ae168952ac0-db-subnet' because at least one database instance: test-multi-az is still using it.

We should adress this. also I think we need to add the backup functionality to RDS module as well as remove automatically taking final snapshot (make a prompt or an argument).
@AmineChikhaoui

FYI, I noticed this issue and opened #11 for it, +1 for the final snapshot, I think it's a sane default to have though.

'';
};

imports = [ ./common-ec2-options.nix ];
Copy link
Member

Choose a reason for hiding this comment

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

This addition wasn't tested, can you please make sure that it works ?
It doesn't evaluate as ./common-ec2-options.nix is a function so please make it's merged to options

options = {
   /* options declarations */
} // (import ./common-ec2-options.nix { inherit lib; });

Also if I fix that locally the diff engine will throw an error as it doesn't find a handler that realizes the tags diff, so it needs to be fixed in the python side to create a handler for the tags option.

{
network.description = "NixOps RDS in a VPC Testing";
# A VPC.
resources.vpc.private = {
Copy link
Member

Choose a reason for hiding this comment

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

Can you also fix the indentation in this file please and remove any comments such as # A VPC which don't seem to be useful.

or isinstance(r, nixopsaws.resources.ec2_rds_subnet_group.EC2RDSSubnetGroupState)
or isinstance(r, nixopsaws.resources.ec2_security_group.EC2SecurityGroupState)}

def destroy_before(self, resources):
Copy link
Member

Choose a reason for hiding this comment

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

Do we really need destroy_before ? afaik it's automatically handled by doing the opposite of create_after

Copy link
Member Author

Choose a reason for hiding this comment

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

I didn't know this, as I was exploring the solution for #11

@RaitoBezarius
Copy link
Member Author

@AmineChikhaoui Changes were made.

@AmineChikhaoui
Copy link
Member

Thank you for the quick changes but please test before asking for review again :)

@RaitoBezarius
Copy link
Member Author

@AmineChikhaoui Now it is tested.

@AmineChikhaoui
Copy link
Member

@RaitoBezarius I think there might be some minor changes to be done to make sure that when not using VPC security groups/DB subnet the config works as well.
I get this with the old example of RDS:

[nix-shell:~/src/nixops]$ nixops deploy -d rds-legacy
Traceback (most recent call last):
  File "/home/amine/src/nixops/scripts/nixops", line 250, in <module>
    args.op(args)
  File "/home/amine/src/nixops/nixops/script_defs.py", line 427, in op_deploy
    max_concurrent_activate=args.max_concurrent_activate)
  File "/home/amine/src/nixops/nixops/deployment.py", line 1062, in deploy
    self.run_with_notify('deploy', lambda: self._deploy(**kwargs))
  File "/home/amine/src/nixops/nixops/deployment.py", line 1051, in run_with_notify
    f()
  File "/home/amine/src/nixops/nixops/deployment.py", line 1062, in <lambda>
    self.run_with_notify('deploy', lambda: self._deploy(**kwargs))
  File "/home/amine/src/nixops/nixops/deployment.py", line 915, in _deploy
    self.evaluate_active(include, exclude, kill_obsolete)
  File "/home/amine/src/nixops/nixops/deployment.py", line 877, in evaluate_active
    self.evaluate()
  File "/home/amine/src/nixops/nixops/deployment.py", line 383, in evaluate
    defn = _create_definition(y, config["resources"][res_type][name], res_type)
  File "/home/amine/src/nixops/nixops/deployment.py", line 1265, in _create_definition
    return cls(xml)
  File "/nix/store/nihlv8ac909rw3lca1jdhalx3j72sw1x-nixops-aws-1.7pre0_abcdef/lib/python2.7/site-packages/nixopsaws/resources/ec2_rds_dbinstance.py", line 49, in __init__
    self.rds_dbinstance_db_subnet_group = xml.find("attrs/attr[@name='dbSubnetGroup']/string").get("value")
AttributeError: 'NoneType' object has no attribute 'get'

@RaitoBezarius
Copy link
Member Author

@AmineChikhaoui I made the change but I'm unable to test it, I would require an ol'EC2 Classic account, those are not available anymore as AWS defaults to EC2-VPC nowadays AFAIK.

I tried to run it but AWS throws me an error saying: botocore.exceptions.ClientError: An error occurred (InvalidParameterValue) when calling the AuthorizeDBSecurityGroupIngress operation: VPC DB Security Groups cannot be modified with this API version. Please use an API version between 2012-01-15 and 2012-10-31 to modify this group.

But according to this: hashicorp/terraform#486 it's expected for people having an EC2 VPC account (like myself).

Let me know your thoughts on this.

@NickSeagull
Copy link

Any progress on this?

@RaitoBezarius
Copy link
Member Author

@NickSeagull AFAIK, I'm waiting for @AmineChikhaoui to give it a try again and see what should we do regarding the EC2-Classic stuff that I cannot test.

@AmineChikhaoui
Copy link
Member

Last time I tested on ec2-classic there was still some problems, I'll try to post the stacktrace next time but I'm not sure how helpful that would be unless I'm going to do the fixes as you can't test it.

@RaitoBezarius
Copy link
Member Author

@AmineChikhaoui It might help us to move forward, I wonder whether I can get my hand on an EC2 Classic account, I'll try to ask AWS support staff.

@grahamc grahamc mentioned this pull request Sep 9, 2020
@RaitoBezarius
Copy link
Member Author

Closing because of #113

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

When creating a RDS in a VPC, the RDS Security Group cannot be created
4 participants