Search code examples
sshamazon-ec2terraformserverspec

Integrating Terraform and Serverspec


I'm using Terraform to automate build out of an AWS EC2 based docker host and then using its remote exec option to download a docker file, build and run it.

I'd hoped to integrate this with Serverspec but am struggling to work out two things:

  1. The best way to pass the external dns of the newly created AWS EC2 instance to Serverspec.

  2. How to configure the SSH options for Serverspec so that it executes correctly on an Amazon Linux AMI using the ec2-user account.

I would normally connect to the EC2 instance using a pre-defined key pair and never use a password however ServerSpec seems to run commands on the server with a sudo -p format.

Any advice much appreciated.

Contents of spec_helper.rb

require 'serverspec'
require 'net/ssh'

set :ssh_options, :user => 'ec2-user'

Also using edited rakefile as follows to force correct EC2 external dns (masked):

require 'rake'
require 'rspec/core/rake_task'

hosts = %w(
  ec2-nn-nn-nn-nnn.eu-west-1.compute.amazonaws.com
)

set :ssh_options, :user => 'ec2-user'

task :spec => 'spec:all'

namespace :spec do
  task :all => hosts.map {|h| 'spec:' + h.split('.')[0] }
  hosts.each do |host|
    short_name = host.split('.')[0]
    role       = short_name.match(/[^0-9]+/)[0]

    desc "Run serverspec to #{host}"
    RSpec::Core::RakeTask.new(short_name) do |t|
      ENV['TARGET_HOST'] = host
      t.pattern = "spec/Nexus/*_spec.rb"
    end
  end
end

Solution

    1. You could make the IP address an output in Terraform. In fact, the link gives an example doing just that to get the IP address of an AWS instance, named web in this case:

      output "address" {
          value = "${aws_instance.web.public_dns}"
      }
      

      Then you can get this value from the command line after a terraform apply with terraform output address.

    2. You can set the sudo password with the config option :sudo_password. If the ec2-user can run sudo without a password, set this to ''. (See this blog post for an example.) Or pass it in the SUDO_PASSWORD environment variable, described here: http://serverspec.org/tutorial.html