Skip to content

teamclairvoyant/terraform-aws-rds-lambda-db-provisioner

 
 

Repository files navigation

terraform-aws-rds-lambda-db-provisioner

Build Status Latest Release

Terraform module to provision a database and optionally a user in RDS instance in a VPC.

Terraform versions

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.

Introduction

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:

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.

Usage

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 = []
  }
}

Examples

Example with passwords passed via SSM Parameters

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 = []
  }
}

Example without a new user

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 = []
  }
}

Requirements

Name Version
terraform ~> 0.12.0
archive ~> 1.3
aws ~> 2.31
local ~> 1.2

Providers

Name Version
archive ~> 1.3
aws ~> 2.31

Inputs

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)
[
"0.0.0.0/0"
]
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({
vpc_id = string
subnet_ids = list(string)
security_group_ids = list(string)
})
n/a yes

Outputs

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

Help

Got a question?

File a GitHub issue.

Contributing

Bug Reports & Feature Requests

Please use the issue tracker to report any bugs or file feature requests.

Developing

In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow.

  1. Fork the repo on GitHub
  2. Clone the project to your own machine
  3. Commit changes to your own branch
  4. Push your work back up to your fork
  5. 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

Copyright © 2017-2020 Aleksandr Fofanov

License

License

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.

Trademarks

All other trademarks referenced herein are the property of their respective owners.

Contributors

Aleksandr Fofanov
Aleksandr Fofanov
Mike Arnold
Mike Arnold

About

Terraform module to provision database in AWS RDS instance in a VPC

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 93.6%
  • HCL 6.3%
  • Makefile 0.1%