Terraform module to provision a database and optionally a user in RDS instance in a VPC.
Terraform 0.12. Pin module version to ~> 1.0
. Submit pull-requests to master
branch.
It's 100% Open Source and licensed under the APACHE2.
This module provisions a AWS lambda function which creates a new database and optionally a new user in RDS instances
in a VPC. Supported engines are postgres
and mysql
. A newly created user, or a master user (in case when you
don't need a new user) will be granted all permissions to created database.
Features:
- Master user password as well as new user password can be passed to the module either via
- Module variables
- Parameters in SSM Parameter Store (Recommended!)
- Secrets in Secrets Manager (Recommended!)
- Lambda function execution logs are shipped to Cloudwatch.
- No database or user will be created if they are already exist.
Notes on using secrets from AWS Secrets Manager:
- When referencing secrets stored in Secrets Manager,
the
/aws/reference/secretsmanager
prefix must be used - A secret must contain password in the
password
field or be a plain-text secret
Caveats:
- This lambda function needs internet access in order to comminitcate with AWS API. You need to associate this function with one or more private subnets in your VPC and make sure that their routing tables have a default route pointing to NAT Gateway or NAT Instance in a public subnet. Associating a lambda function with a public subnet doesn't give it internet connectivity or public IP address. More context: Give Internet Access to a Lambda Function in a VPC
- This lambda function DOES NOT DROP provisioned database or user on destroy in order to prevent accidental data loss. Please make sure to delete provisioned database and user manually.
- ENIs attached to a lambda function may cause
DependencyViolation
error when you try to destroy associated security groups and/or subnets. More context: Corresponding issue on github
Backlog: [ ] Support SSL connections to RDS [ ] Switch to Circle CI for CI/CD pipelines
This module is backed by best of breed terraform modules maintained by Cloudposse.
IMPORTANT: The master
branch is used in source
just as an example. In your code, do not pin to master
because there may be breaking changes between releases.
Instead pin to the release tag (e.g. ?ref=tags/x.y.z
) of one of our latest releases.
This example creates a database new_database
and a user new_user
with the passwords
passed via variables.
module "db_provisioner" {
source = "git::https://github.com/aleks-fofanov/terraform-aws-rds-lambda-db-provisioner.git?ref=master"
name = "stack"
namespace = "cp"
stage = "prod"
db_instance_id = "prod-stack-db"
db_instance_security_group_id = "sg-XXXXXXXX"
db_master_password = "XXXXXXXX"
db_name = "new_database"
db_user = "new_user"
db_user_password = "XXXXXXXX"
vpc_config = {
vpc_id = "vpc-XXXXXXXX"
subnet_ids = ["subnet-XXXXXXXX", "subnet-XXXXXXXX"]
security_group_ids = []
}
}
This example creates a database new_database
and a user new_user
with the passwords
passed via SSM Parameters.
module "db_provisioner" {
source = "git::https://github.com/aleks-fofanov/terraform-aws-rds-lambda-db-provisioner.git?ref=master"
name = "stack"
namespace = "cp"
stage = "prod"
db_instance_id = "prod-stack-db"
db_instance_security_group_id = "sg-XXXXXXXX"
db_master_password_ssm_param = "/cp/prod/stack/database/master_password"
db_master_password_ssm_param_kms_key = "alias/aws/ssm"
db_name = "new_database"
db_user = "new_user"
db_user_password_ssm_param = "/cp/prod/stack/database/new_user_password"
db_user_password_ssm_param_kms_key = "alias/aws/ssm"
vpc_config = {
vpc_id = "vpc-XXXXXXXX"
subnet_ids = ["subnet-XXXXXXXX", "subnet-XXXXXXXX"]
security_group_ids = []
}
}
This example creates a database new_database
without a new user with the master user password
passed via SSM Parameter.
module "db_provisioner" {
source = "git::https://github.com/aleks-fofanov/terraform-aws-rds-lambda-db-provisioner.git?ref=master"
name = "stack"
namespace = "cp"
stage = "prod"
db_instance_id = "prod-stack-db"
db_instance_security_group_id = "sg-XXXXXXXX"
db_master_password_ssm_param = "/cp/prod/stack/database/master_password"
db_master_password_ssm_param_kms_key = "alias/aws/ssm"
db_name = "new_database"
vpc_config = {
vpc_id = "vpc-XXXXXXXX"
subnet_ids = ["subnet-XXXXXXXX", "subnet-XXXXXXXX"]
security_group_ids = []
}
}
Name | Version |
---|---|
terraform | ~> 0.12.0 |
archive | ~> 1.3 |
aws | ~> 2.31 |
local | ~> 1.2 |
Name | Version |
---|---|
archive | ~> 1.3 |
aws | ~> 2.31 |
Name | Description | Type | Default | Required |
---|---|---|---|---|
allowed_egress_cidr_blocks | A list of CIDR blocks allowed to be reached from Lambda. Remember that Lambda needs to be able to communicate with AWS API | list(string) |
[ |
no |
attributes | Additional attributes, e.g. 1 |
list(string) |
[] |
no |
db_instance_id | DB Instance Identifier | string |
n/a | yes |
db_instance_security_group_id | DB instance security group to add rules to. Rules will allow communication between Lambda and DB instance | string |
null |
no |
db_master_password | DB Instance master password. The usage of this parameter is discouraged. Consider putting db password in SSM Parameter Store and passing its ARN to the module via db_master_password_ssm_parameter_arn parameter |
string |
null |
no |
db_master_password_ssm_param | Name of SSM Parameter that stores password for master user. This param takes precedence other db_master_password |
string |
null |
no |
db_master_password_ssm_param_kms_key | Identifier of KMS key used for encryption of SSM Parameter that stores password for master user | string |
null |
no |
db_name | Database name that should be created | string |
n/a | yes |
db_user | Name of user that should be created and own (has all permission to) the provisioned database. If left empty, no user will be created | string |
null |
no |
db_user_password | Password for the user that should be created and own (has all permission to) the provisioned database. Ignored if db_user is set to null |
string |
null |
no |
db_user_password_ssm_param | Name of SSM Parameter that stores password for provisioned user. This param takes precedence other db_user_password |
string |
null |
no |
db_user_password_ssm_param_kms_key | Identifier of KMS key used for encryption of SSM Parameter that stores password for provisioned user | string |
null |
no |
delimiter | Delimiter to be used between namespace , name , stage and attributes |
string |
"-" |
no |
enabled | Defines whether this module should create resources | bool |
true |
no |
invoke | Defines whether lambda function should be invoked immediately after provisioning | bool |
true |
no |
kms_key | KMS key identifier. Accepts the same format as KMS key data source (https://www.terraform.io/docs/providers/aws/d/kms_key.html). If this configuration is not provided when environment variables are in use, AWS Lambda uses a default service key. | string |
null |
no |
logs_kms_key_id | KMS Key Id for Lambda function logs ecnryption | string |
null |
no |
logs_retention_days | Lambda function logs retentions in days | number |
null |
no |
memory | Amount of memory in MB your Lambda Function can use at runtime | number |
256 |
no |
name | Solution name, e.g. 'app' or 'jenkins' | string |
"rds" |
no |
namespace | Namespace (e.g. cp or cloudposse ) |
string |
"" |
no |
stage | Stage (e.g. prod , dev , staging ) |
string |
"" |
no |
tags | Additional tags (e.g. map( BusinessUnit, XYZ) |
map(string) |
{} |
no |
timeout | The amount of time your Lambda Function has to run in seconds | number |
30 |
no |
vpc_config | VPC configuration for Lambda function | object({ |
n/a | yes |
Name | Description |
---|---|
lambda_function_arn | Lambda Function ARN |
lambda_function_name | Lambda Function name |
lambda_iam_policy_arn | Lambda IAM Policy ARN |
lambda_iam_policy_id | Lambda IAM Policy ID |
lambda_iam_policy_name | Lambda IAM Policy name |
lambda_iam_role_arn | Lambda IAM Role ARN |
lambda_iam_role_id | Lambda IAM Role ID |
lambda_iam_role_name | Lambda IAM Role name |
Got a question?
File a GitHub issue.
Please use the issue tracker to report any bugs or file feature requests.
In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow.
- Fork the repo on GitHub
- Clone the project to your own machine
- Commit changes to your own branch
- Push your work back up to your fork
- Submit a Pull Request so that we can review your changes
NOTE: Be sure to merge the latest changes from "upstream" before making a pull request!
Copyright © 2017-2020 Aleksandr Fofanov
See LICENSE for full details.
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
All other trademarks referenced herein are the property of their respective owners.
Aleksandr Fofanov |
Mike Arnold |
---|