あめがえるのITブログ

頑張りすぎない。ほどほどに頑張るブログ。

terraformでAmazon EC2を作成し、ユーザーデータを使って初期設定をしてみた

terraformでユーザーデータを渡す場合いくつかやり方があって、少し癖があったのでまとめてみた。

EC2ユーザーデータとは

EC2ではインスタンスを起動後にユーザーデータを渡して、自動設定タスクを実行したり、スクリプトを実行することができる機能。




やること

terraformでAmazon EC2を作成し、初期設定まで完了させる。
今回はhttpdをインストールし、自動起動設定を行い、トップページに表示させるhtmlファイルの作成および配置までを行う。

前提

下記をもとにterraformのインストールまで完了していること。 amegaeru.hatenablog.jp

実践!

1.ヒアドキュメントでユーザーデータを受け渡し

ヒアドキュメントとは
ヒアドキュメントとは、プログラミング言語などの機能の一つで、特殊な記号などを含む文字列リテラルソースコード中に記述するための特別な記法のこと。

 1-1.tfファイル作成

$ vi main.tf
provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_instance" "sample" {
  ami                                         = "ami-07c2a88388bb80eb0"
  instance_type                          = "t2.micro"
  availability_zone                     = "ap-northeast-1a"
  subnet_id                                = "subnet-08ced1e54ca9c6451"
  key_name                                = "sample-key"
  associate_public_ip_address   = "true"
  user_data = <<EOF
    #!/bin/bash
    yum install -y httpd
    echo "<html><body>Hello World!</body></html>" > /var/www/html/index.html
    systemctl enable --now httpd
  EOF

  tags = {
    Name = "sample-instance"
  }
}


 1-2.terraform実行

$ terraform init
$ terraform validate
$ terraform plan
$ terraform apply
※Enter a value:が表示されたら[yes]を入力


 1-3.動作確認1(terraform showコマンド)

$ terraform show
# aws_instance.sample:
resource "aws_instance" "sample" {
    ami                                  = "ami-07c2a88388bb80eb0"
    arn                                  = "arn:aws:ec2:ap-northeast-1:xxxxxxxx:instance/i-0f00269ca2d8a8d01"
    associate_public_ip_address          = true
    availability_zone                    = "ap-northeast-1a"
    cpu_core_count                       = 1
    cpu_threads_per_core                 = 1
    disable_api_stop                     = false
    disable_api_termination              = false
    ebs_optimized                        = false
    get_password_data                    = false
    hibernation                          = false
    id                                   = "i-0f00269ca2d8a8d01"
    instance_initiated_shutdown_behavior = "stop"
    instance_state                       = "running"
    instance_type                        = "t2.micro"
    ipv6_address_count                   = 0
    ipv6_addresses                       = []
    key_name                             = "sample-key"
    monitoring                           = false
    placement_partition_number           = 0
    primary_network_interface_id         = "eni-00fbe50b3d4fb355f"
    private_dns                          = "ip-172-31-47-60.ap-northeast-1.compute.internal"
    private_ip                           = "172.31.47.60"
    public_dns                           = "ec2-13-231-213-119.ap-northeast-1.compute.amazonaws.com"
    public_ip                            = "13.231.213.119"
    secondary_private_ips                = []
    security_groups                      = [
        "default",
    ]
    source_dest_check                    = true
    subnet_id                            = "subnet-08ced1e54ca9c6451"
    tags                                 = {
        "Name" = "sample-instance"
    }
    tags_all                             = {
        "Name" = "sample-instance"
    }
    tenancy                              = "default"
    user_data                            = "3876765ecb6ea8c6b0d1737c4391ae33d2d0eb4e"
    user_data_replace_on_change          = false
    vpc_security_group_ids               = [
        "sg-08591299bb5c05e63",
    ]

    capacity_reservation_specification {
        capacity_reservation_preference = "open"
    }

    cpu_options {
        core_count       = 1
        threads_per_core = 1
    }

    credit_specification {
        cpu_credits = "standard"
    }

    enclave_options {
        enabled = false
    }

    maintenance_options {
        auto_recovery = "default"
    }

    metadata_options {
        http_endpoint               = "enabled"
        http_put_response_hop_limit = 1
        http_tokens                 = "optional"
        instance_metadata_tags      = "disabled"
    }

    private_dns_name_options {
        enable_resource_name_dns_a_record    = false
        enable_resource_name_dns_aaaa_record = false
        hostname_type                        = "ip-name"
    }

    root_block_device {
        delete_on_termination = true
        device_name           = "/dev/xvda"
        encrypted             = false
        iops                  = 100
        tags                  = {}
        throughput            = 0
        volume_id             = "vol-0ab26bbb43da00eba"
        volume_size           = 8
        volume_type           = "gp2"
    }
}


 1-4.動作確認2(ブラウザ表示)
  ブラウザから接続し[Hello World!]が表示されることを確認
  ※接続IPはEC2のインスタンスから確認


 1-5.削除

$ terraform destroy
※Enter a value:が表示されたら[yes]を入力


2.外部ファイルでユーザデータを受け渡し
 2-1.スクリプト作成

$ vi script.sh
#!/bin/bash
yum install -y httpd
echo "<html><body>Hello World!</body></html> > /var/www/html/index.html
systemctl enable --now httpd


 2-2.trファイル作成

$ vi main.tf
provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_instance" "sample" {
  ami                                         = "ami-07c2a88388bb80eb0"
  instance_type                          = "t2.micro"
  availability_zone                     = "ap-northeast-1a"
  subnet_id                                = "subnet-08ced1e54ca9c6451"
  key_name                                = "sample-key"
  associate_public_ip_address   = "true"
  user_data = file("script.sh")

  tags = {
    Name = "sample-instance"
  }
}


 2-3.terraform実行

$ terraform apply
※Enter a value:が表示されたら[yes]を入力


 2-4.動作確認1(terraform showコマンド)

$ terraform show
# aws_instance.sample:
resource "aws_instance" "sample" {
    ami                                  = "ami-07c2a88388bb80eb0"
    arn                                  = "arn:aws:ec2:ap-northeast-1:xxxxxx:instance/i-00e962baabd76623f"
    associate_public_ip_address          = true
    availability_zone                    = "ap-northeast-1a"
    cpu_core_count                       = 1
    cpu_threads_per_core                 = 1
    disable_api_stop                     = false
    disable_api_termination              = false
    ebs_optimized                        = false
    get_password_data                    = false
    hibernation                          = false
    id                                   = "i-00e962baabd76623f"
    instance_initiated_shutdown_behavior = "stop"
    instance_state                       = "running"
    instance_type                        = "t2.micro"
    ipv6_address_count                   = 0
    ipv6_addresses                       = []
    key_name                             = "sample-key"
    monitoring                           = false
    placement_partition_number           = 0
    primary_network_interface_id         = "eni-09ad59bb16d6d34bb"
    private_dns                          = "ip-172-31-44-223.ap-northeast-1.compute.internal"
    private_ip                           = "172.31.44.223"
    public_dns                           = "ec2-54-248-13-131.ap-northeast-1.compute.amazonaws.com"
    public_ip                            = "54.248.13.131"
    secondary_private_ips                = []
    security_groups                      = [
        "default",
    ]
    source_dest_check                    = true
    subnet_id                            = "subnet-08ced1e54ca9c6451"
    tags                                 = {
        "Name" = "sample-instance"
    }
    tags_all                             = {
        "Name" = "sample-instance"
    }
    tenancy                              = "default"
    user_data                            = "3ce9f5f33c8fdd06711792cc996744ebff4ae6c8"
    user_data_replace_on_change          = false
    vpc_security_group_ids               = [
        "sg-08591299bb5c05e63",
    ]

    capacity_reservation_specification {
        capacity_reservation_preference = "open"
    }

    cpu_options {
        core_count       = 1
        threads_per_core = 1
    }

    credit_specification {
        cpu_credits = "standard"
    }

    enclave_options {
        enabled = false
    }

    maintenance_options {
        auto_recovery = "default"
    }

    metadata_options {
        http_endpoint               = "enabled"
        http_put_response_hop_limit = 1
        http_tokens                 = "optional"
        instance_metadata_tags      = "disabled"
    }

    private_dns_name_options {
        enable_resource_name_dns_a_record    = false
        enable_resource_name_dns_aaaa_record = false
        hostname_type                        = "ip-name"
    }

    root_block_device {
        delete_on_termination = true
        device_name           = "/dev/xvda"
        encrypted             = false
        iops                  = 100
        tags                  = {}
        throughput            = 0
        volume_id             = "vol-05c42553881cb5283"
        volume_size           = 8
        volume_type           = "gp2"
    }
}


 2-5.動作確認2(ブラウザ表示)
  ブラウザから接続し[Hello World!]が表示されることを確認


 2-6.削除

$ terraform destroy
※Enter a value:が表示されたら[yes]を入力



感想

ヒアドキュメントではechoで複数行使えなかったので外部ファイルからの受け渡しが楽でした(*´ω`*)