diff --git a/terraform/modules/attached_ebs/README.md b/terraform/modules/attached_ebs/README.md index 4701f9c..6b64183 100644 --- a/terraform/modules/attached_ebs/README.md +++ b/terraform/modules/attached_ebs/README.md @@ -1,25 +1,41 @@ # attached_ebs + ## Introduction -attached_ebs is a Terraform module used to generate persistent EBS volumes and attach them to auto-scaled instances, ensuring that snapshots are taken of them daily. + +attached_ebs is a Terraform module used to generate persistent EBS or EC2 +Instance Store volumes and attach them to auto-scaled instances, also managing +daily snapshots for EBS instances. ## Usage -Set the input variable `group` to a unique identifier to use to refer to the group of EBS disks. Make sure to tag all of your instances with `Group=XXXX` (with `XXXX` as the value you set for `group`). This is used by the IAM policy to enable permissions for attaching volumes within the group. -The input variable `attached_ebs` takes a map of volume definitions to attach to instances on boot: -``` +Set the input variable `group` to a unique identifier to use to refer to the +group of disks. Make sure to tag all of your instances with `Group=XXXX` +(with `XXXX` as the value you set for `group`). This is used by the IAM policy +to enable permissions for attaching EBS volumes within the group. + +The input variable `attached_ebs` takes a map of volume definitions to attach +to instances on boot: + +```hcl module "attached-ebs" { source = "github.com/ondat/etcd3-bootstrap/terraform/modules/attached_ebs" - attached_ebs = { - "ondat_data_1": { -  size = 100 # required - availability_zone = eu-west-1a # required + attached_ebs = { + "ondat_data_1": { # Basic EBS example +  size = 100 + availability_zone = eu-west-1a encrypted = true volume_type = gp3 block_device_aws = "/dev/xvda1" block_device_os = "/dev/nvme0n1" block_device_mount_path = "/var/lib/data0" } - "ondat_data_2": { + "ondat_data_2": { # EC2 Instance Store + availability_zone = eu-west-1a + ephemeral = true + block_device_os = "/dev/nvme1n1" + block_device_mount_path = "/var/lib/data0" + } + "ondat_data_3": { # Full EBS example   size = 100 availability_zone = eu-west-1a dependson = ["ondat_data_1"] @@ -30,17 +46,21 @@ module "attached-ebs" { throughput = 150000 kms_key_id = "arn:aws::kms/..." block_device_aws = /dev/xvda2 - block_device_os = /dev/nvme1n1 + block_device_os = /dev/nvme2n1 block_device_mount_path = /var/lib/data1 } } } ``` -For airgapped or private environments, the variable `ebs_bootstrap_binary_url` can be used to provide an HTTP/S address from which to retrieve the necessary binary. +For airgapped or private environments, use the variable `ebs_bootstrap_binary_url` +to provide an HTTP/S address from which to retrieve the necessary binary. + +Use the output `iam_role_policy_document` to generate and assign the policy to +your ASG node's role. -Use the output `iam_role_policy_document` to generate and assign the policy to your ASG node's role. -Use the output `userdata_snippets_by_az` to embed in your ASG's userdata - it's a map of AZ to snippets. +Use the output `userdata_snippets_by_az` to embed in your ASG's userdata - +it's a map of AZ to snippets. ## Appendix @@ -52,7 +72,7 @@ No requirements. | Name | Version | |------|---------| -| [aws](#provider\_aws) | n/a | +| [aws](#provider\_aws) | 4.16.0 | ### Modules @@ -83,4 +103,3 @@ No modules. |------|-------------| | [iam\_role\_policy\_document](#output\_iam\_role\_policy\_document) | IAM role policy document to assign to ASG instance role | | [userdata\_snippets\_by\_az](#output\_userdata\_snippets\_by\_az) | Map of snippets of userdata to assign to ASG instances by availability zone | - diff --git a/terraform/modules/attached_ebs/cloudinit/ebs_bootstrap_unit b/terraform/modules/attached_ebs/cloudinit/ebs_bootstrap_unit.tftpl similarity index 61% rename from terraform/modules/attached_ebs/cloudinit/ebs_bootstrap_unit rename to terraform/modules/attached_ebs/cloudinit/ebs_bootstrap_unit.tftpl index 9edb9d7..d840a2f 100644 --- a/terraform/modules/attached_ebs/cloudinit/ebs_bootstrap_unit +++ b/terraform/modules/attached_ebs/cloudinit/ebs_bootstrap_unit.tftpl @@ -13,8 +13,14 @@ ExecStartPre=/usr/bin/curl -C - -L -o /tmp/ebs-bootstrap ${ebs_bootstrap_binary_ ExecStartPre=/bin/chmod +x /tmp/ebs-bootstrap RemainAfterExit=true ExecStart=/tmp/ebs-bootstrap \ +%{ if ephemeral ~} + -use-ebs=false \ + -block-device-os=${block_device_os} \ + -mount-point=${block_device_mount_path} +%{ else ~} -ebs-volume-name=${ebs_volume_name} \ - -block-device-aws=${ebs_block_device_aws} \ - -block-device-os=${ebs_block_device_os} \ + -block-device-aws=${block_device_aws} \ + -block-device-os=${block_device_os} \ -aws-region=${region} \ - -mount-point=${ebs_block_device_mount_path} + -mount-point=${block_device_mount_path} +%{ endif ~} diff --git a/terraform/modules/attached_ebs/ebs.tf b/terraform/modules/attached_ebs/ebs.tf index a8e5edf..88ee6be 100644 --- a/terraform/modules/attached_ebs/ebs.tf +++ b/terraform/modules/attached_ebs/ebs.tf @@ -1,5 +1,5 @@ resource "aws_ebs_volume" "ssd" { - for_each = { for key, value in var.attached_ebs : key => value } + for_each = { for key, value in var.attached_ebs : key => value if(contains(keys(value), "ephemeral") != true) } snapshot_id = lookup(each.value, "restore_snapshot", null) availability_zone = each.value["availability_zone"] diff --git a/terraform/modules/attached_ebs/locals.tf b/terraform/modules/attached_ebs/locals.tf index b11d200..fdc4e8b 100644 --- a/terraform/modules/attached_ebs/locals.tf +++ b/terraform/modules/attached_ebs/locals.tf @@ -7,14 +7,15 @@ locals { for key, value in var.attached_ebs : value["availability_zone"] == az ? templatefile("${path.module}/cloudinit/userdata-snippet.sh", { region = data.aws_region.current.name, ebs_volume_name = "${key}-${value["availability_zone"]}", - ebs_bootstrap_unit = templatefile("${path.module}/cloudinit/ebs_bootstrap_unit", { - region = data.aws_region.current.name - depends = lookup(value, "dependson", false) ? join("\n", [for e in value["dependson"] : "Requires=${e}-${value["availability_zone"]}.service\nAfter=${e}-${value["availability_zone"]}.service"]) : "" - ebs_volume_name = "${key}-${value["availability_zone"]}" - ebs_block_device_aws = value["block_device_aws"] - ebs_block_device_os = value["block_device_os"] - ebs_block_device_mount_path = value["block_device_mount_path"] - ebs_bootstrap_binary_url = local.ebs_bootstrap_binary_url + ebs_bootstrap_unit = templatefile("${path.module}/cloudinit/ebs_bootstrap_unit.tftpl", { + region = data.aws_region.current.name + depends = lookup(value, "dependson", false) ? join("\n", [for e in value["dependson"] : "Requires=${e}-${value["availability_zone"]}.service\nAfter=${e}-${value["availability_zone"]}.service"]) : "" + ebs_volume_name = "${key}-${value["availability_zone"]}" + block_device_aws = contains(keys(value), "block_device_aws") == true ? value["block_device_aws"] : "" + block_device_os = value["block_device_os"] + block_device_mount_path = value["block_device_mount_path"] + ephemeral = lookup(value, "ephemeral", false) ? value["ephemeral"] : false + ebs_bootstrap_binary_url = local.ebs_bootstrap_binary_url }), }) : ""]) }