Skip to content
This repository has been archived by the owner on Jan 25, 2023. It is now read-only.

Feature/launch template #97

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

jcejohnson
Copy link
Contributor

The goal of this PR is to allow the module user to select either launch_configuration (traditional) or launch_template. Selecting launch_template should be backward compatible with the original implementation but with the ability to propagate tags to instance volumes. (With the caveat described below.)

As usual, I can only test this with our particular usecases. In that internal testing (one VPC per region, two vault clusters per VPC) I have validated that the resulting instances are identical to their launch_configuration counterparts and that the instance volumes have the expected tags.

I have not yet implemented a similar change to terraform-aws-consul. Doing so may result in changes to this PR if new edgecases are discovered there.

Caveat:
It only works when encrypted == "". This was reportedly addressed by AWS provider 1.34.0 but I'm still having issues. Ref: hashicorp/terraform-provider-aws#4553

jcejohnson and others added 5 commits August 24, 2018 10:52
…guration so that we can apply tags to instance volumes

Syntax, typos
…corp/terraform-provider-aws#4553 to be fixed & then do a cleaner implementation.

To make this work, I have to do:
terraform apply -target aws_iam_instance_profile.instance_profile -var-file inputs modules/vault-cluster/
terraform apply -var-file inputs modules/vault-cluster/
Tested with AWS provider 1.38.0 and root_volume_ebs_encryption=""
Does not work for *my* usecase with any other value for root_volume_ebs_encryption

variable "asg_launch_mechanism" {
description = "Select between launch_config-driven or launch_template-driven autoscaling group."
default = "launch_config"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On line 14 of main.tf the expected value is launch_configuration, not launch_config.

It's also worth adding here more clearly what are the expected values, or even maybe doing this in a different way, such as using booleans, to avoid confusion?

Another thing is that I think this is lacking an explanation of why you would choose one way over another. If not here, maybe a small note on the Readme?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks. When testing I was always passing the value for asg_launch_mechanism and didn't realize I had a bad default.
What I really need for the choice is an enumeration. If I had a boolean for each option then we're setup for enabling both at the same time. If I do one boolean to select between the two (e.g. - use_launch_template) I feel like it would be contrived.
I've added a bit of explanation in the comment for asg_launch_mechanism. My reason for doing this in the first place is to set tags on instance volumes. I'm sure there are other reasons for choosing one over the other but I'm very myopic at the moment.

name_prefix = "${var.cluster_name}"

launch_configuration = "${aws_launch_configuration.launch_configuration.name}"

depends_on = ["aws_iam_instance_profile.instance_profile", "aws_launch_template.launch_template"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why these depends_on?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have been aws_launch_configuration.launch_configuration. Fixed.
I added these for self-documentation since there are two autoscaling groups.

}"]
}

# An alternate autoscaling group that uses a launch_template
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I wonder if we could get by with just one aws_autoscaling_group resource.

locals {
  launch_template = {
    launch_configuration = []
    launch_template = [
      {
        id      = "${aws_launch_template.launch_template.id}"
        version = "${var.launch_template_version}"
      }
    ]
  }

  launch_configuration = {
    launch_configuration = "${aws_launch_configuration.launch_configuration.name}"
    launch_template = ""
  }
}

resource "aws_autoscaling_group" "autoscaling_group" {
  launch_template = "${local.launch_template[var.asg_launch_mechanism]}"
  launch_configuration = "${local.launch_configuration[var.asg_launch_mechanism]}"
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried but terraform immediately complained if I tried to declare both.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bummer

)
}"
}
# Important note: whenever using a launch configuration with an auto scaling group, you must set
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this true with a launch template too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, I'm not entirely sure that it is (still?) true for launch_configuration. My code is uses the vault-cluster default (true) and I haven't made any special configuration for the other resources.

tags = "${var.launch_template_tags}"
tag_specifications {
# Instance tags are already handled by the autoscaling group
resource_type = "volume"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must admit that this is a lot of extra code to maintain just to be able to tag EBS volumes. Is there no other way to do it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. My hope is that others will find other reasons why launch_template is a better alternative for their usecases and can expand on what I've started here.

The reason for the long delay between my initial submission & issue and this PR was due to the aws provider issue mentioned elsewhere. In the meantime, I was able to find a workaround via user-data script which inspects the instance & applies its tags to the instance volume. Of course, that requires that the instance be able to query its own tags and apply tags to its instance.

So, yes, there is another way to do it but it's a hack. And, from what I gather, launch templates are the new hot thing and presumably the preferred option going forward.

@@ -88,7 +198,7 @@ resource "aws_security_group" "lc_security_group" {
create_before_destroy = true
}

tags = "${merge(map("Name", var.cluster_name), var.security_group_tags)}"
tags = "${merge(var.security_group_tags, map("Name", var.cluster_name))}"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why reverse the order of the tags?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want var.security_group_tags to inadvertently change the value of the Name tag.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I'm tempted to say that's a feature, not a bug, as it allows the user full control over the Name tag in case the default isn't what they want...

@@ -29,10 +66,11 @@ resource "aws_autoscaling_group" "autoscaling_group" {
wait_for_capacity_timeout = "${var.wait_for_capacity_timeout}"

tags = ["${concat(
var.cluster_extra_tags,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why reverse the order of the tags?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want var.cluster_extra_tagsto inadvertently change the value of the Name tag.

value = "${aws_autoscaling_group.autoscaling_group.name}"
# This is safe because asg_launch_mechanism will only allow one of aws_autoscaling_group.autoscaling_group.*
# or aws_autoscaling_group.lt_autoscaling_group.* to be non-empty.
value = "${join("",concat(aws_autoscaling_group.autoscaling_group.*.name,aws_autoscaling_group.lt_autoscaling_group.*.name))}"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our typical approach for this is: ${element(concat(x, y), 0)}.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. Nice. Fixed.


variable "asg_launch_mechanism" {
# Choices are launch_configuration and launch_template.
# launch_template gives you the opportunithy to declare volume encryption and
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can enable volume encryption with a launch config too: https://www.terraform.io/docs/providers/aws/r/launch_configuration.html#encrypted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it can. Comment updated.
(FWIW, that ability isn't currently exposed in this module)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably should expose the ability to encrypt EBS volumes in the module for both launch configs and launch templates...

@jcejohnson
Copy link
Contributor Author

So, the upshot of it is this...

  • There's a lot of new code here to add the option to use launch_template instead of launch_configuration
  • Some (i.e. - lt_autoscaling_group) of the new code is redundant because aws_autoscaling_group cannot be given both a launch_template and a launch_configuration even if one is empty
  • Currently, the new vault-cluster features enabled by choosing launch_template are:
    • volume encryption (possible with launch_configuration but not exposed by this module)
    • specifying volume tags (not possible with launch_configuration but can be worked around via user-data)
  • launch_template offers more features than launch_configuration, whether or not those are applicable to vault-cluster remains to be seen
  • If this PR is accepted I will followup with a similar change to terraform-aws-consul to give it the ability to specify volume tags

@brikis98
Copy link
Collaborator

brikis98 commented Oct 7, 2018

One thought for you: is it worth waiting until Terraform 0.12 comes out to add this feature? It will support both dynamic blocks and null defaults, so we'd be able to do this with just one resource rather than several.

@jcejohnson
Copy link
Contributor Author

One thought for you: is it worth waiting until Terraform 0.12 comes out to add this feature? It will support both dynamic blocks and null defaults, so we'd be able to do this with just one resource rather than several.

I think that is an excellent idea!

@brikis98
Copy link
Collaborator

brikis98 commented Oct 7, 2018

OK, great. Hopefully, 0.12 will be out before too long, and we can make this PR simpler and get it merged. Thanks!

@ozbillwang
Copy link

Any updates for this PR?

@jcejohnson
Copy link
Contributor Author

No. I've been re-tasked to work on GCP adoption and haven't been able to get back to this. If there is no other interest it's probably best to just close this.

@hashicorp-cla
Copy link

hashicorp-cla commented Jun 8, 2020

CLA assistant check

Thank you for your submission! We require that all contributors sign our Contributor License Agreement ("CLA") before we can accept the contribution. Read and sign the agreement

Learn more about why HashiCorp requires a CLA and what the CLA includes


0 out of 2 committers have signed the CLA.

  • jcejohnson
  • efx-jjohnson

Have you signed the CLA already but the status is still pending? Recheck it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants