Skip to content

Terraform module used to schedule an AWS nuke task within an account

License

Notifications You must be signed in to change notification settings

appvia/terraform-aws-nuke

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

66 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Appvia Banner

Terraform Registry Latest Release Slack Community Contributors

Github Actions

Terraform Nuke Module

Description

The purpose of this module is to provide a method of automated cleanup of resources, using the aws-nuke tool. This module will create a scheduled task that will run an ECS task on a regular basis to clean up resources that are no longer needed.

It is intended to be used in a non-production environment, such as a development or testing account, to ensure that resources are not left running and incurring costs when they are no longer needed.

Usage

The following provides an example of how to use this module:

locals {
  tags = {
    "Environment" = "Sandbox"
    "GitRepo"     = "https://github.com/appvia/terraform-aws-nuke"
    "Owner"       = "Support"
    "Product"     = "Sandbox"
  }
}

module "vpc" {
  source  = "appvia/network/aws"
  version = "0.3.2"

  availability_zones     = 2
  enable_ipam            = false
  enable_transit_gateway = false
  name                   = "nuke"
  public_subnet_netmask  = 28
  tags                   = local.tags
  transit_gateway_id     = null
  vpc_cidr               = "172.16.0.0/25"
}

module "nuke" {
  source = "github.com/appvia/terraform-aws-nuke?ref=main"

  ## The account id we are running in
  account_id = data.aws_caller_identity.current.account_id
  ## Indicates if the KMS key should be created for the log group
  create_kms_key = false
  ## The region to use for the resources
  region = data.aws_region.current.name
  ## The ssubnet_ids to use for the nuke service
  subnet_ids = module.vpc.public_subnet_ids
  ## The tags for the resources created by this module
  tags = local.tags

  ## The docker image to use for the nuke service - NOTE: we would recommend you
  ## build and push this image to you own registry
  container_image = "ghcr.io/ekristen/aws-nuke"
  ## The tag to use for the container image
  container_image_tag = "v3.26.0-2-g672408a-amd64"

  tasks = {
    "default" = {
      ## The path to the configuration file for the task
      configuration = file("${path.module}/assets/nuke-config.yml.example")
      ## A description for the task
      description = "Runs the actual nuke service, deleting resources"
      ## Indicates if the task should be a dry run (default is true)
      dry_run = false
      ## The log retention in days for the task
      retention_in_days = 7
      ## The schedule expression for the task, every friday at 10:00
      schedule = "cron(0 10 ? * FRI *)"
      ## The IAM permissions to attach to the task role
      permission_arns = [
        "arn:aws:iam::aws:policy/AdministratorAccess"
      ]
      ## Additional inline permissions
      additional_permissions = {
        "secrets" = {
          policy = data.aws_iam_policy_document.additional.json
        }
      }
    }
  }
}

Yon can find a full example in the examples/basic directory.

Configuration Module

The repository also includes a helper configuration module that can be used to render a nuke configuration. An example of how to use the module can be found below

module "configuration" {
  source = "../.."

  accounts = [123456789012, 123456789013]
  regions  = ["us-east-1", "us-west-2"]

  presets = {
    "default" = {
      "IAMRole" = [
        {
          property = "roleName"
          type     = "regex"
          value    = "^AWSControlTower.*"
        }
      ]
    }
  }

  filters = [
    {
      property = "tag:Environment"
      type     = "string"
      value    = "Sandbox"
    },
    {
      property = "tag:Owner"
      type     = "string"
      value    = "Support"
    }
  ]

  include_presets = {
    enable_control_tower     = true
    enable_cost_intelligence = true
    enable_landing_zone      = true
  }
}

module "nuke" {
  source = "github.com/appvia/terraform-aws-nuke?ref=main"

  ## The account id we are running in
  account_id = data.aws_caller_identity.current.account_id
  ## Indicates if the KMS key should be created for the log group
  create_kms_key = false
  ## The region to use for the resources
  region = data.aws_region.current.name
  ## The ssubnet_ids to use for the nuke service
  subnet_ids = module.vpc.public_subnet_ids
  ## The tags for the resources created by this module
  tags = local.tags

  tasks = {
    "default" = {
      ## The path to the configuration file for the task
      configuration = module.configuration.configuration
      ## A description for the task
      description = "Runs the actual nuke service, deleting resources"
      ## Indicates if the task should be a dry run (default is true)
      dry_run = false
      ## The log retention in days for the task
      retention_in_days = 7
      ## The schedule expression for the task, every friday at 10:00
      schedule = "cron(0 10 ? * FRI *)"
      ## The IAM permissions to attach to the task role
      permission_arns = [
        "arn:aws:iam::aws:policy/AdministratorAccess"
      ]
      ## Additional inline permissions
      additional_permissions = {
        "secrets" = {
          policy = data.aws_iam_policy_document.additional.json
        }
      }
    }
  }
}

Update Documentation

The terraform-docs utility is used to generate this README. Follow the below steps to update:

  1. Make changes to the .terraform-docs.yml file
  2. Fetch the terraform-docs binary (https://terraform-docs.io/user-guide/installation/)
  3. Run terraform-docs markdown table --output-file ${PWD}/README.md --output-mode inject .

Requirements

Name Version
terraform >= 1.0.7
aws = 5.70.0

Providers

Name Version
aws = 5.70.0

Modules

Name Source Version
kms terraform-aws-modules/kms/aws 3.1.1
lambda_function terraform-aws-modules/lambda/aws 7.14.0

Resources

Name Type
aws_cloudwatch_event_rule.ecs_task_stopped_rule resource
aws_cloudwatch_event_rule.tasks resource
aws_cloudwatch_event_target.invoke_lambda resource
aws_cloudwatch_event_target.tasks resource
aws_cloudwatch_log_group.tasks resource
aws_ecs_cluster.current resource
aws_ecs_task_definition.tasks resource
aws_iam_role.cloudwatch resource
aws_iam_role.execution resource
aws_iam_role.task resource
aws_iam_role_policy.execution_ecr resource
aws_iam_role_policy.execution_secrets resource
aws_iam_role_policy.task_additional_permissions resource
aws_iam_role_policy_attachment.cloudwatch resource
aws_iam_role_policy_attachment.execution resource
aws_iam_role_policy_attachment.task_permissions_arns resource
aws_lambda_permission.allow_eventbridge resource
aws_secretsmanager_secret.configuration resource
aws_secretsmanager_secret_version.configuration resource

Inputs

Name Description Type Default Required
account_id The account id to use for the resources string n/a yes
region The region to use for the resources string n/a yes
subnet_ids The subnet id's to use for the nuke service list(string) n/a yes
tags Map of tags to apply to resources created by this module map(string) n/a yes
tasks A collection of nuke tasks to run and when to run them
map(object({
additional_permissions = optional(map(object({
policy = string
})), {})
configuration = string
description = string
dry_run = optional(bool, true)
notifications = optional(object({
sns_topic_arn = optional(string, null)
}), {
sns_topic_arn = null
})
permission_boundary_arn = optional(string, null)
permission_arns = optional(list(string), ["arn:aws:iam::aws:policy/AdministratorAccess"])
retention_in_days = optional(number, 7)
schedule = string
}))
n/a yes
assign_public_ip Indicates if the task should be assigned a public IP bool false no
cloudwatch_event_role_name The name of the role to use for the cloudwatch event rule string "nuke-cloudwatch" no
cloudwatch_event_rule_prefix The prefix to use for the cloudwatch event rule string "lza-nuke" no
configuration_secret_name_prefix The prefix to use for AWS Secrets Manager secrets to store the nuke configuration string "/lza/configuration/nuke" no
container_cpu The amount of CPU to allocate to the container number 256 no
container_image The image to use for the container string "ghcr.io/ekristen/aws-nuke" no
container_image_tag The tag to use for the container image string "v3.26.0-2-g672408a-amd64" no
container_memory The amount of memory to allocate to the container number 512 no
create_kms_key Indicates if a KMS key should be created for the log group bool false no
ecs_cluster_name The name of the ECS cluster we provision run the nuke tasks within string "nuke" no
enable_container_insights Indicates if container insights should be enabled for the cluster bool false no
iam_execution_role_prefix The prefix to use for the IAM execution roles used by the tasks string "lza-nuke-execution-" no
iam_task_role_prefix The prefix to use for the IAM tasg roles used by the tasks string "lza-nuke-" no
kms_administrator_role_name The name of the role to use as the administrator for the KMS key (defaults to account root) string null no
kms_key_alias The alias to use for the nuke KMS key string "nuke" no
log_group_kms_key_id The KMS key id to use for encrypting the log group string null no
log_group_name_prefix The name of the log group to create string "/lza/services/nuke" no

Outputs

Name Description
kms_key_arn The KMS key ARN used for the nuke service, if created
kms_key_id The KMS key ID used for the nuke service, if created