Danny Roberts
Danny Roberts

Reputation: 301

Terraform - ASGs with Mixed Instance Policies

I am using AWS with Terraform to spin up infra, but specifically I'm having issues spinning up an ASG with a Mixed Instance Policy. I am trying to spin up an ASG where by one instance will always be on-demand and the rest spots (all of the same type), on the face of it this looks easy but Ive been trying for a while and keep hitting various errors. Here's what I'm currently using:

 resource "aws_launch_template" "lt" {
   name_prefix            = "danny_test-"
   vpc_security_group_ids = [
     "${module.sec_groups.security_group_id_common}",
     "${module.sec_groups.security_group_id_ssh}",
     "${module.sec_groups.security_group_id_web}"
   ]
   image_id               = "${module.core_ami.core_ami_id}"
   instance_type          = "t2.small"
   key_name               = "${var.ssh_privkey_name}"
   user_data              = "${base64encode(data.template_file.common_user_data.rendered)}"

   iam_instance_profile {
     name = "${module.infradev_remote_state.iam_profile_updater_id}"
   }

   lifecycle {
     create_before_destroy = true
   }
}

resource "aws_autoscaling_group" "asg" {
  name                      = "danny_test"
  vpc_zone_identifier       = ["${split(",", module.environment.private_subnet_ids)}"]
  #launch_configuration      = "${aws_launch_configuration.lc.name}"
  min_size                  = "0"
  max_size                  = "1"
  desired_capacity          = "1"
  health_check_grace_period = "600"
  health_check_type         = "EC2"

  launch_template {
    id = "${aws_launch_template.lt.id}"
  }

  mixed_instances_policy {
    instances_distribution {
      on_demand_base_capacity = "1"
    }
  }
}

But I get this error:

Error: aws_autoscaling_group.asg: "mixed_instances_policy.0.launch_template": required field is not set

According to the documentation launch_template is optional there. I have tried setting this but it just goes down a rabbit hole of supposedly optional settings some of which I simply don't want to set (like overrides).

What is the correct way to achieve what I'm after? Either way it looks like the docs are at least partially wrong based on the above...

Upvotes: 5

Views: 2957

Answers (1)

ydaetskcoR
ydaetskcoR

Reputation: 56987

The documentation appears to be wrong because it's set as a Required field in the actual code:

        "mixed_instances_policy": {
            Type:     schema.TypeList,
            Optional: true,
            MaxItems: 1,
            Elem: &schema.Resource{
                Schema: map[string]*schema.Schema{
                    # ...
                    "launch_template": {
                        Type:     schema.TypeList,
                        Required: true,
                        MinItems: 1,
                        MaxItems: 1,

The aws_autoscaling_group resource docs show a useful example which includes the optional overrides you mentioned:

resource "aws_launch_template" "example" {
  name_prefix   = "example"
  image_id      = "${data.aws_ami.example.id}"
  instance_type = "c5.large"
}

resource "aws_autoscaling_group" "example" {
  availability_zones = ["us-east-1a"]
  desired_capacity   = 1
  max_size           = 1
  min_size           = 1

  mixed_instances_policy {
    launch_template {
      launch_template_specification {
        launch_template_id = "${aws_launch_template.example.id}"
      }

      override {
        instance_type = "c4.large"
      }

      override {
        instance_type = "c3.large"
      }
    }
  }
}

These overrides are in fact optional as shown in the code:

                                "override": {
                                    Type:     schema.TypeList,
                                    Optional: true,
                                    Elem: &schema.Resource{
                                        Schema: map[string]*schema.Schema{
                                            "instance_type": {
                                                Type:     schema.TypeString,
                                                Optional: true,
                                            },
                                        },
                                    },
                                },

Upvotes: 3

Related Questions