chef-provisioning-aws
chef-provisioning-aws copied to clipboard
Not possible to define Security Groups
Current when creating RDS instance is not possible to select which security group will be used (currently default is selected)
It looks like a shortcut is available to access the additional parameters that aren't exposed via attributes/properties, called additional_options
which accepts a hash of keys/values - You need to specify what additional parameters you want to "make available" within the , such as db_security_groups
in your case. I snipped the following out of the SDK documentation to show what is possible:
- :db_security_groups - (Array<) A list of DB Security Groups to associate with this DB Instance.
- :vpc_security_group_ids - (Array<) A list of EC2 VPC Security Groups to associate with this DB Instance. Default: The default EC2 VPC Security Group for the DB Subnet group's VPC.
As for the Chef Provisioning resource itself, a reasonable example is in the spec tests:
aws_rds_instance "test-rds-instance2" do
engine "postgres"
publicly_accessible false
db_instance_class "db.t1.micro"
master_username "thechief"
master_user_password "securesecure"
multi_az false
allocated_storage 5
additional_options(multi_az: true, backup_retention_period: 2)
end
So in your case you could change the additional_options
to (for example):
additional_options(db_security_groups: %w(my-db-sg1 my-db-sg2))
I haven't actually used the RDS instance resource yet, but it's only a matter of time! I'm sure the resources will also get a little more polished over time and introduce some of the popular options as first-class attributes/properties (or not, who knows!)
HTH. :-)
I just tried it in a test and it doesn't produce any results. Am I missing something?
aws_rds_instance "rds-core" do
engine "postgres"
publicly_accessible false
db_instance_class "db.t1.micro"
master_username "dbadmin"
master_user_password "test"
multi_az true
db_subnet_group_name "db-subnet-coredb"
allocated_storage 10
additional_options(db_security_groups: 'security-group-core-rds')
end
Fwiw, vpc_security_group_ids
really wants the ids, not the names as with db_security_groups
.
Thanks @josb but still no change:
security_group_core_rds = aws_security_group 'security-group-core-rds' do
vpc 'vpc-my'
inbound_rules [
{:port => 5432, :protocol => :tcp, :sources => ["172.16.16.0/20"] },
]
aws_tags :chef_type => "aws_security_group"
end
aws_rds_instance "rds-core" do
engine "postgres"
publicly_accessible false
db_instance_class "db.t1.micro"
master_username "dbadmin"
master_user_password "test"
multi_az true
db_subnet_group_name "db-subnet-coredb"
allocated_storage 10
additional_options(db_security_groups: security_group_core_rds.aws_object.id)
end
@lfrodrigues A couple of points:
- I'm not 100% certain, but I think you need to provide an array of the values, rather than a string (not sure if the SDK API converts it into an array or not).
- You need to ensure you use
vpc_security_group_ids
instead ofdb_security_groups
(note: I should have realised earlier you needed the VPC variant!) - Depending on whether
security-group-core-rds
exists or not, you might need to wrapsecurity_group_core_rds.aws_object.id
in alazy
block to ensure that the value is only accessed during convergence.
So maybe something like this (untested):
aws_rds_instance "rds-core" do
engine "postgres"
publicly_accessible false
db_instance_class "db.t1.micro"
master_username "dbadmin"
master_user_password "test"
multi_az true
db_subnet_group_name "db-subnet-coredb"
allocated_storage 10
additional_options lazy {
{
vpc_security_groups_ids: [security_group_core_rds.aws_object.id]
}
}
end
If it works, great, I can do something similar when I need it later!
HTH. :-)
Here's what I use:
libraries/recipe_helper.rb:
module Helper
def get_aws_object(klass, name)
klass.get_aws_object(
name,
run_context: run_context,
driver: run_context.chef_provisioning.current_driver,
managed_entry_store: ::Chef::Provisioning.chef_managed_entry_store(run_context.cheffish.current_chef_server)
)
end
end
In the recipe:
aws_rds_instance "mydb" do
# <other options>
extend Helper
additional_options(
lazy do
{
# We need the sg ids here
vpc_security_group_ids: [
get_aws_object(Chef::Resource::AwsSecurityGroup, "foo").id,
get_aws_object(Chef::Resource::AwsSecurityGroup, "bar").id
],
}
end
)
end
Alternatively, if you have the Chef resource object, you can use obj.aws_object.id
instead of the helper method (which uses the resource name), as @lskillen points out.
@josb Great! :+1: I've actually got something similar in my libraries as well. Probably makes a good candidate for something that can be made available in the provisioning library; perhaps monkey patched into Chef::DSL::Recipe and perhaps with additional helpers such as get_aws_security_group_id(name or resource)
.
@lfrodrigues I'm going to go ahead and close this because I think the documentation explains the additional_options
attribute and the confusion was around what AWS key to use (vpc_security_group_ids
). Please re-open if you are still having issues!
@tyler-ball Security groups are essential to define a RDS, shouldn't they be added as attributes and allow to reference an aws_security_group directly?
@lfrodrigues You're right - it would be much nicer to specify
aws_rds_instance "mydb" do
vpc_security_group_ids: ["foo", "bar]
additional_options(...)
end
than
aws_rds_instance "mydb" do
# <other options>
extend Helper
additional_options(
lazy do
{
# We need the sg ids here
vpc_security_group_ids: [
get_aws_object(Chef::Resource::AwsSecurityGroup, "foo").id,
get_aws_object(Chef::Resource::AwsSecurityGroup, "bar").id
],
}
end
)
end
:+1: to that last comment.
I'm trying to create a aws_rds_instance using an additional_options(vpc_security_group_ids: [securitygroup1.aws_object.id])
line. When I run it, I get an InvalidParameterCombination, RDS does not exist at the default VPC.
[2017-01-02T23:07:57-03:00] INFO: [Aws::RDS::Client 400 1.728897 0 retries] create_db_instance(vpc_security_group_ids:["sg-c83896a1"],db_instance_identifier:"stage-rds-instance",allocated_storage:5,engine:"mysql",db_instance_class:"db.t2.micro",master_username:"root",master_user_password:"secretsecret",multi_az:false,publicly_accessible:false) Aws::RDS::Errors::InvalidParameterCombination Database is in vpc-2653a64f, but Ec2 Security Group sg-c83896a1 is in vpc-08409461
The Security Group is defined as:
securitygroup1 = aws_security_group 'be-sec-group' do
# options
end
@pulpo have you tried specifying the vpc in the above reference to securitygroup1?
I missed the db_subnet_group_name at the aws_rds_instance resource, at the aws_security_group just the subnets where needed. I have it working now.
aws_rds_subnet_group "stage-db-subnet-group" do
description "some_description"
subnets ['octo-stage-private-a', 'octo-stage-private-c']
end
aws_rds_instance = aws_rds_instance "stage-rds-instance" do
engine "mysql"
publicly_accessible false
db_instance_class "db.t2.micro"
master_username data['stage']['db_username']
master_user_password data['stage']['db_password']
allocated_storage 5
multi_az false
db_subnet_group_name 'stage-db-subnet-group'
additional_options lazy {
{
vpc_security_group_ids: [securitygroupdb.aws_object.id]
}
}
end
thanks @josb