Skip to content

Module Structure

terraform-aws-arc-backup

Latest Release Last Updated Terraform GitHub Actions

Quality gate

Known Vulnerabilities

Introduction

SourceFuse's AWS Reference Architecture (ARC) Terraform module centralizes and automates the backup of data across AWS services such as Amazon RDS, EBS, DynamoDB, EFS, and more. It allows you to schedule automated backups, and manage and monitor backup activity from a single console, ensuring compliance and data protection. AWS Backup also supports cross-region and cross-account backup capabilities for enhanced data durability and disaster recovery.

Prerequisites

Before using this module, ensure you have the following:

  • AWS credentials configured.
  • Terraform installed.
  • A working knowledge of Terraform.

Getting Started

  1. Define the Module

Initially, it's essential to define a Terraform module, which is organized as a distinct directory encompassing Terraform configuration files. Within this module directory, input variables and output values must be defined in the variables.tf and outputs.tf files, respectively. The following illustrates an example directory structure:

1
2
3
4
billing/
|-- main.tf
|-- variables.tf
|-- outputs.tf
  1. Define Input Variables

Inside the variables.tf or in *.tfvars file, you should define values for the variables that the module requires.

  1. Use the Module in Your Main Configuration In your main Terraform configuration file (e.g., main.tf), you can use the module. Specify the source of the module, and version, For Example
module "example" {
  source      = "sourcefuse/arc-backup/aws"
  version     = "0.0.1"

  backup_vault_data        = local.backup_vault_data
  backup_plan              = local.backup_plan
  create_role              = true
  role_name                = local.backup_role_name
  backup_selection_data    = local.backup_selection_data
  vault_lock_configuration = local.vault_lock_configuration

  tags = module.tags.tags
}
  1. Output Values

Inside the outputs.tf file of the module, you can define output values that can be referenced in the main configuration. For example:

1
2
3
4
5
6
7
8
9
output "backup_plan_id" {
  description = "AWS backups plan ID"
  value       = module.example.backup_plan_id
}

output "vault_arn" {
  description = "Vault ARN"
  value       = module.example.vault_arn
}
  1. .tfvars

Inside the .tfvars file of the module, you can provide desired values that can be referenced in the main configuration. For example:

Edit the locals.tf file and provide desired values.
backup_plan - variable is used to define Backup plan and lifecycle policies.

backup_vault_data - Defines where backup has to be stored

backup_selection_data - Which all resources needs backup

locals {
  prefix = "arc-dev"

  backup_plan_name = "${local.prefix}-backup-plan"
  backup_role_name = "${local.prefix}-backup-restore"
  vault_name       = "${local.prefix}-backup-vault-1"

  backup_vault_data = {
    name                            = local.vault_name
    enable_encryption               = true
    backup_role_name                = local.backup_role_name
    kms_key_deletion_window_in_days = 7
    kms_key_admin_arns              = []
  }


  backup_plan = {
    name = local.backup_plan_name

    rules = [{
      name                     = "backup-rule-1"
      target_vault_name        = local.vault_name
      schedule                 = "cron(0 12 * * ? *)"
      recovery_point_tags      = module.tags.tags
      enable_continuous_backup = true

      lifecycle = [{ // its mandatory if `enable_continuous_backup = true` , error: Lifecycle must be specified for backup rule enabled continuous backup
        cold_storage_after = 0
        delete_after       = 35
      }]
    }]
  }

  backup_selection_data = {
    name      = "${local.prefix}-backup-selection"
    plan_name = local.backup_plan_name
    resources = ["*"]
    selection_tags = [{
      type  = "string"
      key   = "enable_backup"
      value = "true"
      }
    ]
  }

  vault_lock_configuration = {
    changeable_for_days = 3 // it has to be atleast 3
    max_retention_days  = 2
    min_retention_days  = 1
  }

}

First Time Usage

uncomment the backend block in main.tf

terraform init -backend-config=config.dev.hcl
If testing locally, terraform init should be fine

Create a dev workspace

terraform workspace new dev

Plan Terraform

terraform plan -var-file dev.tfvars

Apply Terraform

terraform apply -var-file dev.tfvars

Production Setup

terraform init -backend-config=config.prod.hcl

Create a prod workspace

terraform workspace new prod

Plan Terraform

terraform plan -var-file prod.tfvars

Apply Terraform

terraform apply -var-file prod.tfvars  

Cleanup

Destroy Terraform

terraform destroy -var-file dev.tfvars

Requirements

Name Version
terraform >= 1.4, < 2.0.0
aws >= 5.0, < 6.0

Providers

Name Version
aws 5.49.0

Modules

Name Source Version
backup_vault ./modules/backup-vault n/a

Resources

Name Type
aws_backup_plan.this resource
aws_backup_selection.this resource
aws_backup_vault_lock_configuration.this resource
aws_iam_role.this resource
aws_iam_role_policy_attachment.aws_backup_policy_backup_attachment resource
aws_iam_role_policy_attachment.aws_backup_policy_restore_attachment resource
aws_iam_role.this data source

Inputs

Name Description Type Default Required
backup_plan Rules for AWS backup plan, null act as flag to enable or disable backup plan
object({
name = string
rules = list(object({
name = string
target_vault_name = string
schedule = string
start_window = optional(string, null)
completion_window = optional(string, null)
recovery_point_tags = optional(map(string), {})
enable_continuous_backup = optional(bool, false)
lifecycle = list(object({
cold_storage_after = optional(number, 0)
delete_after = number
}))

copy_action = optional(list(object({
destination_vault_arn = string
lifecycle = optional(list(object({
cold_storage_after = string
delete_after = string
})), [])
})), [])

}))
})
null no
backup_selection_data (optional) Backup selection criteria to select resources
object({
name = string
plan_name = string
resources = optional(list(string), [""]) // List of resources eg [ "arn:aws:ec2:::instance/" ] , * -> All supported resources
selection_tags = optional(list(object({
type = string
key = string
value = string
})), [])
})
null no
backup_vault_data Details to create backup vault, null act as flag to enable or disable
object({
name = string
backup_role_name = string
enable_encryption = optional(bool, true)
kms_key_deletion_window_in_days = optional(number, 7)
kms_key_admin_arns = optional(list(string), [])
})
null no
create_role (optional) Role Required for taking backup and restore bool true no
role_name IAM role name string null no
tags Tags for AWS backup service map(string) n/a yes
vault_lock_configuration (optional) Vault lock configuration , changeable_for_days > 0 , then its governance else compliance mode
object({
vault_name = string
changeable_for_days = number
max_retention_days = number
min_retention_days = number
})
null no

Outputs

Name Description
backup_plan_id AWS backups plan ID
backup_role_arn n/a
backup_role_name n/a
vault_arn ARN of Vault

Versioning

This project uses a .version file at the root of the repo which the pipeline reads from and does a git tag.

When you intend to commit to main, you will need to increment this version. Once the project is merged, the pipeline will kick off and tag the latest git commit.

Development

Prerequisites

Configurations

  • Configure pre-commit hooks
    pre-commit install
    

Versioning

while Contributing or doing git commit please specify the breaking change in your commit message whether its major,minor or patch

For Example

git commit -m "your commit message #major"
By specifying this , it will bump the version and if you don't specify this in your commit message then by default it will consider patch and will bump that accordingly

Tests

  • Tests are available in test directory
  • Configure the dependencies
    1
    2
    3
    cd test/
    go mod init github.com/sourcefuse/terraform-aws-refarch-<module_name>
    go get github.com/gruntwork-io/terratest/modules/terraform
    
  • Now execute the test
    go test -timeout  30m
    

Authors

This project is authored by: - SourceFuse ARC Team