Skip to main content
Data Storage Modules 0.35.0Last updated in version 0.31.4

Copy Snapshot Lambda Module

View SourceRelease Notes

This module creates an AWS Lambda function that runs periodically and makes local copies of snapshots of an Amazon Relational Database (RDS) database that were shared from some external AWS account. This allows you to make backups of your RDS snapshots in a totally separate AWS account.

Note that to use this module, you must have access to the Gruntwork Continuous Delivery Infrastructure Package (terraform-aws-ci). If you need access, email support@gruntwork.io.

How do you copy an encrypted snapshot?

Let's say you created an RDS snapshot in account 111111111111 encrypted with a KMS key and shared that snapshot with account 222222222222. To be able to make a copy of that snapshot in account 222222222222 using this module, you must:

  1. Give account 222222222222 access to the KMS key in account 111111111111, including the kms:CreateGrant permission. If you're using the kms-master-key module to manage your KMS keys, then in account 111111111111, you add the ARN of account 222222222222 to the cmk_user_iam_arns variable:

    # In account 111111111111

    module "kms_master_key" {
    source = "git::git@github.com:gruntwork-io/terraform-aws-security.git//modules/kms-master-key?ref=<VERSION>"

    cmk_user_iam_arns = ["`arn:aws:iam::222222222222:root`"]

    # (Other params omitted)
    }
  2. In account 222222222222, you create another KMS key which can be used to re-encrypt the copied snapshot. You need to give the Lambda function in this module permissions to use that key as follows:

    # In account 222222222222

    module "kms_master_key" {
    source = "git::git@github.com:gruntwork-io/terraform-aws-security.git//modules/kms-master-key?ref=<VERSION>"

    # (Other params omitted)
    }

    module "copy_snapshot" {
    source = "git::git@github.com:gruntwork-io/terraform-aws-data-storage.git//modules/lambda-copy-shared-snapshot?ref=<VERSION>"

    # Tell this copy snapshot module to use this key to encrypt the copied snapshot
    kms_key_id = "${module.kms_master_key.key_arn}"

    # (Other params omitted)
    }

    # Giver the copy snapshot module permissions to use the KMS key
    resource "aws_iam_role_policy" "access_kms_master_key" {
    name = "access-kms-master-key"
    role = "${module.copy_snapshot.lambda_iam_role_id}"
    policy = "${data.aws_iam_policy_document.access_kms_master_key.json}"
    }

    data "aws_iam_policy_document" "access_kms_master_key" {
    statement {
    effect = "Allow"
    actions = [
    "kms:Encrypt",
    "kms:Decrypt",
    "kms:ReEncrypt*",
    "kms:GenerateDataKey*",
    "kms:DescribeKey"
    ]
    resources = ["${module.kms_master_key.key_arn}"]
    }

    statement {
    effect = "Allow"
    resources = ["*"]
    actions = [
    "kms:CreateGrant",
    "kms:ListGrants",
    "kms:RevokeGrant"
    ]
    condition {
    test = "Bool"
    variable = "kms:GrantIsForAWSResource"
    values = ["true"]
    }
    }
    }

Background info

For more info on how to backup RDS snapshots to a separate AWS account, check out the lambda-create-snapshot module documentation.

Sample Usage

main.tf

# ------------------------------------------------------------------------------------------------------
# DEPLOY GRUNTWORK'S LAMBDA-COPY-SHARED-SNAPSHOT MODULE
# ------------------------------------------------------------------------------------------------------

module "lambda_copy_shared_snapshot" {

source = "git::git@github.com:gruntwork-io/terraform-aws-data-storage.git//modules/lambda-copy-shared-snapshot?ref=v0.35.0"

# ----------------------------------------------------------------------------------------------------
# REQUIRED VARIABLES
# ----------------------------------------------------------------------------------------------------

# The ID of the external AWS account that shared the DB snapshots with this
# account
external_account_id = <string>

# The identifier of the RDS database
rds_db_identifier = <string>

# If set to true, this RDS database is an Amazon Aurora cluster. If set to
# false, it's running some other database, such as MySQL, Postgres, Oracle,
# etc.
rds_db_is_aurora_cluster = <bool>

# An expression that defines how often to run the lambda function to copy
# snapshots. For example, cron(0 20 * * ? *) or rate(5 minutes).
schedule_expression = <string>

# ----------------------------------------------------------------------------------------------------
# OPTIONAL VARIABLES
# ----------------------------------------------------------------------------------------------------

# Set to false to have this module skip creating resources. This weird
# parameter exists solely because Terraform does not support conditional
# modules. Therefore, this is a hack to allow you to conditionally decide if
# this module should create anything or not.
create_resources = true

# The ARN, key ID, or alias of a KMS key to use to encrypt the copied
# snapshot.
kms_key_id = null

# Namespace all Lambda resources created by this module with this name. If not
# specified, the default is var.rds_db_identifier with '-copy-snapshot' as a
# suffix.
lambda_namespace = null

# If set true, just before the lambda function finishes running, it will
# report a custom metric to CloudWatch, as specified by
# var.report_cloudwatch_metric_namespace and
# var.report_cloudwatch_metric_name. You can set an alarm on this metric to
# detect if the backup job failed to run to completion.
report_cloudwatch_metric = false

# The name to use for the the custom CloudWatch metric. Only used if
# var.report_cloudwatch_metric is set to true.
report_cloudwatch_metric_name = null

# The namespace to use for the the custom CloudWatch metric. Only used if
# var.report_cloudwatch_metric is set to true.
report_cloudwatch_metric_namespace = null

# Namespace all Lambda scheduling resources created by this module with this
# name. If not specified, the default is var.lambda_namespace with
# '-scheduled' as a suffix.
schedule_namespace = null

}


Reference

Required

external_account_idstringrequired

The ID of the external AWS account that shared the DB snapshots with this account

rds_db_identifierstringrequired

The identifier of the RDS database

If set to true, this RDS database is an Amazon Aurora cluster. If set to false, it's running some other database, such as MySQL, Postgres, Oracle, etc.

schedule_expressionstringrequired

An expression that defines how often to run the lambda function to copy snapshots. For example, cron(0 20 * ? ) or rate(5 minutes).

Optional

create_resourcesbooloptional

Set to false to have this module skip creating resources. This weird parameter exists solely because Terraform does not support conditional modules. Therefore, this is a hack to allow you to conditionally decide if this module should create anything or not.

true
kms_key_idstringoptional

The ARN, key ID, or alias of a KMS key to use to encrypt the copied snapshot.

null
lambda_namespacestringoptional

Namespace all Lambda resources created by this module with this name. If not specified, the default is rds_db_identifier with '-copy-snapshot' as a suffix.

null

If set true, just before the lambda function finishes running, it will report a custom metric to CloudWatch, as specified by report_cloudwatch_metric_namespace and report_cloudwatch_metric_name. You can set an alarm on this metric to detect if the backup job failed to run to completion.

false

The name to use for the the custom CloudWatch metric. Only used if report_cloudwatch_metric is set to true.

null

The namespace to use for the the custom CloudWatch metric. Only used if report_cloudwatch_metric is set to true.

null
schedule_namespacestringoptional

Namespace all Lambda scheduling resources created by this module with this name. If not specified, the default is lambda_namespace with '-scheduled' as a suffix.

null