概要
こんにちは。HashiCorp Advent Calendar 2015 12日目の@ikemonnです。
この記事では、WerckerとTerraformを使ってEC2を立てる方法について書きます。
フローとしては下記のような感じです。
- 開発用のdevelopブランチにgit push
- pushをhookして、Wercker上でterraform plan
- terraform planが通ったら自動的にpull reqを作成
- pull reqがマージされたら、Wercker上でdeployボタンを押し、terraform applyしてEC2インスタンスをたてる
下準備
まず下記を済ませておきます。
- Werckerでアカウント登録をする
- Werckerで対象のリポジトリを登録する
- curlを叩いてpull reqを作れるようにGitHubのアクセストークンを取得する
- tfstateを管理するためのbucketをS3に用意する(Amazon S3 で Terraform の状態管理ファイル terraform.tfstate を管理 / 共有する - Qiita)
Terraformの準備
今回作るのはt2.microのインスタンスです。
こんな感じでtfファイルを準備します。
resource "aws_instance" "sample" {
ami = "ami-908a2f90"
instance_type = "t2.micro"
availability_zone = "ap-northeast-1a"
tags {
Name = "terraform_sample"
}
vpc_security_group_ids = ["${var.default_security_group}"]
key_name = "${var.lc_key_name}"
}
region = "ap-northeast-1"
default_security_group = “sg-xxxxxxx"
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {}
variable "default_security_group" {}
variable "lc_key_name" {}
provider "aws" {
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
region = "${var.region}"
}
TF_VAR_aws_access_key=“youraccesskey"
TF_VAR_aws_secret_key=“yoursecretkey"
TF_VAR_lc_key_name=“yourkey"
開発者が複数人でも大丈夫なように、tfstateは先ほど準備したS3に置くことにします。
terraform remote config -backend=S3 -backend-config=“bucket=your-terraform-state-bucket" -backend-config="key=terraform.tfstate" -backend-config="encrypt=true"
ここで一度、ローカル環境でTerraformが実行できるか確認しておくと手戻りが少なくて良いと思います。
Werckerの準備
先ほどWerckerをリポジトリに連携させたので、適当なブランチにpushするとrootディレクトリ直下にあるwercker.yamlで記述した処理が実行されます。
.
├── terraform
│ ├── common_variables.tf
│ ├── sample_ec2.tf
│ └── terraform.tfvars
└── wercker.yml
今回はterraformをwgetでinstallして、それを使ってterraform planとapplyを実行します。
同時に、その他必要なものを一緒にinstallしておきます。
(buildとdeployの処理が冗長なので、boxやstepを利用するともっと簡潔に書けると思います)
box: debian
build:
steps:
- script:
name: install some tools
code: |
sudo apt-get update
sudo apt-get -f install
sudo apt-get install -y wget unzip curl
- script:
name: setup terraform
code: |
# create terraform directory and export PATH
mkdir -p $HOME/terraform
export PATH=$PATH:$HOME/terraform
# download terraform
VERSION=0.6.8
cd $HOME/terraform
wget https://releases.hashicorp.com/terraform/${VERSION}/terraform_${VERSION}_linux_amd64.zip
unzip terraform_${VERSION}_linux_amd64.zip
rm terraform_${VERSION}_linux_amd64.zip
- script:
name: terraform remote config
code: |
cd terraform
terraform remote config -backend=S3 -backend-config="bucket=your-terraform-state-bucket" -backend-config="key=terraform.tfstate" -backend-config="encrypt=true"
terraform plan
- script:
name: create pull request
code: |
curl -u "[username]:${GITHUB_TOKEN}" -d '{"title": "Terraform plan Success","body": "You can merge this pull request","head": "[username]:[fromBranch]","base": "[toBranch]"}' https://api.github.com/repos/[username]/[yourBranch]/pulls
deploy:
steps:
- script:
name: install some tools
code: |
sudo apt-get update
sudo apt-get -f install
sudo apt-get install -y wget unzip curl
- script:
name: setup terraform
code: |
# create terraform directory and export PATH
mkdir -p $HOME/terraform
export PATH=$PATH:$HOME/terraform
# download terraform
VERSION=0.6.8
cd $HOME/terraform
wget https://releases.hashicorp.com/terraform/${VERSION}/terraform_${VERSION}_linux_amd64.zip
unzip terraform_${VERSION}_linux_amd64.zip
rm terraform_${VERSION}_linux_amd64.zip
- script:
name: terraform remote config
code: |
cd terraform
terraform remote config -backend=S3 -backend-config="bucket=your-terraform-state-bucket" -backend-config="key=terraform.tfstate" -backend-config="encrypt=true"
terraform plan
- script:
name: terraform apply
code: |
terraform apply
その後、Wercker上で環境変数を設定できるので、awsのkeyやGitHubのトークンなど必要な環境変数を設定しておきます。
git pushからデプロイまで
その後、適当なブランチにpushしてみましょう。
Werckerがpushを検知してbuildフェーズに書かれている処理を実行します。
terraform planまで成功すると、devからmasterにpull reqが送られます。
pull reqをマージするとmergeされたことを検知して、masterブランチでbuildが走ります。
buildが成功したらdeployボタンを押します。
ここで、deployフェーズの処理にあるterraform apply
が実行されます。
AWSコンソールを確認すると無事インスタンスができていることがわかります。
改善点
- Werckerの部分が冗長なのでBoxやStepを使ってすっきりさせたい
- terraform planの結果をpull reqのbodyに渡したい