LoginSignup
0
0

More than 5 years have passed since last update.

AWSのNATインスタンス用AMIを取得するTerraformモジュールを作ってみた

Last updated at Posted at 2015-07-11

TerraformでAmazon LinuxのNATインスタンス用AMIを取得するためのモジュールを作成してみました。

使い方

リージョンやバージョン等のパラメータを指定してNATインスタンス用AMIのIDを取得することができます。

module "nat_instance_ami" {
  source = "github.com/atsaki/tf_aws_nat_ami"
  region = "eu-central-1
  version = "2015.03.0"
  virttype = "pv"
  volumetype = "ebs"
}

regionのみ必須で、他は省略可能です。

  • region : (例:eu-central-1)
  • version : (例:2015.03.0、デフォルト:2015.03.0)
  • virttype : hvm or pv (デフォルト:hvm)
  • volumetype : gp2 or ebs (デフォルト:gp2)

実際のtfファイル、tfvarsファイルは以下のようになります。(NATを行うためにはroute tableの設定などが必要ですが今回は割愛します。)

main.tf
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {}

provider "aws" {
  access_key = "${var.aws_access_key}"
  secret_key = "${var.aws_secret_key}"
  region = "${var.region}"
}

module "nat_instance_ami" {
  source = "github.com/atsaki/tf_aws_nat_ami"
  region = "${var.region}"
  virttype = "pv"
  volumetype = "ebs"
}

resource "aws_instance" "nat_instance" {
  ami = "${module.nat_instance_ami.ami_id}"
  instance_type = "t1.micro"
  tags {
    Name = "nat_instance"
  }
}
terraform.tfvars
aws_access_key = "YOUR_ACCESS_KEY"
aws_secret_key = "YOUR_SECRET_KEY"
region = "YOUR_REGION"

tfファイルができたらterraform get コマンドでモジュールをダウンロードします。

$ terraform get

この後は、通常通りterraform planterraform apply を実行可能です。

仕組み

このモジュールはterraform-community-modulestf_aws_fedora_amitf_aws_ubuntu_amiを参考に作成しました。

何れも仕組みとしては同じで前もってスクリプトでAMIのリストを取得しTerraformの変数として保存しておき、モジュールのパラメータを使ってlookupしています。

今回作成したモジュールではAWS SDK for Rubyを使って各リージョンのAMIのリストを取得し、名前がamzn-ami-vpc-nat から始まるAMIの情報をvariables.tf.json に保存しています。

getvariables.rb
#!/usr/bin/env ruby

require 'aws-sdk'
require 'json'

regions = Aws::EC2::Client.new(region: 'us-east-1')
    .describe_regions.regions.map { |r| r.region_name }

data = {}
regions.each do |region|
    images = Aws::EC2::Client.new(region: region).describe_images(
        owners: ['amazon'],
        filters: [{ name: 'image-type', values: ['machine'] }]
    ).images.select { |image|
        !image.name.nil? && image.name.start_with?("amzn-ami-vpc-nat")
    }
    data.merge!(Hash[images.map {|i| ["#{region},#{i.name}", i.image_id]}])
end

puts JSON.pretty_generate({ 
    variable: {
        amis: {
            default: data
        }
    }
})

variables.tf.json の中は以下のようになっており、リージョン名とAMI名をキー、AMI idをバリューとしてAMIのリストが格納されています。

variables.tf.json
{
  "variable": {
    "amis": {
      "default": {
        "eu-central-1,amzn-ami-vpc-nat-hvm-2015.03.0.x86_64-ebs": "ami-1e073a03",
        "eu-central-1,amzn-ami-vpc-nat-hvm-2014.03.2.x86_64-ebs": "ami-204c7a3d",
        "eu-central-1,amzn-ami-vpc-nat-pv-2015.03.0.x86_64-ebs": "ami-3604392b",
        "eu-central-1,amzn-ami-vpc-nat-hvm-2015.03.0.x86_64-gp2": "ami-46073a5b",
      〜〜〜省略〜〜〜
      }
    }
  }
}

main.tf ではlookup 関数を使ってモジュールのパラメータで指定された条件と合致するAMIを抽出しIDを出力しています。
lookupformat についてはTerraformのドキュメントを参照)

main.tf
variable "region" {}
variable "version" {
  default = "2015.03.0"
}
variable "virttype" {
  default = "hvm"
}
variable "volumetype" {
  default = "gp2"
}

output "ami_id" {
  value = "${lookup(var.amis, format(\"%s,amzn-ami-vpc-nat-%s-%s.x86_64-%s\", var.region, var.virttype, var.version, var.volumetype))}"
}

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0