雑記

インフラのことだったりプログラムのことだったりどうでもいいこと書いたり。要は雑記。

Terraformで最低限のAWS環境を作ってみた

タイトル通り。

Terraformってなに?

インフラの構成をコード化するもの。

AWSに限っていうと、VPCやSecurityGroup、GatewayからEC2などなどをコード化できる。 (Terraform自体はAWSだけでなく、DigitalOceanやHerokuなど各種サービスに対応している)

サーバの中身をコード化するChefやAnsibleなどとはそもそも異なる。

Terraform by HashiCorp

インストール

Macの場合はHomebrewで一発

% brew install terraform

2015/07時点の最新版である0.6がインストールされた。 以降、0.6でのお話し。

設定

tfファイルで構成を定義する。 以下、AWSインスタンスを作成する設定サンプル。

# Credential
provider "aws" {
    access_key = "xxxxxxxxxx"
    secret_key = "xxxxxxxxxx"
    region = "ap-northeast-1"
}

# Create instance
resource "aws_instance" "sample" {
    ami = "ami-cbf90ecb" # Amazon Linux AMI 2015.03 (HVM), SSD Volume Type
    instance_type = "t2.micro"
    tags {
      Name = "sample"
    }
}

コマンド

作成したtfファイルを元に適用のテストをする(ようはdry-run)

% terraform plan

作成したtfファイルを元に構成を適用する

% terraform apply

構成を全て破棄する

% terraform destroy

構成を確認する

% terraform show

試しに

AWSで一通りの構成を作ってみた。

github.com

これで作れるものは以下。

  • Key Pairs
  • VPC
  • Subnets
  • Internet Gateway
  • Route Tables
  • Security Groups
  • EC2
  • ELB

気になったこと

tfstateファイルについて

terraform applyを実行すると、tfstateファイルが作成されます。

こいつが現在の生の構成を把握するファイルみたいなので、複数人で利用する場合は統一する必要があります。

インスタンスの設定変更について

EC2インスタンスを一度立ち上げた後に設定を変更する場合、なんと一度Destroyしてからの再作成となります。 SecurityGroupを追加してもそうなりました(ただ、タグの追加は大丈夫でした) 完璧にImmutable化できているのなら大丈夫ですが、そうでない場合やインスタンスの用途がDB系である場合は要注意かと思います。

感想

使ってて気持ちいい。 apply -> destroy -> applyして全く同じ環境ができるのはちょっと感動。 初めて構成管理ツール使った時の感覚を思い出しました。

とりあえずは軽めのところから実践投入する予定。

ImageMagick-lastをAmazonLinuxにインストールする

AmazonLinuxでインストールできるImageMagickは若干バージョンが古いです。 最新版をパッケージでインストールするにはremiから入れればいいのですが、普通にやると依存関係でエラーがでます。

エラー: パッケージ: ImageMagick-last-libs-6.9.1.2-1.el6.remi.x86_64 (remi)
             要求: libHalf.so.6()(64bit)
エラー: パッケージ: ImageMagick-last-libs-6.9.1.2-1.el6.remi.x86_64 (remi)
             要求: libIlmImf.so.6()(64bit)
エラー: パッケージ: ImageMagick-last-libs-6.9.1.2-1.el6.remi.x86_64 (remi)
             要求: libgdk_pixbuf-2.0.so.0()(64bit)
エラー: パッケージ: ImageMagick-last-libs-6.9.1.2-1.el6.remi.x86_64 (remi)
             要求: libIex.so.6()(64bit)
エラー: パッケージ: ImageMagick-last-libs-6.9.1.2-1.el6.remi.x86_64 (remi)
             要求: librsvg-2.so.2()(64bit)
エラー: パッケージ: ImageMagick-last-devel-6.9.1.2-1.el6.remi.x86_64 (remi)
             要求: OpenEXR-devel(x86-64)
エラー: パッケージ: ImageMagick-last-libs-6.9.1.2-1.el6.remi.x86_64 (remi)
             要求: libImath.so.6()(64bit)
エラー: パッケージ: ImageMagick-last-libs-6.9.1.2-1.el6.remi.x86_64 (remi)
             要求: libIlmThread.so.6()(64bit)

手取り早く解決するためにCentOSのBaseレポジトリを利用すればよいです。

レポジトリの追加

CentOS-Base

[base]
name=CentOS-6 - Base
mirrorlist=http://mirrorlist.centos.org/?release=6&arch=x86_64&repo=os
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-6

remi

ImageMagick-lastを入れるために利用

# yum install http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

インストール

これでImageMagick-lastをインストールすればよいと思いきや、今度はlibwebpで依存関係がでます。 AmazonLinuxだとlibwebpのバージョンが0.3だから? なので、epelからwebpをインストールするようにすればOKです。

先にlibwebpだけをインストール。

# yum install libwebp-devel --enablerepo=epel --disablerepo=amzn-main

で、ImageMagickをインストール

# yum install ImageMagick-last ImageMagick-last-devel --enablerepo=epel,base,remi

参考

AWS SDK for GOを使ってRoute53のレコードを取得する

タイトル通り、サンプル作ってみました

環境

% go version
go version go1.4.2 darwin/amd64

準備

  • パッケージの取得
% go get -u github.com/aws/aws-sdk-go/
% go get -u github.com/vaughan0/go-ini

go-iniはaws-sdk-goのcredentialsで使ってるらしく、いれていないと以下のエラーがでる

../../../../.golocal/src/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go:8:2: cannot find package "github.com/vaughan0/go-ini" in any of:
        /usr/local/Cellar/go/1.4.2/libexec/src/github.com/vaughan0/go-ini (from $GOROOT)
        /Users/ogawa-masaki/.golocal/src/github.com/vaughan0/go-ini (from $GOPATH)
  • クレデンシャルの設定
% cat ~/.aws/credentials
[default]
aws_access_key_id = xxxxxxxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

サンプル

登録しているレコード情報を表示するだけです。

package main

import(
    "fmt"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/awsutil"
    "github.com/aws/aws-sdk-go/service/route53"
)

func main() {
    domain := "example.internal."

    client := route53.New(&aws.Config{})

    // domainからHostedZoneIDの取得
    hzresp, err := client.ListHostedZonesByName(&route53.ListHostedZonesByNameInput{DNSName: aws.String(domain),})
    if err != nil {
        panic(err)
    }
    HostedZoneID := hzresp.HostedZones[0].ID

    // ResourceRecordSetsを取得
    rrsresp, err := client.ListResourceRecordSets(&route53.ListResourceRecordSetsInput{HostedZoneID: HostedZoneID})
    if err != nil {
        panic(err)
    }

    // 出力
    for i := range rrsresp.ResourceRecordSets {
        fmt.Println(awsutil.StringValue(*rrsresp.ResourceRecordSets[i]))
    }
}

AWS SDK for GOもついにPreview版となりましたし、どんどん活用していきたいですね。

go langことはじめ

ちょっとgoさわってみたくなった

インストール

Macなのでhomebewで

% brew install go

ちょーかんたん

PATHの設定

zshなので.zprofileで

if [ -x "`which go`" ]; then
    export GOROOT=`go env GOROOT`
    export GOPATH=$HOME/.golocal
    export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
fi

事前にmkdir ~/.golocalしてます

はろーごーらんぐ

定番

  • hello.go
package main

import "fmt"

func main() {
    fmt.Println("はろーごーらんぐ")
}

というか普通に日本語つかえた。

build

% go build hello.go

実行

% ./hello
はろーごーらんぐ

でけた。

ちなみに

なんでいきなりgoかというと、aws-goを使ってみたかったから。 AWS API使ったすごい簡単なものをpythonで作ったんだけど、ふとこれをgoで作ったらどんなんになるんだろと思って。

というわけでこれからaws-goで遊んでみます。

EC2のタグをCLIで管理するtapewriterというツールを作った

タイトル通りですが、EC2のタグをCLIで管理したくて(=コード化したくて)作ってみました。

route53をDSLで管理するroadworkerという素晴らしいツールがあるのですが、おもいっきりその影響を受けています。 (や、ほんと素晴らしいツールで結構な衝撃だったんです)

なにをするもの?

EC2のタグをjsonで管理できるようになるツールです。 jsonなのでバージョン管理もバックアップも取れます。

どんなところで使うの?

  • タグのバックアップをとりたいとき
  • タグをバージョン管理したいとき
  • ブラウザでの作業が嫌だというとき
  • タグを一気に変更したいとき

つかいかた

 タグをエクスポートする

% tapewriter -r ap-northeast-1 -f dev-app.json --export --filter '{"Env":"dev", "Role":"app"}' 

フィルターが使えます

タグを編集する

  • 変更前
{
  "instances": [
    {
      "id": "i-11111111",
      "region": "ap-northeast-1",
      "tags": {
        "Env": "dev",
        "Role": "app",
        "Name": "hoge",
        "State": "standby"
      }
    },
    {
      "id": "i-22222222",
      "region": "ap-northeast-1",
      "tags": {
        "Env": "dev",
        "Role": "app",
        "Name": "fuga",
        "State": "standby"
      }
    }
  ]
}
  • 変更後
{
  "instances": [
    {
      "id": "i-11111111",
      "region": "ap-northeast-1",
      "tags": {
        "Env": "dev",
        "Role": "app",
        "Name": "hoge",
        "State": "run"
      }
    },
    {
      "id": "i-22222222",
      "region": "ap-northeast-1",
      "tags": {
        "Env": "dev",
        "Role": "app",
        "Name": "fuga",
        "State": "run"
      }
    }
  ]
}

Stateタグを変更しています。

dry-run(テスト実行)

どんな変更がされるか確認

% tapewriter -r ap-northeast-1 -f dev-app.json --apply --dry-run

適用

タグを適用

% tapewriter -r ap-northeast-1 -f dev-app.json --apply

実際使ってみて

複数インスタンスのタグを一気に変更したいときにあってよかったなーと思いました。

でも1つのインスタンスのタグを一つだけ変える、とかだったらAWSコンソールからやったほうが早いです。

そもそも

みんなタグってどうやって管理しているんだろ。というかそもそも使ってないのか?ちょっと聞いてみたい。