ニクニクドットミー

カッコいいおっさんを目指すエンジニアの厳かなブログ

【AWS】CodeDeployでS3をRevision Locationにしてデプロイしてみた

Codedeploy つい先日CodeDeployを試してみました。【AWS】5分で分かるAWS CodeDeploy その時はGithubと連携してデプロイを試したのですが、今回はS3で試してみたいと思います。

前回の記事で用意したApplicationを使いまわします。

S3バケットの作成

肝心のS3バケットを作成します。バケットのリージョンに注意しましょう。 CodeDeployはヴァージニア、オレゴンにしか対応してないので、それ以外のリージョンに作ってしまうとデプロイがDownloadBundleでコケます。 s3

aws deploy pushでリビジョンのアップロード

リビジョンとはデプロイするソースコードを指します。 リビジョンのアップロードにawscliを使ってみます。 ちなみにawscliのversion。2015/04/22時点の最新。

aws-cli/1.7.23 Python/2.7.5 Darwin/13.4.0

awscliにdeployとかあったんですね。知らなかった^^; ドキュメントはこちら。 http://docs.aws.amazon.com/cli/latest/reference/deploy/push.html

aws deploy push --application-name WordPress_App --description "This is my deployment" --ignore-hidden-files --s3-location s3://CodeDeployDemoBucket/WordPressApp.zip --source /tmp/MyLocalDeploymentFolder/

sourceで指定したディレクトリをzip圧縮して、それをs3-locationで指定したS3バケットにアップロードします。 今回は前回作ったApplicationを使い回してますが、aws deployコマンドでApplication作ることもできます。

サンプルを例にdeploy push してみます。前回のApplicationを使うので、test_v1という前回作ったものを指定してみます。


aws deploy push --region us-west-2 --application-name test_v1 --s3-location s3://s3-deploy/test_v1.zip --source ./CodeDeployLab/

push成功すると、こんな感じ


To deploy with this revision, run:
aws deploy create-deployment --application-name test_v1 --s3-location bucket=s3-deploy,key=test_v1.zip,bundleType=zip,eTag="66f02fcb38c7e4987e7bb0ee246c6b50" --deployment-group-name  --deployment-config-name <deployment-config-name> --description <description>

eTagというのがつきました。

Etagはオブジェクトのハッシュです。Etagはオブジェクトのコンテンツの同一性を識別するものなので、メタデータの変更はEtagには反映されません。 Etagはオブジェクトが作成されたときに決まります。 PUTまたはPOSTオペレーションにより作成されたオブジェクトの場合、Etagはクォート付の32桁の16進数となり、これはオブジェクトデータのmd5ダイジェストを表しています。

オブジェクトのコンテンツの同一性を識別するものみたいです。 s3_1

CodeDeployでデプロイする

Create New DeploymentでRevision TypeをS3を選択します。 s3_2

これでデプロイ! s3_3 無事成功ですね。

失敗もしたのですが、その時はS3のバケットをTokyoリージョンで作ってしまったが原因でした。

まとめ

自動化必須! 次はLambdaと組み合わせて自動化してみよう!

参考

LambdaでCodeDeployの自動デプロイ機能を実装する

【AWS】5分で分かるAWS CodeDeploy

Codedeploy

久々にAWSのサービスを触ってみました。というのもデプロイの仕組みをカイゼンしたいなーと考えていて、社内でもどうしよか?と話をしていました。 現状はfabricというPython製のツールを使っているのですが、fabricを動かす為に環境を整えてあげる必要があったり、依存しているライブラリのバグが影響して、デプロイができない時があったりと、深刻な状況です。 AWS CodeDeployであればマネジメントコンソールから実行もできるので、環境構築の手間が省けるので、良いのではと思い軽く触ってみました。 触ってみた感想と、CodeDeployを簡単に説明したいと思います。 ※5分は釣りです^^;

AWS CodeDeployとは

AWS CodeDeployはEC2,AutoScaling,オンプレミスに特化したデプロイサービスです。 たしか2014年11月ぐらいに登場しました。ただ、サービスを提供しているリージョンがオレゴン、ヴァージニアのみ(2015/04/19時点)ですので、 東京リージョンはまだ使えないです。残念。はやく対応してほしいです。

リポジトリとして、S3、Githubが対応しています。今後はAWS CodeCommitと連携もするようです。 うちの会社ではリポジトリをStashで管理している為、対応していません。今後に期待!?

CodeDeploy用語

codedeploy-agent デプロイ対象となるサーバには必須になる。 S3からコピーしてインストールする必要がある。


$ sudo yum update
$ sudo yum install aws-cli
$ cd /home/ec2-user
$ aws s3 cp s3://aws-codedeploy-us-east-1/latest/install . --region us-east-1
$ chmod +x ./install
$ sudo ./install auto

appspec.yml アプリケーションのソースコードをどのディレクトリに配置するか、どのような権限で付与するかを決めるファイル。 またCodeDeployのライフサイクルに応じた処理をどうするかとかも記載する。必須

Application Name アプリケーション名。そのまんまだけど、実際につけるとするとプロジェクト名_環境名って感じになるのかな? hoge_productionとか。

Deployment Group Name デプロイ対象のグループ。グループの選び方はEC2のタグのKey,Value、AutoScalingGroup名、オンプレミス。 codedeploy codedeploy

Deployment Configuration デプロイ方法。デフォルトでは、

  1. CodeDeployDefault.AllAtOnce
    一度にすべてのインスタンスにデプロイする。最低1つのインスタンスにデプロイが成功した場合、全体のデプロイが成功したものとする。すべてのインスタンスへのデプロイが失敗した場合、全体のデプロイが失敗したものとする。
  2. CodeDeployDefault.OneAtTime
    インスタンス1つずつにデプロイする。全てのインスタンスにデプロイが成功した場合、全体のデプロイが成功したものとする。デプロイが失敗した時点で失敗と扱われるが、既にデプロイが成功したインスタンスはそのまま。
  3. CodeDeployDefault.HalfAtTime
    一度に総インスタンス数の半分までデプロイする。総インスタンス数の半分までデプロイが成功した場合、全体のデプロイが成功したものとする。全体のデプロイが失敗した場合でも、既にデプロイが成功したインスタンスはそのまま。

codedeploy_3

Service Role CodeDeployがEC2インスタンスにアクセスするロール。 codedeploy_4

デプロイの流れ

他のブログを参考にデプロイするリポジトリ作りました。 1.Applicationの作成 実は上の画像がほぼApplicationの設定の流れになります。ここではアプリの名前とデプロイ対象のグループを作る感じ。その枠を決めたイメージです。

2.デプロイするリビジョンの選択 1でCreate Applicationしたら遷移する画面。 deploy_settings 右のオレンジ枠がデプロイされたリビジョンの履歴が記載される所。ここから前のリビジョンをデプロイしたりする。つまりロールバックに使う感じ。 左の赤枠が、Deploy Group。ここからデプロイするソースを選択する。

deploy_settings_1.png

S3,Githubを選択する画面。 Create New Deployment

実はデプロイを実行する度にこの画面の入力はしないといけない。 リポジトリ名、コミットIDをいちいち入力するのがすごく面倒くさい。 自動化必須

Deploy結果とNGパターン

デプロイに成功するとこうなります。 deploy_success_1 デプロイ対象のインスタンスは2台あったので成功してますね。

次にNGパターン deploy_success_2 Deployment ConfigurationをCodeDeployDefault.OneAtTimeに設定していたので、一台ずつデプロイしています。 まず一台にデプロイしてFailedとなったので、残りのもう一台にはSkippedとなってデプロイ実行されてないです。 View All Instancesをクリック。

deploy_success_3 実際にどこで失敗したのかは赤枠を見ると分かります。 BeforeInstallで失敗したようです。 次に青枠のView Eventsを見てみましょう。

deploy_success_4 View Logsをクリック。

deploy_success_5 エラーメッセージが出てますね。よくわかりませんが。。。 この時どこに問題があったかというとappspec.ymlです。 appspec修正。 appspecのosの書き方が違ったので、修正

ほんとしょうもないミスなのですが、先ほどのメッセージからでは分かりにくいですよね。

まとめ

かなり雑になってしまいましたが、触ってみた感想を。

  • 自動化しないとツライ。コミットIDとかいちいち入力するのツライ
  • ロールバックするときにどのリビジョンがどういう修正だったかわからない。UIにタグが付けれて、デプロイする時に追加できると良いと思う。
  • codedeploy-agentの死活監視必須

参考

GitHubリポジトリと連携してAWS CodeDeployを使う(準備編) GitHubリポジトリと連携してAWS CodeDeployを使う(デプロイ編) AWS CodeDeploy を使って Rails アプリケーションをデプロイしてみた [新サービス] AWS CodeDeployを触ってみた #reinvent

kamakura.go#2に参加してきた!

28日に鎌倉で行われたGoの勉強会 kamakura.go #2に参加してきました。

第一回目の開催には所用があった為、参加できず、二回目開催してほしいなーとtwitterでつぶやいていたら、二回目開催されるとのことだったので、即申し込みしました。

ちなみにiichiさんで開催されているのですが、iichiさんのslackのGoのチャンネルに参加させて頂いてます。

勉強会としてはもくもく会で、最後に成果発表がありました。

成果発表時にやったこととkamakura.goの感想をslideにしたので、張っておきます。

会場はiichiさんで、場所は鎌倉にあります。小町通にあるので、休日は人がすごいです。

僕はよく鎌倉には行くので、人ごみは想定内でしたが、一緒に行った同僚の方は初鎌倉で面食らってました(笑)

とても天気がよくて鎌倉を散策するにはもってこいな日でした。

勉強会終了後の懇親会で鎌倉の焼き鳥屋に行ったのですが、そこの大将がすごく人に絡む人で、同僚が気に入られてしまい、ずっとその話で盛り上がりました。(おつかれさまでした^^;)

夜の鎌倉は初めてで、だいぶ人も減り、小町通もシャッターがすぐおりてました。昼間とはガラっと雰囲気変わるので驚きでした。

kamakura.go #3あれば参加します!

鎌倉で気になるお店も出来ました。尾崎、ブルールーム。これは行ってみたい!

やっぱ鎌倉いいとこだ。

【資料公開】社内LTで「プログラミング学習の3つのポイント」を話しました。

社内でLTを月に一回ぐらいのペースで開催していて、久々に登壇しました。

久々に発表用資料を作りましたが、頭の中を整理するのにちょうどいいですね。あとLTで意識しているのは「緊張感を楽しむ」ということ。 これは中学時代の部活(実はバレー部のキャプテン)で先生に教えてもらった言葉ですが、いまも意識しています。

大した話ではないですが、資料公開しておきます。 (今年は発表に力入れているので)

1.SIMPLE シンプルに継続する。

継続は力なりという言葉の通り、続けるとすこしずつ成長はする。 運動もそうで、ジムに週6日くらい通っている奥さんの方が、だんぜん動ける。。。頑張ろう。

2.EASY&SMALL 小さく簡単に作る。

少しでも動くとやっぱ楽しい。いきなりでかいものは作れないので、少しずつ進めていく。 そして、簡単なものでいいから作る。

3.READ コードを読む。

コード読むのはメリットだらけ。次第に読めてくると楽しいし、アイディアも湧く。 尊敬・憧れのエンジニアのコードだと尚更。

憧れのエンジニアはメルカリの久保さん。これはdotsSummit2015の発表を見て、カッコイイと思いました。 発表も冷静沈着な印象で、僕とは違う感じ(笑) slackboardの話で、イラっとしてGoでささっと書いたという話が印象的で、インフラでしっかりコードが書ける久保さんのようになりたいと思いました。 なので、slackboardのコードはgithubで読んでます。

ということで、pocket-for-Golangを頑張るぞ。

Goでtoml.DecodeFileしたときにハマったことメモ

182b65b9 539c 4d24 9b1f ee4a1a8756f1 TOMLという設定ファイルの為のミニ言語があり、それをGoで試してみた所、うまく読み込まれずにハマってしまったので、メモ。

config_test.go


package main

import (
    "github.com/BurntSushi/toml"
    "testing"
    "fmt"
)

type ConfToml struct {
    Keys SectionKeys `toml:"keys"`
}

type SectionKeys struct {
    Consumer_key string `toml:"consumer_key"`
    access_token string `toml:"access_token"`
}

// config の read
func readSettingsConfig(path string, config *ConfToml) {
    _, err := toml.DecodeFile(path, config)
    if err != nil {
        panic(err)
    }
}

func Test_readSettingsConfg(t *testing.T) {
    var conftoml ConfToml

    _, err := toml.DecodeFile("config.toml", &conftoml) 
    if err != nil {
        panic(err)
    }
    
    fmt.Println(conftoml.Keys)

    // Printlnする為に、あえてerrorにしている。
    if conftoml.Keys.Consumer_key != "aab" {
        t.Error("Not Match")
    }
    if conftoml.Keys.Consumer_key != "bbb" {
        t.Error("Not Match")
    }

}

config.toml


[keys]
consumer_key = "aaa"
access_token = "bbb"

実行結果


{aaa }
--- FAIL: Test_readSettingsConfg (0.00s)
        config_test.go:38: Not Match
        config_test.go:41: Not Match
FAIL
FAIL    command-line-arguments  0.005s

この太字にしたところがポイントで、これはtomlファイルを読み込んだ構造体をPrintlnしているのですが、aaaという値だけ格納されている状態です。 本来ならば、{aaa bbb}となるはずです。


type SectionKeys struct {
    Consumer_key string `toml:"consumer_key"`
    access_token string `toml:"access_token"`
}

このSectionKesyという構造体のフィールド名が小文字と大文字で違っているのが原因です。 どうやらDecodeFileはフィールド名が小文字だと値が設定されないようです。 ※Access_tokenと大文字で設定すると正しく値は設定されました。

恐らくですが、github.com/BurntSushi/tomlパッケージ外の構造体へのアクセス権限がない(エクスポートできない)のが原因かと思っています。 値が設定されず、やだな〜やだな〜こわいなーこわいな〜とハマっておりました。

謝った認識かもしれませんので、ご指導ご鞭撻のほどよろしくお願いします。

参考サイト

【個人メモ】設定ファイルフォーマットにはTOMLがいいのかも Go言語での構造体実装パターン

【AWS】ElastiCacheRedisをMulti-AZ構成にするとAOFの設定ができないっぽい?

Redis 今日はElastiCacheRedisを触ることが多かったので、本日二回目のElastiCacheのメモ。

ElastiCacheRedisがMulti-AZ対応したので、Multi-AZ構成でクラスタを作成していたのですが、 なんとParameterGroupでappendonly yesにしたgroupを設定するとエラーとなってしまうのです!ドン!(多分だけど。。。)


Cannot have redis persistence(appendonly) and Multi-AZ both on

ちなみにこんなエラー。

どうやら同じエラーになった方がいたようで、こちらの記事を参考にさせて頂きました。 [AWS]マルチAZなElastiCache Redisの永続性についてメモ

実は今年の一月ぐらいに他のインスタンスで同じMulti-AZ構成にしたクラスタがあったのですが、そちらはなんとAOFの設定が出来ているのです!(さらに深まる謎)

結局のところ

埒が明かないので、AOFの設定無しのParameterGroupを設定したところ、クラスタの作成が問題なく出来ました。 参考にさせて頂いた記事にありましたが、Multi-AZではインスタンスが死んだら、そのインスタンスは破棄するので、AOFを残す意味がないから?という仮説を立てられておりました。 自分もその意見には納得です。

だれかご存知の方いますかーーーーー?

追記 2015/02/18 この件についてAWSに問い合わせしたところ早速回答がきました! Multi-AZ構成でAOF設定は出来ない仕様 さらに英語のみですが、ドキュメントに記載されているとのこと。  - Best Practices for Implementing Amazon ElastiCache / Mitigating Out-of-Disk-Space Issues When Using AOF  http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/BestPractices.html#BestPractices.FaultTolerance

Enabling Redis Multi-AZ as a Better Approach to Fault Tolerance  If you are enabling AOF to protect against data loss, consider using a replication group with Multi-AZ enabled instead of AOF. In any Redis replication group, if a replica fails, it is automatically replaced and synchronized with the primary cluster. If Multi-AZ is enabled on a Redis replication group and the primary fails, it fails over to a read replica. This functionality is much faster than rebuilding the primary from an AOF file. For maximum fault tolerance, even against a hardware fault in an underlying physical server, launch your primary and replica clusters in different Availability Zones. Because there is no need for AOF in this scenario, you do not risk running out of disk space. AOF ですがローカルディスクに書き込みを行う都合上、物理的な障害には対応できません。また、ディスクに書き込みを行う都合上、更新が非常に多いとローカルディスクを使い切り書き込みができなくなる事例も報告されております。この影響を回避するため、ベストプラクティスとしては AOF ではなく Multi-AZ 構成によって耐障害性を考慮頂くことをお勧めしております。 Multi-AZ 構成により十分な耐障害性が確保できることから、ElastiCache の仕様としては AOF との併用ができないような仕様となっております。

やはりMulti-AZになったことでAOFファイルつくる必要がないという判断のようです。

早急に連絡くれたサポートに感謝!

【AWS】S3のrdbファイルからElastiCache Redisを作成する時の些細な注意点

Redis S3にアップしたrdbファイルからElastiCacheを作成することってよくありますよね。ありますよね。

僕は今回初めて対応しましたが、たった些細な設定が漏れていた為、大ハマりしました。お世話になりました。

ドキュメント

バックアップと復元の管理 (Redis)

RDB ファイルへの読み込みアクセスを ElastiCache に許可 次のステップでは、Amazon S3 にコピーしておいたスナップショットファイルへの読み込みアクセスを ElastiCache に許可します。 Amazon S3 にコピーしておいたスナップショットへの読み込みアクセスを ElastiCache に許可するには AWS Management Console にサインインして Amazon S3 コンソールを開きます(https://console.aws.amazon.com/s3)。 [All Buckets] をクリックし、RDB ファイルを含む Amazon S3 バケットの名前をクリックします。 RDB ファイルを含むフォルダの名前をクリックします。 RDB ファイルの名前をクリックし、[Actions] ドロップダウンメニューをクリックして [Properties] を選択します。 [Permissions] をクリックして [Add more permissions] をクリックします。 [Grantee] ボックスに、E メールアドレスaws-scs-s3-readonly@amazon.comを入力します。 [Open/Download] をクリックし、[Save] をクリックします。 Note aws-scs-s3-readonly@amazon.com アカウントは、Amazon S3 から Redis スナップショットデータをアップロードするお客様だけが使用します。

aws-scs-s3-readonly@amazon.comを許可

はい。これを許可してなかったので、No permission to access S3ってエラーになってましたとさ。

ドキュメント大事。

(ってかこれハマる人結構いるんじゃね)