[小ネタ]ソースバンドルでElastic Beanstalkにハマった話

春ですね。春と言えば桜・花粉症……新学期。新しい事が始まる季節です。 秋葉原の桜も咲き、神田川からはのどかに往来する遊覧船が拝め、Developers.IO Cafeではタピオカドリンクの販売が始まっておりました!

▲実は元号以外も天皇の追号に出来るらしいですよ。まだワンチャンありますね

タピオカの仕入れ分のみの販売となっているようですが、映えるし何よりも美味しいです!ちょっと甘いものが欲しくなるおやつ時にピッタリな一杯です。後は何よりも映える

▲社内Slackによく可愛いカップの絵をあげるのですが、何でやラズパイ関係ないやろ(いちごミルクタピオカです)

こんにちは。一番好きなDevelopers.IO Cafeのドリンクはホットヘーゼルナッツラテ(L/シロップ2倍)のAWS事業本部のしろたです。花粉で辛いこの時期のたまの出社において、楽しみがカフェ通いになっております。
さて、新しく出来たカフェに通うのも楽しいですが、 新しい技術にも触れていきたい心持ちです。この活性化されている感じがいかにも春だなぁと感じてやまない今日この頃。 そんな訳で、今回は「初めてBeanstalkでアプリケーションをデプロイしてみようとしたらちょいちょいハマった話」をしつつ、ハマりポイントについて色々と触れていければと思います。

春だしElastic Beanstalkを始めてみた

「アプリケーション、作った事がないから挑戦しよう!」 「作ってみたいけど、まず環境の整備がさっぱり分からん……」

アプリケーションの為の環境作りでめげて、本題がポシャってしまう事はとても残念な事だと思います。
でも、そんな人の為にあるのがElastic Beanstalk
2019年版のAWS全サービスまとめのエントリから、その概要を抜粋してきました。

 

AWS Elastic Beanstalk アプリケーションのデプロイ・管理サービスで、AWSのPaaSのひとつ。EB単体のものではなく、実態はEC2やS3、RDSやELBなどをプロビジョニングするサービス。

との事で、「環境の整備がさっぱり分からん」をAWSがいい感じに手助けしてくれるサービスとなっております。
私はゴリッゴリにインフラしか経験(1年程度)が無く(プログラムを書いた事はありますが本当にシンプルなPythonや大学でC言語の講義を受けたレベル)、EC2やRDSで3層構造は構築できるもののそこ止まりです。TomcatやDockerをよしなに設定してくれと言われると検索の構えを取るレベル。
「アプリでも作ってみっか」と思いたって三日、コンテナ周りで止まっていると思います。言いたかっただけですすいません

止まらずにサクッと成功体験を築きたい!という事で、早速Elastic Beanstalkを使用していきます。

▲たったこれだけの選択でDockerが動かせるなんて、Docker入門本を積読中の自分からすると驚きです

私の中では一番経験が無く悩ましかった部分も上記の通り何も問題なく設定出来、サクッと起動出来ました。便利!一番大事な最初の一歩を踏み出せたので、この勢いで次に進んで行こうと思います。

ちょっとだけ先に踏み出してみたら、事故った

▲Sample Applicationをダウンロードしてきてちょっと弄ってみようと思います

上記のリンクから飛べるAWS公式ページで、各プラットフォームのアプリケーションがダウンロード出来ます。今回はSingle Container Dockerを使用しているので、対応するzipファイルを探してダウンロードしました。
ちょっと次のステップへ、という事でダウンロードしたディレクトリに「.ebextensions」を追加してみます。
.ebextensionsとは、Elastic Beanstalkでの環境構築時に環境をカスタマイズする設定ファイルを配置するディレクトリです。このディレクトリ内に、「.config」拡張子でYAMLもしくはJSON形式のドキュメントを配置してデプロイする事で使用する事が可能です。
と言うわけで簡単なconfigファイルを書き、.ebextensionに配置して環境のカスタマイズに挑戦してみようと思います。

▲お前はいつもそうだ。

サンプルアプリケーションに設定ファイルを追加してみただけなのに

実際に私が行ったことを纏めてみます。「原因が何となく分かった!」と言う方も次の見出しまでご静聴頂けますと幸いです。

  1. .ebextensionディレクトリを作成
    mkdir ~/sampleapp/.ebextension
  2. .configファイルを作成 .configファイルの中身は、Deep Securityの検証を行なっていた事もあって以下のブログとGitHubを参考にして作成しました。

    vi ~/sampleapp/.ebextension/test.config
    
    

    AWS Elastic Beanstalk Docker 環境へDeep Security Agentをインストールする GitHub

  3.  sampleappディレクトリをMacのFinderからzipする
  4. zipファイルをデプロイする、エラーが出る

追加の仕方が悪かった?エラーメッセージを読み解いていく

私は不肖ながら原因が分からなかったので、大人しくエラーメッセージを読んでみることにしました。

エラー1:記憶に無い「__MACOSXディレクトリ」

 

The configuration file __MACOSX/hogehoge-v1/.ebextensions/.piyopiyo.config in application version hogehoge-v2 contains invalid YAML or JSON. YAML exception: unacceptable character '' (0x0) special characters are not allowed in "", position 0, JSON exception: Unexpected character () at position 0.. Update the configuration file.

configファイルですか?いいえ、それよりも気になるものがあります。
誰やねん __MACOSXて。
知らない奴に邪魔されている、そんな怒りを鎮めるべく__MAXOSXディレクトリについて調べました。

__MACOSXは、主にリソースフォークとメタデータを格納しているMacOS独自のディレクトリです。
より噛み砕いて説明すると、「MacOS間では必要となる、実データとは別の情報を収めたディレクトリ」と言ったところでしょうか。
つまり、今回起こってしまった事を纏めるとMacOS以外では必要のないファイルがデプロイ可能であるJSONでもYAMLでも無い形式を取っていたせいでエラーが発生したとなります。
これらの情報を必要とする、MacOS純正アプリケーションであるFinderでzipファイルを生成した事によるエラーでした。3.の手順ですね。
さて、これで邪魔者は分かったので邪魔者を省いて圧縮します。 終わった!

$ zip -d ~/Documents/docker-singlecontainer-v4.zip __MACOSX/\*

▲Elastic Beanstalkは私を愛さない。またしても。

エラー2:"caused by: Dockerfile and Dockerrun.aws.json are both missing, abort deployment"?

 

ERROR [3656] : Command execution failed: Activity failed. (ElasticBeanstalk::ActivityFatalError) caused by: Dockerfile and Dockerrun.aws.json are both missing, abort deployment (ElasticBeanstalk::ExternalInvocationError) caused by: Dockerfile and Dockerrun.aws.json are both missing, abort deployment (Executor::NonZeroExitStatus)

エラーの種類は変わったようなので、次の問題に立ち向かいます。
DockerfileとDockerrun.aws.jsonが無い!と言われていますがそんな事は無いはずなのです。
だって、Docker用のサンプルアプリケーションに元から入っていた二つだから。
階層も弄っていないし。
実はあまりFinder上でzipファイルを生成する機会がなかった私は全く気付けず、随分解決までに時間を要しました。
そう、ディレクトリを選択してzipしているのでディレクトリの入れ子が出来てしまったのです。
そりゃ階層もズレますね。これを解決するにはディレクトリの下の階層を全て選択してからzipすれば良いと思ったのですが、ここでFinderの壁にぶつかりました。
隠しファイルがデフォルトで表示されないのです。
デフォルトで表示されるようにオプションをつけてFinderをターミナルから起動する手段があるのですが、もうそこまでしてFinderで圧縮する必要はありません。大人しくzipコマンドで圧縮します。

$ zip ../hogehoge-v2.zip -r  
  adding: Dockerfile (deflated 29%)  
  adding: Dockerrun.aws.json (deflated 11%)  
  adding: application.py (deflated 58%)  
  adding: cron.yaml (deflated 24%)  
  adding: .ebextensions/ (stored 0%)  
  adding: .ebextensions/piyopiyo.config (deflated 42%)

この後、configファイルに関するエラーメッセージに変わったのでようやく私は本題に取り組む事が出来ました。戦いは続く!(補足:4/12現在、解決しております)

必要なものだけをzipするならCLI!

いかがでしたでしょうか?言ってみたかった
Finderで圧縮すれば(余計なファイルが作られるせいで)多すぎて、Finderで圧縮すれば(隠しファイルが入らず)不足する。zipは(Finderだと)とかくに難しい。
N目S石の頃にMacがあったらきっとこう言っていた事でしょう。
私は元々CLIには抵抗が無い(寧ろかっこ良く感じていて、ターミナルをHomebrewにしてはニヤニヤしていた時期がありました)為、初めからzipコマンドでさらりとzipすれば良かったわーと感じましたがついつい直感的にGUIを触ってどうにかする事もしばしばあるかと思います。ちょっとしたファイルをzipしてメールで送信する時には「便利だなFinder」と思って使っていました。
お陰で全く気付くことの出来なかったMacOSのファイルシステムについて触れる事が出来ました。後今度からはスタートラインに立ってBeanstalkを使う事が出来るようになれそうです。

折角のBeanstalk、関係の無いところでコケて辛いと思う人がこの記事で一人(私含む)でも減れば良いなと願っております。