Skip to content

Commit

Permalink
Fixup
Browse files Browse the repository at this point in the history
  • Loading branch information
cvlc committed Feb 10, 2022
1 parent 898ece7 commit c3209d2
Show file tree
Hide file tree
Showing 23 changed files with 248 additions and 176 deletions.
19 changes: 0 additions & 19 deletions .terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2017 Monzo Bank Limited
Copyright (c) 2022 StorageOS

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ To retrieve the LB address, refer to the outputs of the module:
export ETCD_LB="$(terraform show -json | jq -r '.values.outputs.lb_address.value')"; echo $ETCD_LB
```

The certificates are automatically created in the your working Terraform directory as `ca.pem`, `client.pem` and `client.key` but if you don't have access to the filesystem you can extract them from the state:
You can extract the certificates from the state:

```
terraform show -json | jq -r '.values.outputs.ca_cert.value' > ca.pem
Expand Down
43 changes: 22 additions & 21 deletions asg.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ resource "aws_launch_configuration" "default" {
enable_monitoring = false
associate_public_ip_address = var.associate_public_ips
security_groups = [aws_security_group.default.id]
user_data = templatefile("${path.module}/cloudinit/userdata-template.sh", {
user_data = join("\n", [module.asg-attached-ebs[count.index].userdata_snippet, templatefile("${path.module}/cloudinit/userdata-template.sh", {
environment = var.environment,
role = var.role,
region = data.aws_region.current.name,
Expand All @@ -21,19 +21,13 @@ resource "aws_launch_configuration" "default" {
discovery_domain_name = "${var.role}.${data.aws_region.current.name}.i.${var.environment}.${var.dns["domain_name"]}"
cluster_name = var.role
}),
etcd_bootstrap_unit = templatefile("${path.module}/cloudinit/etcd_bootstrap_unit", {
region = data.aws_region.current.name
peer_name = "peer-${count.index}"
discovery_domain_name = "${var.role}.${data.aws_region.current.name}.i.${var.environment}.${var.dns["domain_name"]}"
etcd3_bootstrap_binary_url = local.etcd3_bootstrap_binary_url
}),
ca_file = tls_self_signed_cert.ca.cert_pem,
peer_cert_file = tls_locally_signed_cert.peer[count.index].cert_pem,
peer_key_file = tls_private_key.peer[count.index].private_key_pem,
server_cert_file = tls_locally_signed_cert.server[count.index].cert_pem,
server_key_file = tls_private_key.server[count.index].private_key_pem,
maintenance_day_of_the_month = count.index < 26 ? count.index + 1 : count.index - 25
})
})])
root_block_device { encrypted = true }

lifecycle {
Expand Down Expand Up @@ -90,7 +84,7 @@ resource "aws_autoscaling_group" "default" {
value = aws_route53_zone.default.id
propagate_at_launch = false
}
depends_on = [aws_ebs_volume.ssd, aws_lambda_permission.cloudwatch-dns-service-autoscaling]
depends_on = [aws_lambda_permission.cloudwatch-dns-service-autoscaling]
}

data "aws_subnet" "target" {
Expand All @@ -99,18 +93,25 @@ data "aws_subnet" "target" {
id = element(var.subnet_ids, count.index)
}

resource "aws_ebs_volume" "ssd" {
module "asg-attached-ebs" {
count = var.cluster_size
snapshot_id = lookup(var.restore_snapshot_ids, (count.index), "")
availability_zone = data.aws_subnet.target[count.index].availability_zone
size = var.ssd_size
encrypted = true

tags = {
Name = "peer-${count.index}-ssd.${var.role}.${data.aws_region.current.name}.i.${var.environment}.${var.dns["domain_name"]}"
environment = var.environment
role = "peer-${count.index}-ssd.${var.role}"
cluster = var.role
"snap-daily" = "true"
source = "./modules/asg_attached_ebs"
asg_name = "peer-${count.index}.${var.role}.${data.aws_region.current.name}.i.${var.environment}.${var.dns["domain_name"]}"
availability_zone = element(data.aws_subnet.target.*.availability_zone, count.index)
attached_ebs = {
"data-${count.index}.${var.role}.${data.aws_region.current.name}.i.${var.environment}.${var.dns["domain_name"]}" = {
size = var.ssd_size
encrypted = true
volume_type = "gp3"
block_device_aws = "/dev/xvda1"
block_device_os = "/dev/nvme0n1"
block_device_mount_path = "/var/lib/etcd"
tags = {
Name = "peer-${count.index}-ssd.${var.role}.${data.aws_region.current.name}.i.${var.environment}.${var.dns["domain_name"]}"
environment = var.environment
role = "peer-${count.index}-ssd.${var.role}"
cluster = var.role
}
}
}
}
18 changes: 0 additions & 18 deletions certs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,6 @@ resource "tls_self_signed_cert" "ca" {
]
}

resource "local_file" "ca-cert" {
content = tls_self_signed_cert.ca.cert_pem
filename = "./ca.pem"
file_permission = "0700"
}

resource "tls_private_key" "peer" {
algorithm = "ECDSA"
ecdsa_curve = "P384"
Expand Down Expand Up @@ -102,18 +96,6 @@ resource "tls_locally_signed_cert" "server" {
]
}

resource "local_file" "client-cert" {
content = tls_locally_signed_cert.client.cert_pem
filename = "./client.pem"
file_permission = "0700"
}

resource "local_file" "client-key" {
content = tls_private_key.client.private_key_pem
filename = "./client.key"
file_permission = "0700"
}

resource "tls_private_key" "client" {
algorithm = "ECDSA"
ecdsa_curve = "P384"
Expand Down
19 changes: 0 additions & 19 deletions cloudinit/etcd_bootstrap_unit

This file was deleted.

2 changes: 1 addition & 1 deletion cloudinit/etcd_member_unit
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[Unit]
Description=etcd key-value store
Documentation=https://github.com/etcd-io/etcd
After=network.target etcd-bootstrap.service
After=network.target ebs-bootstrap.service

[Service]
User=etcd
Expand Down
8 changes: 0 additions & 8 deletions cloudinit/userdata-template.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ mv /tmp/etcd-v${etcd_version}-linux-amd64/{etcd,etcdctl,etcdutl} /usr/local/bin
mkdir -p /var/lib/etcd/
mkdir -p /etc/etcd

## Create systemd units
cat << EOT > /etc/systemd/system/etcd-bootstrap.service
${etcd_bootstrap_unit}
EOT

cat << EOT > /etc/systemd/system/etcd-member.service
${etcd_member_unit}
EOT
Expand Down Expand Up @@ -60,8 +55,5 @@ chmod 755 /usr/local/share/ca-certificates/my-ca.crt
update-ca-certificates
## Enable and start services
systemctl enable etcd-bootstrap.service
systemctl enable etcd-member.service
systemctl start etcd-bootstrap.service
systemctl start etcd-member.service
Binary file removed files/etcd3-bootstrap-linux-amd64
Binary file not shown.
42 changes: 0 additions & 42 deletions iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,45 +28,3 @@ resource "aws_iam_instance_profile" "default" {
depends_on = [aws_iam_role.default]
}

resource "aws_iam_role_policy" "default" {
name = "${var.role}.${data.aws_region.current.name}.i.${var.environment}.${var.dns["domain_name"]}"
role = aws_iam_role.default.name
depends_on = [aws_iam_role.default]

lifecycle {
create_before_destroy = true
}

policy = <<EOF
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeAddresses",
"ec2:DescribeInstances",
"ec2:DescribeVolumes",
"ec2:DescribeVolumeStatus"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:AttachVolume",
"ec2:DetachVolume"
],
"Resource": "*",
"Condition": {
"ForAllValues:StringEquals": {
"ec2:ResourceTag/cluster": "${var.role}",
"ec2:ResourceTag/environment": "${var.environment}",
"ec2:Region": "${data.aws_region.current.name}"
}
}
}
]
}
EOF
}
81 changes: 81 additions & 0 deletions modules/asg_attached_ebs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# asg_attached_ebs
## Introduction
asg_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.

## Usage
Set the input variable `asg_name` to the name of the auto-scaling group to attach the EBS to. This must be size `1` in order to prevent contention over the EBS volumes.

The input variable `attached_ebs` takes a map of volume definitions to attach to instances on boot:
```
attached_ebs = {
"ondat_data_1": {
  size = 100
encrypted = true
volume_type = gp3
block_device_aws = "/dev/xvda1"
block_device_os = "/dev/nvme0n1"
block_device_mount_path = "/var/lib/data0"
}
"ondat_data_1": {
  size = 100
encrypted = true
restore_snapshot = ""
iops = 3000
volume_type = io2
throughput = 150000
kms_key_id = "arn:aws::kms/..."
block_device_aws = /dev/xvda2
block_device_os = /dev/nvme1n1
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.

Use the output `iam_role_policy_arn` to assign the policy to your ASG node's role.
Use the output `userdata_snippet` to embed in your ASG's userdata.

## Appendix

### Requirements

No requirements.

### Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | n/a |

### Modules

No modules.

### Resources

| Name | Type |
|------|------|
| [aws_dlm_lifecycle_policy.automatic_snapshots](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dlm_lifecycle_policy) | resource |
| [aws_ebs_volume.ssd](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume) | resource |
| [aws_iam_policy.data](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.dlm_lifecycle_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.dlm_lifecycle](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_iam_policy_document.ebs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |

### Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_asg_name"></a> [asg\_name](#input\_asg\_name) | Name of the ASG for the EBSes to be attached to | `string` | n/a | yes |
| <a name="input_attached_ebs"></a> [attached\_ebs](#input\_attached\_ebs) | Map of the EBS objects to allocate | `any` | n/a | yes |
| <a name="input_availability_zone"></a> [availability\_zone](#input\_availability\_zone) | The availability zone to create the EBS volume in | `string` | n/a | yes |
| <a name="input_ebs_bootstrap_binary_url"></a> [ebs\_bootstrap\_binary\_url](#input\_ebs\_bootstrap\_binary\_url) | Custom URL from which to download the ebs\_bootstrap binary | `any` | `null` | no |

### Outputs

| Name | Description |
|------|-------------|
| <a name="output_iam_role_policy_arn"></a> [iam\_role\_policy\_arn](#output\_iam\_role\_policy\_arn) | IAM role policy ARN to assign to ASG instance role |
| <a name="output_userdata_snippet"></a> [userdata\_snippet](#output\_userdata\_snippet) | Snippet of userdata to assign to ASG instances |
18 changes: 18 additions & 0 deletions modules/asg_attached_ebs/cloudinit/ebs_bootstrap_unit
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[Unit]
Wants=network-online.target
After=network-online.target
Wants=etcd-member.service
Before=etcd-member.service
Before=multi-user.target

[Service]
Type=oneshot
ExecStartPre=/usr/bin/curl -C - -L -o /tmp/ebs-bootstrap ${ebs_bootstrap_binary_url}
ExecStartPre=/usr/bin/chmod +x /tmp/ebs-bootstrap
RemainAfterExit=true
ExecStart=/tmp/ebs-bootstrap \
-ebs-volume-name=${ebs_volume_name} \
-block-device-aws=${ebs_block_device_aws} \
-block-device-os=${ebs_block_device_os} \
-aws-region=${region} \
-mount-point=${ebs_mount_point}
8 changes: 8 additions & 0 deletions modules/asg_attached_ebs/cloudinit/userdata-snippet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Create systemd unit
cat << EOT > /etc/systemd/system/ebs-bootstrap-${ebs_volume_name}.service
${ebs_bootstrap_unit}
EOT

## Enable and start service
systemctl enable ebs-bootstrap-${ebs_volume_name}.service
systemctl start ebs-bootstrap-${ebs_volume_name}.service
36 changes: 36 additions & 0 deletions modules/asg_attached_ebs/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
data "aws_region" "current" {}

data "aws_iam_policy_document" "ebs" {
statement {
sid = "allow-ec2-read"
actions = [
"ec2:DescribeAddresses",
"ec2:DescribeInstances",
"ec2:DescribeVolumes",
"ec2:DescribeVolumeStatus"
]
resources = [
"*"
]
}
statement {
sid = "allow-ebs-reassignment"
actions = [
"ec2:AttachVolume",
"ec2:DetachVolume"
]
resources = [
"*"
]
condition {
test = "StringEquals"
values = [var.asg_name]
variable = "ec2:ResourceTag/ebs-owner"
}
condition {
test = "StringEquals"
values = [data.aws_region.current.name]
variable = "ec2:Region"
}
}
}
Loading

0 comments on commit c3209d2

Please sign in to comment.