Spotinst & Terraform Getting Started – Create Cost-Efficient Auto Scaling on AWS

Tags: , ,

How to install Spotinst plugin for Terraform

In this post we will demonstrate how to create a cost-efficient Auto-Scaling in AWS using Spotinst Terraform plugin.

This post assumes that you already have a Spotinst account, and that you have connected your AWS account with Spotinst.

1. Download the binary file terraform-provider-spotinst. (Notice: the Spotinst Terraform provider has been merged with the master Terraform branch in Github).

Please download the proper binary file for your operating system and architecture and put it somewhere on your filesystem:

0.9.0 Windows :
0.9.0 Linux :
0.9.0 Darwin :
0.8.7 Windows :
0.8.7 Linux:
0.8.7 Darwin :
0.8.5 Windows :
0.8.5 Linux :
0.8.5 Darwin :

2. Configure Terraform to be able to find the binary file:

If you are on a Unix-like system, create a file named .terraformrc in your home directory:

~/.terraformrc

If you are on a Windows system, create a file named terraform.rc in the %APPDATA% directory:

%APPDATA%/terraform.rc

3. Edit the file and add the following content:

providers {
  spotinst = "/path/to/terraform-provider-spotinst"
}

4. Create a new Terraform template and configure the Spotinst provider.

Please read the documentation for more details.

# Configure the Spotinst provider
provider "spotinst" {
  token = "${var.spotinst_personal_access_token}"
}

You can provide your API details from Spotinst API Zone, or create a Personal Access Token.

5. Create a new Spotinst resource.

Please read the documentation for more details.

# Create an AWS group
resource "spotinst_aws_group" "workers" {
  name = "workers-group"
  description = "created by Terraform"
  product = "Linux/UNIX"
     
  capacity {
    target = 75
    minimum = 50
    maximum = 100
  }

  strategy {
    risk = 100
  }

  instance_types {
    ondemand = "c3.large"
    spot = ["c3.large", "c4.large"]
  }
     
  availability_zone {
    name = "us-west-2b"
    subnet_id = "subnet-7bbbf51e"
  }

  launch_specification {
    monitoring = false
    image_id = "ami-f0091d91"
    key_pair = "pemfile_name"
    security_group_ids = ["default"]
  } 
    
  scheduled_task {
    task_type = "backup_ami"
    frequency = "weekly"
  } 

  scaling_up_policy {
    policy_name = "Scaling Policy 1"
    metric_name = "CPUUtilization"
    statistic = "average"
    unit = "percent"
    threshold = 80
    adjustment = 1
    namespace = "AWS/EC2"
    period = 300
    evaluation_periods = 2
    cooldown = 300
  }

  scaling_down_policy {
    policy_name = "Scaling Policy 2"
    metric_name = "CPUUtilization"
    statistic = "average"
    unit = "percent"
    threshold = 40
    adjustment = 1
    namespace = "AWS/EC2"
    period = 300
    evaluation_periods = 2
    cooldown = 300
  }   
}

Once you have everything setup correctly, you can execute your Terraform file and apply the changes. It should trigger an API call to Spotinst, and create an Elatigroup.

If you have any question or a comment, please feel free to reach me at: liran@spotinst.com

Best,
The Spotinst Team.

  • Pingback: AWS Week in Review – February 22, 2016 – SMACBUZZ()

  • Glenn Poston

    Hi Liran, any plans to integrate the ECS integration into the terraform provider?

    • Spotinst

      Hi Glenn,

      It’s ready! Please download the latest binary file of our provider for your operating system and you are ready to go:

      linux_amd64
      darwin_amd64
      windows_amd64

      To integrate your Elastigroup with EC2 Container Service all you need to do is to add a ec2_container_service_integration block and specify your cluster name, for example:

      ec2_container_service_integration {
      cluster_name = “ecs_prod_services”
      }

      • Ryan Jung

        The links provided in that comment and in the article above are dead, requiring authentication. I also don’t see mention of this provider in the docs. Is there a working download link?

        • Spotinst

          Hi Ryan,

          Thank you for letting us know!

          Please check it again, it should work fine now.

          • Ryan Jung

            Looks like it’s working now. Thanks for the prompt response!

      • Ryan Jung

        When running this against Terraform 0.6.16 (latest as of this posting), I get a message like this:

        * Incompatible API version with plugin. Plugin version: 1, Ours: 2

        I’ve found mention online of a change to this format causing problems when plugins aren’t compiled against a recent Terraform version. This Google Groups posting expresses something like that: https://groups.google.com/d/msg/terraform-tool/a1agp4CAEDk/ULWm4jrVBQAJ

        Will we be able to use this new version of the plugin with this new plugin format Terraform is imposing?

        • Spotinst

          Hi Ryan,

          Our provider has been upgraded to support the changes in the new version of Terraform.

          You are using Terraform v0.6.16, so please download the compatible version of our provider from here:

          darwin_amd64
          linux_amd64
          windows_amd64

          • Ryan Jung

            Thanks! That worked for me!

  • wjimenez5271

    Hello
    If you have multiple Spotinst accounts how do you specify in the terraform block which one this resource applies to? The API tokens seem to be shared across accounts…

    • Spotinst

      Personal Access Tokens are not shared across accounts. If you want to work with a different account simply set in a different token under the `provider` block.

  • Steve B

    Hi just a quick question – looking at the above example configuration you need to specifiy each availability zone & subnet. Is there an ability to specify a list of availability zones & subnets, so the values passed in can be from an existing variable and output from an existing terraform module exported as a module output/outputs?

  • Glenn Poston

    I know it’s just out, but has support for dedicated tenancy been added yet?

  • Alex Gray

    Hi Liran, I see that Terraform has merged https://github.com/hashicorp/terraform/pull/5001, but that will be released in terraform 0.8.8. Any chance we get this to work with terraform 0.8.5?