LoginSignup
25

More than 5 years have passed since last update.

terraform で userdata を渡して ec2 インスタンスを起動し、ホスト名をつける

Last updated at Posted at 2015-11-17

やること

  • terraform で iam ロールをつくる
  • terraform で ec2 インスタンスをつくる
    • userdata を渡す
      • s3 から shellscript をダウンロードして実行
        • インスタンスに付与されている Name タグを hostname に設定する

これらを terraform apply のみで完了させます。

環境

name version
ec2 amazon-linux 2015.09
terraform 0.5.3
ローカル環境 OSX 10.10.5

※ terraform の現在の最新は 0.6.6 のようです

前提

  • subnet / routetable / security-group が作成済みであること

tf ファイルの作成

ec2 インスタンスの構成情報を記述します。作業ディレクトリは ~/terraform/test とします。

aws アクセスキー

~/terraform/test/aws.tf
/*
    aws settings
*/

provider "aws" {
    access_key = "************"
    secret_key = "********************"
    region = "ap-northeast-1"
}

変数

今回は使いませんが、バケット名を書いたりすると便利そうです。

~/terraform/test/variables.tf
/*
   variables
*/

variable "my-env" {
    default = {
        vpc_id = "vpc-****"
        vpc_cidr = "10.0.0.0/16"
    }
}

iam ロール

s3 へのアクセスと ec2 describe-instances を許可します。

~/terraform/test/iam_role.tf
resource "aws_iam_role_policy" "test_policy" {
    name = "test_policy"
    role = "${aws_iam_role.test.id}"
    policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "ec2:Describe*"
      ],
      "Effect": "Allow",
      "Resource": "*"
    },
    {
      "Action": [
        "s3:*"
      ],
      "Effect": "Allow",
      "Resource": [
          "arn:aws:s3:::my-bucket/*",
          "arn:aws:s3:::my-bucket"
      ]
    }
  ]
}
EOF
}

resource "aws_iam_role" "test_role" {
    name = "test_role"
    assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

resource "aws_iam_instance_profile" "test_profile" {
  name = "test_profile"
  roles = ["${aws_iam_role.test_role.name}"]
}

一旦ここまでで terraform apply して iam 設定を作成しておきます。

userdata

中身はこんな感じで、s3 からダウンロードしたスクリプトを実行するだけのものです。

userdata.sh
#!/bin/bash
# for userdata

aws="/usr/bin/aws --region ap-northeast-1"
work_dir="/tmp/userdata"
s3_url="s3://my-bucket/my-folder"
logger="logger -t $0"

${logger} "start scirpt."
mkdir -p "${work_dir}"

### download & run
${aws} s3 cp --recursive "${s3_url}" "${work_dir}"
ls "${work_dir}" | while read script
do
  sh "${work_dir}"/"${script}"
done

${logger} "finished."
exit 0

これを base64 エンコードします。 mac だったら以下です。

$ cat userdata.sh | openssl enc -e -base64
IyEvYmluL2Jhc2gKIyBmb3IgdXNlcmRhdGEKCmF3cz0iL3Vzci9iaW4vYXdzIC0t
cmVnaW9uIGFwLW5vcnRoZWFzdC0xIgp3b3JrX2Rpcj0iL3RtcC91c2VyZGF0YSIK
czNfdXJsPSJzMzovL215LWJ1Y2tldC9teS1mb2xkZXIiCmxvZ2dlcj0ibG9nZ2Vy
IC10ICQwIgoKJHtsb2dnZXJ9ICJzdGFydCBzY2lycHQuIgpta2RpciAtcCAiJHt3
b3JrX2Rpcn0iCgojIyMgZG93bmxvYWQgJiBydW4KJHthd3N9IHMzIGNwIC0tcmVj
dXJzaXZlICIke3MzX3VybH0iICIke3dvcmtfZGlyfSIKbHMgIiR7d29ya19kaXJ9
IiB8IHdoaWxlIHJlYWQgc2NyaXB0CmRvCiAgc2ggIiR7d29ya19kaXJ9Ii8iJHtz
Y3JpcHR9Igpkb25lCgoke2xvZ2dlcn0gImZpbmlzaGVkLiIKZXhpdCAw

これを次の tf ファイルに貼り付けます。

ec2 インスタンス

~/terraform/test/instance.tf
resource "aws_instance" "test-001" {
    ami = "ami-*****"
    instance_type = "t2.micro"
    subnet_id = "subnet-*****"
    private_ip = "10.0.0.5"
    user_data = <<EOF
IyEvYmluL2Jhc2gKIyBmb3IgdXNlcmRhdGEKCmF3cz0iL3Vzci9iaW4vYXdzIC0t
cmVnaW9uIGFwLW5vcnRoZWFzdC0xIgp3b3JrX2Rpcj0iL3RtcC91c2VyZGF0YSIK
czNfdXJsPSJzMzovL215LWJ1Y2tldC9teS1mb2xkZXIiCmxvZ2dlcj0ibG9nZ2Vy
IC10ICQwIgoKJHtsb2dnZXJ9ICJzdGFydCBzY2lycHQuIgpta2RpciAtcCAiJHt3
b3JrX2Rpcn0iCgojIyMgZG93bmxvYWQgJiBydW4KJHthd3N9IHMzIGNwIC0tcmVj
dXJzaXZlICIke3MzX3VybH0iICIke3dvcmtfZGlyfSIKbHMgIiR7d29ya19kaXJ9
IiB8IHdoaWxlIHJlYWQgc2NyaXB0CmRvCiAgc2ggIiR7d29ya19kaXJ9Ii8iJHtz
Y3JpcHR9Igpkb25lCgoke2xvZ2dlcn0gImZpbmlzaGVkLiIKZXhpdCAw
EOF
    iam_instance_profile = "${aws_iam_instance_profile.test_profile.name}"
    security_groups = [
        "sg-*******"
    ]
    ebs_block_device = {
      device_name = "/dev/xvdba"
      volume_type = "standard"
      volume_size = "15"
      encrypted = "true"
      delete_on_termination = "true"
    }
    ebs_block_device = {
      device_name = "/dev/xvdbb"
      volume_type = "standard"
      volume_size = "15"
      encrypted = "true"
      delete_on_termination = "true"
    }
    tags {
        Name = "test-001"
    }
}

ホスト名をつけるスクリプト

s3 にアップロードしておくスクリプトです。

set_hostname.sh
#!/bin/bash
# set_hostname.sh
# require awscli and ec2 read access on iam role

set -e
aws="/usr/bin/aws --region ap-northeast-1"
logger="logger -t $0"

get_instance_id()
{
    instance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
}

get_tag_name()
{
    tag_name=$(${aws} ec2 describe-instances \
                  --instance-id ${instance_id} \
                  --query 'Reservations[].Instances[].Tags[?Key==`Name`].Value' \
                  --output text)
}

set_hostname()
{
    hostname "${tag_name}"
    local res=$(grep "HOSTNAME=${tag_name}" /etc/sysconfig/network)
    if [ -z "${res}" ]; then
        sed -i -e '/HOSTNAME/d' /etc/sysconfig/network
        echo "HOSTNAME=${tag_name}" >> /etc/sysconfig/network
    fi
}

get_instance_id
get_tag_name
set_hostname
${logger} "finished $0"
exit 0

terraform 実行

$ terraform apply

~略~
  ebs_block_device.66500966.delete_on_termination:   "" => "1"
  ebs_block_device.66500966.device_name:             "" => "/dev/xvdba"
  ebs_block_device.66500966.encrypted:               "" => "1"
  ebs_block_device.66500966.iops:                    "" => "<computed>"
  ebs_block_device.66500966.snapshot_id:             "" => "<computed>"
  ebs_block_device.66500966.volume_size:             "" => "15"
  ebs_block_device.66500966.volume_type:             "" => "standard"
  ebs_block_device.7499016.delete_on_termination:    "" => "1"
  ebs_block_device.7499016.device_name:              "" => "/dev/xvdbb"
  ebs_block_device.7499016.encrypted:                "" => "1"
  ebs_block_device.7499016.iops:                     "" => "<computed>"
  ebs_block_device.7499016.snapshot_id:              "" => "<computed>"
  ebs_block_device.7499016.volume_size:              "" => "15"
  ebs_block_device.7499016.volume_type:              "" => "standard"
  ephemeral_block_device.#:                          "" => "<computed>"
  iam_instance_profile:                              "" => "test_profile"
  instance_type:                                     "" => "t2.medium"
  key_name:                                          "" => "<computed>"
  placement_group:                                   "" => "<computed>"
  private_dns:                                       "" => "<computed>"
  private_ip:                                        "" => "10.0.0.5"
  public_dns:                                        "" => "<computed>"
  public_ip:                                         "" => "<computed>"
  root_block_device.#:                               "" => "<computed>"
  security_groups.#:                                 "" => "1"
  security_groups.2820007362:                        "" => "sg-******"
  subnet_id:                                         "" => "subnet-******"
  tags.#:                                            "" => "1"
  tags.Name:                                         "" => "test-001"
  tenancy:                                           "" => "<computed>"
  user_data:                                         "" => "53f8ca1523019339fffee792e0210ded15b39f5a"
  vpc_security_group_ids.#:                          "" => "<computed>"
aws_instance.test-001: Creation complete

Apply complete! Resources: 1 added, 1 changed, 1 destroyed.

ssh -i key ec2-user@10.0.0.5 でログインし、 prompt が変わっていることが確認できました。

[ec2-user@test-001 ~]$

とっても便利ですね!

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
25