terraformでEC2+RDS+ElastiCacheを構築してみる(その1 EC2構築まで)


仕事ではAWS、プライベートではGCPを使うので、オーケストレーションツールで両方で使えるterraformを今更ながら試してみた。

#環境

macOS mojave Version 10.14.4
Terraform v0.11.13
provider. 

#目的
EC2+RDS+ElastiCacheを使ったシステムの構築

#事前準備
AWSアカウントを持っていること、IAMユーザを発行していること

# Terraformインストール

公式のページからmac 64bit版をダウンロード

https://www.terraform.io/downloads.html

バイナリを自分の好きなところにおいてパスを通す

```
% mkdir ~/APPS/
% wget https://releases.hashicorp.com/terraform/0.11.13/terraform_0.11.13_darwin_amd64.zip
% unzip terraform_0.11.13_darwin_amd64.zip
% echo 'export PATH="$HOME/APPS:$PATH"' >> ~/.zshrc    ※bashではあれば読み替え
% terraform --version
Terraform v0.11.13
+ provider.aws v2.6.0
```

# Terraformの初期化

terraformを使用するには初期化が必要です。
実行するとpluginを同ファイル内にインストールします。

```
% terraform init
Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "aws" (2.6.0)...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.aws: version = "~> 2.6"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

```

# 最小構成のtfファイルの作成

terraformでは定義ファイルの拡張子はtfです。

```
% mkdir terreform_test
% cd terreform_test
% vim example.tf
% cat example.tf 
provider "aws" {
  access_key = "xxxxxxxxxxxxxx"
  secret_key = "xxxxxxxxxxxxxx"
  region     = "ap-northeast-1"
}

resource "aws_instance" "example" {
  ami           = "ami-0f9ae750e8274075b"   ※存在しているAMIIDを指定
  instance_type = "t2.micro"
}
```

公式ドキュメントより

>Note: If you simply leave out AWS credentials, Terraform will automatically search for saved >API credentials (for example, in ~/.aws/credentials) or IAM instance profile credentials. This >option is much cleaner for situations where tf files are checked into source control or where >there is more than one admin user. See details here. Leaving IAM credentials out of the >Terraform configs allows you to leave those credentials out of source control, and also use >different IAM credentials for each user without having to modify the configuration files.

とのことなので、すでにcredentialの設定をlocalでしている方は自動でTerraformが取得してくれるようです。
今回は定義ファイル内に記載。

# 構築する環境の確認と実行
|コマンド  |説明|
|---|---|
|terraform plan  | 構築予定の環境確認|
|terraform apply  | 構築実行|
|terraform show  |構築した環境確認  |


確認

```
% terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + aws_instance.example
      id:                           <computed>
      ami:                          "ami-0f9ae750e8274075b"
      arn:                          <computed>
      associate_public_ip_address:  <computed>
      availability_zone:            <computed>
      cpu_core_count:               <computed>
      cpu_threads_per_core:         <computed>
      ebs_block_device.#:           <computed>
      ephemeral_block_device.#:     <computed>
      get_password_data:            "false"
      host_id:                      <computed>
      instance_state:               <computed>
      instance_type:                "t2.micro"
      ipv6_address_count:           <computed>
      ipv6_addresses.#:             <computed>
      key_name:                     <computed>
      network_interface.#:          <computed>
      network_interface_id:         <computed>
      password_data:                <computed>
      placement_group:              <computed>
      primary_network_interface_id: <computed>
      private_dns:                  <computed>
      private_ip:                   <computed>
      public_dns:                   <computed>
      public_ip:                    <computed>
      root_block_device.#:          <computed>
      security_groups.#:            <computed>
      source_dest_check:            "true"
      subnet_id:                    <computed>
      tenancy:                      <computed>
      volume_tags.%:                <computed>
      vpc_security_group_ids.#:     <computed>
```

構築

```
% terraform apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + aws_instance.example
      id:                           <computed>
      ami:                          "ami-0f9ae750e8274075b"
      arn:                          <computed>
      associate_public_ip_address:  <computed>
      availability_zone:            <computed>
      cpu_core_count:               <computed>
      cpu_threads_per_core:         <computed>
      ebs_block_device.#:           <computed>
      ephemeral_block_device.#:     <computed>
      get_password_data:            "false"
      host_id:                      <computed>
      instance_state:               <computed>
      instance_type:                "t2.micro"
      ipv6_address_count:           <computed>
      ipv6_addresses.#:             <computed>
      key_name:                     <computed>
      network_interface.#:          <computed>
      network_interface_id:         <computed>
      password_data:                <computed>
      placement_group:              <computed>
      primary_network_interface_id: <computed>
      private_dns:                  <computed>
      private_ip:                   <computed>
      public_dns:                   <computed>
      public_ip:                    <computed>
      root_block_device.#:          <computed>
      security_groups.#:            <computed>
      source_dest_check:            "true"
      subnet_id:                    <computed>
      tenancy:                      <computed>
      volume_tags.%:                <computed>
      vpc_security_group_ids.#:     <computed>


Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes　　　　　　※ここでyesを入力

aws_instance.example: Creating...
  ami:                          "" => "ami-0f9ae750e8274075b"
  arn:                          "" => "<computed>"
  associate_public_ip_address:  "" => "<computed>"
  availability_zone:            "" => "<computed>"
  cpu_core_count:               "" => "<computed>"
  cpu_threads_per_core:         "" => "<computed>"
  ebs_block_device.#:           "" => "<computed>"
  ephemeral_block_device.#:     "" => "<computed>"
  get_password_data:            "" => "false"
  host_id:                      "" => "<computed>"
  instance_state:               "" => "<computed>"
  instance_type:                "" => "t2.micro"
  ipv6_address_count:           "" => "<computed>"
  ipv6_addresses.#:             "" => "<computed>"
  key_name:                     "" => "<computed>"
  network_interface.#:          "" => "<computed>"
  network_interface_id:         "" => "<computed>"
  password_data:                "" => "<computed>"
  placement_group:              "" => "<computed>"
  primary_network_interface_id: "" => "<computed>"
  private_dns:                  "" => "<computed>"
  private_ip:                   "" => "<computed>"
  public_dns:                   "" => "<computed>"
  public_ip:                    "" => "<computed>"
  root_block_device.#:          "" => "<computed>"
  security_groups.#:            "" => "<computed>"
  source_dest_check:            "" => "true"
  subnet_id:                    "" => "<computed>"
  tenancy:                      "" => "<computed>"
  volume_tags.%:                "" => "<computed>"
  vpc_security_group_ids.#:     "" => "<computed>"
aws_instance.example: Still creating... (10s elapsed)
aws_instance.example: Still creating... (20s elapsed)
aws_instance.example: Still creating... (30s elapsed)
aws_instance.example: Creation complete after 33s (ID: i-08d3e6512751c8505)

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

構築した環境確認

```
% terraform show
aws_instance.example:
  id = i-08d3e6512751c8505
  ami = ami-0f9ae750e8274075b
~
```

AWSコンソールで確認
<img width="933" alt="Screen Shot 2019-04-13 at 17.02.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267983/cff8cd17-612b-407d-3dea-4f728871dddc.png">


#参考

[Terraform 公式ドキュメント](https://www.hashicorp.com/products/terraform/)
[Terraform get started](https://learn.hashicorp.com/terraform/?track=getting-started#getting-started)