Sionの技術ブログ

SREとして日々の学習を書いて行きます。twitterは@sion_cojp

terraform-provider-awsの開発からPRを出すまでの手順

github.com

些細ではありますが、出したPRがmergeされました。

開発方法よくわからないなぁ。と思う人が多いと思うので、私が実際に行ったことを書いて見ます。

開発方法

# go get。今回は本家で修正して試して、その差分をあとでfork先に適用する感じ。
# この二度手間めんどくさいときは、$GOPATH/src/github.com/terraform-providersにforkしたやつをgit cloneしたほうが良い
$ go get -u github.com/terraform-providers/terraform-provider-aws

# よしなに修正

# buildする
$ cd $GOPATH/src/github.com/terraform-providers/terraform-provider-aws
$ make build
# このときgofmtしろってエラーが出たらgoのバージョンが低い可能性があります
# 最新にしてまたやってみましょう

# buildしたものを利用する
# 既存のproviderを削除して自前のbuildをcopy。copyしたらinitを打つ
$ cd terraform-repository/xxxxx.tfファイルがあるところ
$ rm -f .terraform/plugins/darwin_amd64/*
$ cp $GOPATH/terraform-provider-aws .terraform/plugins/darwin_amd64
$ terraform init

# planとapply。global.tfvarsを設定してるバージョンです
$ terraform plan
$ terraform apply -var-file=global.tfvars

# debugログの出力。めっちゃ便利
# TF_LOGでloglevelが設定できます
# TF_LOG_PATHでファイルに出力できます(追加保存)
$ TF_LOG=1 TF_LOG_PATH='/tmp/terraform.log' terraform apply -var-file=global.tfvars

test

PR出す際に貼らないといけません。 結構な権限を持ったaccess_key, secret_keyが必要です。

# 移動してtest。TESTARGSに設定するのはmethod名。*で正規表現マッチが使えます
$ cd $GOPATH/src/github.com/terraform-providers/terraform-provider-aws
$ AWS_ACCESS_KEY_ID=xxxx AWS_SECRET_ACCESS_KEY=xxxx make testacc TEST=./aws TESTARGS='-run=TestFetchRootDevice*'
# このときgofmtしろってエラーが出たらgoのバージョンが低い可能性があります
# 最新にしてまたやってみましょう

FOLIOに入社して3ヶ月経ちました

SREとして担当してたモバイルアプリもリリース出来て落ち着いたので書いてみようと思います

FOLIO is 何?

f:id:sion_cojp:20180803152158p:plain

Fintech

[https://folio-sec.com/:title]

入社してやったこと

  • terraform操作周りのリファクタ

    • バージョンの統一
    • terraformを打つまでの認証周りや、providerの設定、ソフトウェアのアップデートなど自動化
    • makeで terraform xxxx を打てるようにした
    • applyログをs3に保存するようにした
  • terraform module作った

    • ECS ec2 type
    • fargate
    • ECS task scheduler
    • waf + cloudfront + s3のsorryサーバ
  • モバイルのインフラ構築、運用

    • サーバレス
    • infra: fargate, ALB, waf, cloudfront, ECR
    • logging: cloudwatch, lambda, kinesis stream/firehose, s3, elastic search(ロギングは同じチームの人が作ってくれました。最高)
    • monitoring: datadog(terraformで管理)
    • slack chatopsをGoで書いた(ossにしたい)
    • リリース前にSREと必要な関係者を読んで、SRE本のLaunchチェックリストをベースに構成やモニタリングなどの最終チェックを行なった
  • セキュリティ周り

    • SSMでの暗号化、復号化を積極的に使った
    • GoでtomlからSSMの復号化出来るようにした GitHub - sioncojp/tomlssm
  • fargateで色々サービス立てた

terraform周り

入社したとき、terraformを打つまでにいろんな障壁があることを経験したので、即座に自動化タスクに取り組みました。

前職の影響からか、makeで色々と出来るようにし、今ではその障壁がなくなりました。

make helpはこんな感じです。

f:id:sion_cojp:20180803142154p:plain

弊社で動かしてるansibleやpacker周りも自動化したいです。 が、ansibleに関してはそもそも無くす(減らす)動きをしていく気持ちです。

モバイルのインフラ構築にあたって

「まだsshしてるの?」「開発者が開発に集中」という気持ちで進めてました。

結果sshはしなくなったので、セキュアにもなりましたし、インフラ運用コストも下がって楽になりました。

chatopsや、エラーログやアラートなどもslackで対応出来るようになったのもgood。

今回初めてやったのですが、SRE本にも書かれてる Launchチェックリストを元に、構成や仕組みを一から全てチェックしました。

これで安全にリリース出来るよねという合意と、サービスにあまり携わらなかった人もシステム構成を把握出来た(非属人化への一歩)のは良かったです。

fargate

モバイルアプリ用APIは、EC2で行こうという話だったのですが、

それだと技術的進歩が望めないので、ECSを導入しました。

最初はEC2 typeで導入したのですが、途中でfargateが登場したので載せ換えました。

挙動、特にEC2 typeにはないオプション周りで悩まされた記憶があります。

運用と拡張しやすいようなterraform module構成を意識したので、すぐにfargate構成が出来るようになりました(今は4, 5サービスくらい動いてます)

ECS task scheduler

fargate対応してないので、やむなくEC2 typeでmodule化。

chatops

slack interactive componentsを使っており、Goで書かれてます。

auth周りも実装してるので、config.tomlのプロジェクト設定にある指定された人しかdeploy出来なくなってます。

モバイルアプリのメンテナンス画面切り替えもこちらでやってます。

f:id:sion_cojp:20180803140150p:plain

  • プロジェクトを選択
  • prod, stg...を選択
  • ブランチを選択
  • 最後にコミット番号などが出るので、OK or cancelを選択
  • deploy finish

最後に

Fintechなのに、スピード感もって新しいことが出来るいい会社だなぁと思いました。

個人としては運用しやすい、拡張しやすいコードを意識して出来たのとも良かったです。

(そのため、コメントを中心にドキュメント(README.md)や構成図(draw.io)を充実させた。)

インフラ周りが落ち着いたら、microserviceアーキテクチャの実装や、認証認可のサービス実装など色々やりたいですね。

tomlファイルをParameterStoreからdecodeするtomlssmを作った

github.com

GitHub - suzuken/yamlssm と同様にtomlでも出来るようにしました。

やってることは

  • AWS System Managerで、Parameter Storeでを設定する(例えばxxxという名前でsecure stringで設定します)
  • "ssm://xxxx" と書いてると、toml読み込み時にxxxの部分をdecodeする

使い方はREADMEにも書いてますが、下記のように使います

1. decode

package main

import (
    "fmt"
    toml "github.com/sioncojp/tomlssm"
)

type Config struct {
    User     string `toml:"username"`
    Password string `toml:"password"`
}

func LoadToml(c string) (*Config, error) {
    var config Config
    if _, err := toml.Decode(c, &config, "ap-northeast-1"); err != nil {
        return nil, err
    }
    return &config, nil
}

func main() {
    conf, err := LoadToml(`
username = "test"
password = "ssm://password"
`)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(conf)
}

2. tomlファイルを指定する

# config.toml
username = "test"
password = "ssm://password"
package main

import (
    "fmt"
    toml "github.com/sioncojp/tomlssm"
)

type Config struct {
    User     string `toml:"username"`
    Password string `toml:"password"`
}

func LoadToml(c string) (*Config, error) {
    var config Config
    if _, err := toml.DecodeFile(c, &config, "ap-northeast-1"); err != nil {
        return nil, err
    }
    return &config, nil
}

func main() {
    conf, err := LoadToml("config.toml")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(conf)
}

GKEでGoのhttpサーバを動かしてみた

Overview

GKEを触ってみたかったので実際に触ってみた。

ref: クイックスタート  |  Kubernetes Engine のドキュメント  |  Google Cloud

ソースはこちら

github.com

ただの"Hello World"を返すGoのコード。

kubernetes特有で、 /healthz がヘルスチェック用のpathなんですね。

READMEの通りにやれば動くと思います。

流れとしては、

- gcloudコマンドインストール、アカウント設定、ログイン(project_idゲット。とcredential(JSON)を作ってゲット)
- gcloudでkubectlインストール
- gcloudでGCRにイメージを保存するために、docker-credential-gcrインストール
- GCRにイメージpush
- gcloudでクラスタ作成
- kubectlでクラスタにdeploy
- curlでアクセス出来る

感想

  • cliがよくできてるなぁと思った。特にgcloud
    • ID/credential情報さえ指定すれば、あとは引数にIAMやVPCを気にしなくて良い。
    • awsと比べて短いcliで動かせるのがよかった
    • 既にあるものは「already exist」で怒られるので、何回でも叩いていい安心感がある
  • あとGUIを触らせないのもよかった

vs ECS

Go - AWS SSM Parameter Storeのデータを復号化とmockテストの書き方

SSMとは?

インフラ運用を便利にするサービス

SSM ParameterStoreとは?

パスワードなど値を管理

SecureStringsは裏でKMSを使って文字列を暗号化して保持も出来るよ!

(料金かかるけど、そんなたいしたことない。前提知識として持っててね! 料金 - AWS Key Management Service (KMS)| AWS

DBのパスワードを保管して呼び出す、みたいなので使えそう





実際にやってみよう

1. ParameterStoreの登録

SystemManager->Parameter Store->パラメーターの作成

安全な文字列にチェックをいれて"hogehoge"と入れてみます

f:id:sion_cojp:20180115210244p:plain




2. aws-cliで試してみる

### --with-decryptionを外すと暗号化された文字が出力されます
$ aws ssm get-parameters --region ap-northeast-1 --name sion_test --with-decryption
{
    "Parameters": [
        {
            "Name": "sion_test",
            "Type": "SecureString",
            "Value": "hogehoge",
            "Version": 1
        }
    ],
    "InvalidParameters": []
}




3. Goで動かす

あとでテストでSSM mockを使うので、ssmiface.SSMAPIを使います

package main

import (
    "fmt"
    "os"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ssm"
    "github.com/aws/aws-sdk-go/service/ssm/ssmiface"
)

func main() {
    d := newssmDecrypter()
    s, err := d.decrypt("sion_test")
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    fmt.Println(s)
}

// ssmDecrypter stores the AWS Session used for SSM decrypter.
type ssmDecrypter struct {
    sess *session.Session
    svc  ssmiface.SSMAPI
}

// newssmDecrypter returns a new ssmDecrypter.
func newssmDecrypter() *ssmDecrypter {
    sess := session.New()
    svc := ssm.New(sess)
    return &ssmDecrypter{sess, svc}
}

// decrypt decrypts string.
func (d *ssmDecrypter) decrypt(encrypted string) (string, error) {
    params := &ssm.GetParameterInput{
        Name:           aws.String(encrypted),
        WithDecryption: aws.Bool(true),
    }
    resp, err := d.svc.GetParameter(params)
    if err != nil {
        return "", err
    }
    return *resp.Parameter.Value, nil
}

// $ export AWS_REGION=ap-northeast-1 && export AWS_PROFILE=xxxxxx && go run main.go
// hogehoge




4. テストを書く

SSMのmockを使います

aws-sdk-go/interface.go at master · aws/aws-sdk-go · GitHub

こちらをみればわかると思いますが、色々とinterfaceが用意されてる + サンプルコードも書いてます

今回はGetParameterメソッドをmock用に作ります("decrypted"の文字列を返すようにする)

package main

import (
    "reflect"
    "testing"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/service/ssm"
    "github.com/aws/aws-sdk-go/service/ssm/ssmiface"
)

// mockSSMClient stores SSM interface for mock
type mockSSMClient struct {
    ssmiface.SSMAPI
}

// newTestssmDecrypter returns a new ssmDecrypter for mock.
func newTestssmDecrypter(mock ssmiface.SSMAPI) *ssmDecrypter {
    return &ssmDecrypter{
        svc: mock,
    }
}

// GetParameter returns "decrypted" that is Decrypted SSM parameter.
func (m *mockSSMClient) GetParameter(i *ssm.GetParameterInput) (*ssm.GetParameterOutput, error) {
    parameter := &ssm.Parameter{
        Value: aws.String("decrypted"),
    }

    return &ssm.GetParameterOutput{
        Parameter: parameter,
    }, nil
}

func TestDecrypt(t *testing.T) {
    mock := &mockSSMClient{}
    d := newTestssmDecrypter(mock)

    cases := []struct {
        value    string
        expected interface{}
    }{
        // string decrypt
        {
            "a",
            "decrypted",
        },
    }
    for _, c := range cases {
        s, err := d.decrypt(c.value)
        if err != nil {
            t.Fatalf("failed decrypt: %s", err)
        }

        if !reflect.DeepEqual(c.expected, s) {
            t.Errorf("want %s got %s", c.expected, s)
        }
    }
}
$ go test -v .
s-koyama-m:hoho s-koyama$ go test -v .
=== RUN   TestDecrypt
--- PASS: TestDecrypt (0.00s)
PASS
ok      my/ssm  0.017s

社内で技術力評価会というものをやった

技術力評価会ってなに?

VoyageGroupで評価制度の一環。

半期に1回、「どんくらい技術的にドヤれることをしたの?」というの評価します。



おまえはどんなドヤ顔してきたの?

SREとして、PHP+CentOS6+apacheで動いてたとあるシステムを、Go+CentOS7+nginxに移行した話をしました。

それについては VOYAGE GROUP エンジニアブログ でいつか書く予定なので、乞うご期待。



おおまかな流れ

  1. 評価する人、される人が入ったslackチャンネルを公開で作る
  2. 評価する日のをfix
  3. ドヤ顔する内容をgithubにあげる
  4. 素振り(任意)
  5. 評価実施(1時間30分くらい)
  6. フィードバック(その内容もgithubに上がります)



素振りis何?

評価はお賃金に反映される。ぶっつけ本番する前に軽く指摘欲しい!

って人がやったりします。やっててよかった。。



githubにあげた内容ってどんなの?

例となるテンプレートがありましたが、私はこんな感じで自由に書きました。

概要
評価してほしいポイント
背景
リリース後に計測する指標
関連チケット
プロジェクトの進め方
PHP->Goに関すること
apache->nginxに関すること
CentOS6->Centos7に関すること
運用について
本番投入までの流れ
サーバ入れ替えについて
何か障害が発生したか?
総括
ref: PHP vs Go



評価実施

1. 何も知らない人に、シンプルで分かりやすく説明することが出来る大切さ

評価する人はエンジニアとはいえ、私の場合は別のグループ会社さんでした。

なので、何も知らない前提で説明をしないといけない というのがとても大変でしたね。

システムの説明はもちろんのこと、自身の業界では当然の如く使ってるワードなどの説明など。。

シンプルに分かりやすく説明することの難しさがあると思います。苦手な人多そう

2. 自身を振り返る良い機会

システムを深堀していくと意外と知らない点も実はあったり。。評価前に気づく点も多く、理解が深まって良い時間でした。

3. ロジカルシンキングが身につく

ロジカルな点をすごくチェックされるので、教育的観点としてとても良いですね。

転職活動の面接みたいな感じ。

人はいつか転職するものだと私は思ってるので、その練習する場が提供されてるっての大事だと思います。

「あ、ここからきた人優秀な人多いよね」って他社に思わせるだけでも凄いこと。

4. フィードバックがありがたい

「こういう風にできたんじゃない?」「こうやってたことありますよ」

ってのが聞けて、「おお、そんなアプローチが!」と気づくことが多かったです。



評価後

評価する内容も、フィードバックもgithubに上がってます。

もちろん全員分みれます。

抵抗がある人はいると思いますが、公平性が担保されてて良いシステムだなぁと私は思います。

他の人の評価見れて私は楽しいです。



個人的に思った点

1. 評価者の負担が大きそう

評価者は事前にある程度見る必要があります。

コミットログだったりPRだったり、issueだったり。すごく時間持ってかれそう。萎えそう。

2. だからこそ評価者の成長の場にもしたい

ドヤ顔を聞けて評価者も成長は出来ると思います。

だけどドヤ顔以外にも、悩んだり困ったりしたことは作業中あるはず。

そいうネタをぶっこんでいけたら、評価者もさらに成長の場になると思いました。

なので評価されない部分だけども、PHP vs Go(移行前と移行後のモニタリング比較と、自分なりの考察)などを入れてみました。

意外と好評っぽかった?ので次回からも、そういうネタをぶっこんでいけたらと思います。

3. 新しく入った人は深堀されすぎると結構辛い?

深堀されすぎると分からない事も多々ありました。(今回は特にいろんなシステムが絡んでたので)

そのときは素直に「分からない」と答えましたが、お賃金が懸かってるので若干心辛かったり。

4. 縛りがある部署はどうなるんだろう?

昔所属してた会社で、「予算がないから新しいことはさせれない。今ある機能で乗り切る」

といった時期がありました。

そいう部署だったら、良いドヤりもできにくそうだなぁと思ったり。



結局どうだったの?

エンジニアとして評価されてるのが凄く嬉しく、やってよかったと思うし、他の会社でもぜひやって欲しいと思います。

そういえば、他の方も書いてました。 初めての技術力評価会を終えたので感想を書いた - VOYAGE GROUP techlog

どうやらajito.fmってのもあるらしく。お偉い方々の意見が聴けるみたいですよ!

ajito.fm

VOYAGE GROUPのfluctに入社しました

お前 is 誰

前職の話

eurekaでpairsというアプリのインフラやってました。

オンプレばかりやってきたので、100% AWS楽しかったです。

1年も経たずに辞めてしまったので、結構突っ込まれます。

辞めた理由はプログラム寄りに身を置きたかったのと、会社へのネガティブ要素が多かったです。

ただ会社は成長するもので。今は私の言ってた意見が徐々に反映されてるみたいです。

ネガティブ要素を書いてたら、結構エグかったので、具体的に聞きたい人はtwitterで気軽に飲みにでも誘ってください。



そして転職

行く当てなく退職届を先に出し、会社の許可を得てtwitterで募集してみました。




そして、id:katzchangさんに誘われて、VOYAGE GROUPfluctでSREとして働くことになりました。

他にも魅力的な会社からお誘い頂き光栄で、嬉しい反面とても悩ましかったです。

VOYAGEは面接段階でソースコードを見せて頂けたりしたので、そこが若干ポイントになったのかなぁと思います。



現職の話

3月から働いてます。

入社時には色んなところにGetWildの文字が書いてたり、曲が流れたりして、たっぷりGetWild歓迎されて最高でした!

今の仕事はAWS-オンプレでインフラやりつつ、とあるシステムをPHP->Goに書き直して、入れ替えるプロジェクトをやってます。

やりたいことを意思表示すればやらせてくれるので、ビビらず責任持って、技術力でサービスに貢献していきたいです。

逆に意思表示できない人は腐ってくんじゃないか?という課題感はあるので、なんとか改善していきたいなぁと思いつつ。


あと大企業なのに意見が通りやすいのもびっくり。(私は通りにくい印象ありました)

「キーボードとモニタ(2枚)は会社として用意して欲しい!」と意見を言ったらその週には購入してもらえるようになりました。爆速。

今の段階ではとても働きやすいので、このまま維持していきたいです。


皆様、どこかで勉強会でお会いしたときは、何卒宜しくお願いします!