Help us understand the problem. What is going on with this article?

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

More than 3 years have 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に渡したい

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away