TerraformとWerckerを使って、git pushしたらEC2を立てる

  • 8
    Like
  • 0
    Comment
More than 1 year has passed since last update.

概要

こんにちは。HashiCorp Advent Calendar 2015 12日目の@ikemonnです。
この記事では、WerckerTerraformを使ってEC2を立てる方法について書きます。

フローとしては下記のような感じです。

  1. 開発用のdevelopブランチにgit push
  2. pushをhookして、Wercker上でterraform plan
  3. terraform planが通ったら自動的にpull reqを作成
  4. pull reqがマージされたら、Wercker上でdeployボタンを押し、terraform applyしてEC2インスタンスをたてる

下準備

まず下記を済ませておきます。

  1. Werckerでアカウント登録をする
  2. Werckerで対象のリポジトリを登録する
  3. curlを叩いてpull reqを作れるようにGitHubのアクセストークンを取得する
  4. tfstateを管理するためのbucketをS3に用意する(Amazon S3 で Terraform の状態管理ファイル terraform.tfstate を管理 / 共有する - Qiita)

Terraformの準備

今回作るのはt2.microのインスタンスです。
こんな感じでtfファイルを準備します。

sample_ec2.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}"
}
terraform.tfvars
region = "ap-northeast-1"
default_security_group = “sg-xxxxxxx"
common_variables.tf
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フェーズに書かれている処理を実行します。

スクリーンショット 2015-12-12 16.29.16.png

terraform planまで成功すると、devからmasterにpull reqが送られます。

スクリーンショット 2015-12-12 14.30.01.png

pull reqをマージするとmergeされたことを検知して、masterブランチでbuildが走ります。

スクリーンショット 2015-12-12 14.40.57.png

buildが成功したらdeployボタンを押します。
ここで、deployフェーズの処理にあるterraform applyが実行されます。

スクリーンショット 2015-12-12 16.17.16.png

AWSコンソールを確認すると無事インスタンスができていることがわかります。

スクリーンショット 2015-12-12 16.32.57.png

改善点

  • Werckerの部分が冗長なのでBoxやStepを使ってすっきりさせたい
  • terraform planの結果をpull reqのbodyに渡したい

参考