Terraformを試してみた


##参考
前佛さんと大瀧さんのエントリーを参考に
[Terraformのblog投稿、参考訳](http://qiita.com/zembutsu/items/402e02950ce9d59fa0e6)
[Terraform簡易チュートリアル on AWS](http://qiita.com/zembutsu/items/93e546df765f8b2c4f32)
[HashiCorpの新オーケストレーションツールTerraformを試してみた](http://dev.classmethod.jp/cloud/terraform-first-impression/)


##試してみる
- Terraformのダウンロード・インストール

```
$ mkdir terraform
$ cd terraform
$ wget -O 0.1.0_linux_amd64.zip https://dl.bintray.com/mitchellh/terraform/0.1.0_linux_amd64.zip
$ unzip ./0.1.0_linux_amd64.zip
Archive:  ./0.1.0_linux_amd64.zip
  inflating: terraform
  inflating: terraform-provider-aws
  inflating: terraform-provider-consul
  inflating: terraform-provider-digitalocean
  inflating: terraform-provider-dnsimple
  inflating: terraform-provider-heroku
  inflating: terraform-provisioner-file
  inflating: terraform-provisioner-local-exec
  inflating: terraform-provisioner-remote-exec
```

- バージョン確認

```
$ ./terraform --version
Terraform v0.1.0
```

- 設定ファイルの配置

```
$ vi aws.tf
```

> provider "aws" {
    access_key = "AKIxxxxxxxxxxxx"
    secret_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
    region = "ap-northeast-1"
}
> 
> resource "aws_instance" "test1" {
    ami = "ami-29dc9228"
    instance_type = "t2.micro"
    subnet_id = "subnet-xxxxxxxx"
}

VPCの中にインスタンスを作成するためには、subnet_idを指定すればよいらしいです。vpc-idは指定しなくてもよいというあたりが地味に嬉しいですね。
※キーとサブネットIDは自分ので

- planで計画

```
$ ./terraform plan
Refreshing Terraform state prior to plan...

aws_instance.example: Refreshing state... (ID: i-6a3f076c)

The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

+ aws_instance.test1
    ami:               "" => "ami-29dc9228"
    availability_zone: "" => "<computed>"
    instance_type:     "" => "t2.micro"
    key_name:          "" => "<computed>"
    private_dns:       "" => "<computed>"
    private_ip:        "" => "<computed>"
    public_dns:        "" => "<computed>"
    public_ip:         "" => "<computed>"
    security_groups:   "" => "<computed>"
    subnet_id:         "" => "subnet-xxxxxxxx"
```

- applyでインスタンス起動

```
$ ./terraform apply
aws_instance.example: Refreshing state... (ID: i-6a3f076c)
aws_instance.test1: Creating...
  ami:           "" => "ami-29dc9228"
  instance_type: "" => "t2.micro"
  subnet_id:     "" => "subnet-xxxxxxxx"
aws_instance.example: Destruction complete
aws_instance.test1: Creation complete

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

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path: terraform.tfstate
```

**インスタンスが起動していることが確認できます**
![スクリーンショット_2014-07-29_11_37_49.png](https://qiita-image-store.s3.amazonaws.com/0/11653/47005edf-9bb7-af59-2de3-b75f049d6e64.png "スクリーンショット_2014-07-29_11_37_49.png")


## 設定を変更してみる
```
$ vi aws.tf
```
インスタンスタイプをt2.smallにして実行してみる
> provider "aws" {
    access_key = "AKIxxxxxxxxxxxx"
    secret_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
    region = "ap-northeast-1"
}
> 
> resource "aws_instance" "test1" {
    ami = "ami-29dc9228"
    instance_type = "t2.small"
    subnet_id = "subnet-xxxxxxxx"
}

- terraform plan

```
$ ./terraform plan
Refreshing Terraform state prior to plan...

aws_instance.test1: Refreshing state... (ID: i-04370f02)

The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

-/+ aws_instance.test1
    availability_zone: "ap-northeast-1b" => "<computed>"
    instance_type:     "t2.micro" => "t2.small" (forces new resource)
    key_name:          "" => "<computed>"
    private_dns:       "ip-10-0-1-78.ap-northeast-1.compute.internal" => "<computed>"
    private_ip:        "10.0.1.78" => "<computed>"
    public_dns:        "" => "<computed>"
    public_ip:         "" => "<computed>"
    security_groups:   "" => "<computed>"
    subnet_id:         "subnet-xxxxxxxx" => "<computed>"
```

- terraform apply

```
./terraform apply
aws_instance.test1: Refreshing state... (ID: i-04370f02)
aws_instance.test1: Destroying...
aws_instance.test1: Destruction complete
aws_instance.test1: Modifying...
  instance_type: "t2.micro" => "t2.small"
aws_instance.test1: Error: Error launching source instance: The parameter groupName cannot be used with the parameter subnet (InvalidParameterCombination)
Error applying plan:

1 error(s) occurred:

* Error launching source instance: The parameter groupName cannot be used with the parameter subnet (InvalidParameterCombination)

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
```
なんかエラーになる。。。

しかたないので再実行

```
$ ./terraform apply
aws_instance.test1: Creating...
  ami:           "" => "ami-29dc9228"
  instance_type: "" => "t2.small"
  subnet_id:     "" => "subnet-xxxxxxxx"
aws_instance.test1: Creation complete

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

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path: terraform.tfstate
```
今度はうまくいった
![スクリーンショット_2014-07-29_12_20_03.png](https://qiita-image-store.s3.amazonaws.com/0/11653/72cc0b8a-61e0-c0c4-8046-eb2749029289.png "スクリーンショット_2014-07-29_12_20_03.png")


**インスタンスサイズの変更について、インスタンスを削除して再作成してしまう（→Modifyのほうが期待される動きではないか）という点と、2回インスタンスサイズの変更をやったけど、必ず一回エラーになるという動きな模様**


試した範囲ではなかなかカジュアルに使えて便利なので、運用まで見据えてどう使いどころがあるかとか考えてみたいと思いました。