AWS s3cmd を使ってS3から複数EC2インスタンスへ簡単デプロイ環境を作る


基本的に複数台の EC2 インスタンスある場合にファイルをデプロイする時は、手動なら SCP で1台ずつやるのだろうけど、楽をするなら Chef を使って環境を作るとかになると思う。だけど、オートスケーリングをさせている場合、起動しているインスタンスは常に変わってしまう懸念があるので、実際そこまで作りこむのは大変。

そこで、s3cmd sync を使うと簡単デプロイ環境ができると思って触ってみた。
インストールや基本的な動かし方は下記参考URLを見ながら、それ以外の情報も得られたので載せておく。

参考URL

  • http://blog.serverworks.co.jp/tech/2012/06/27/nginx-01/
  • http://memocra.blogspot.jp/2013/02/s3s3cmd-syncinotifys3cmd-sync.html
  • http://understeer.hatenablog.com/entry/2012/07/23/124402
  • http://recipe.kc-cloud.jp/archives/1059
  • http://blog.serverworks.co.jp/tech/2013/04/23/ec-cube-on-aws-s3/
  • http://understeer.hatenablog.com/entry/2012/07/23/124402

インストール

$ sudo yum -y --enablerepo epel install s3cmd

AWS アカウントの Access Key と Secret Key の情報を設定する。HTTPSを使うか、HTTP Proxyを使うかとかあるが適宜入力する。

$ s3cmd --configure

Enter new values or accept defaults in brackets with Enter.
Refer to user manual for detailed description of all options.

Access key and Secret key are your identifiers for Amazon S3
Access Key: [PUT YOUR ACCESS KEY]
Secret Key: [PUT YOUR SECRET KEY]

Encryption password is used to protect your files from reading
by unauthorized persons while in transfer to S3
Encryption password: [PUT YOUR PASSWORD]
Path to GPG program [/usr/bin/gpg]:

When using secure HTTPS protocol all communication with Amazon S3
servers is protected from 3rd party eavesdropping. This method is
slower than plain HTTP and can't be used if you're behind a proxy
Use HTTPS protocol [No]:

On some networks all internet access must go through a HTTP proxy.
Try setting it here if you can't conect to S3 directly
HTTP Proxy server name:

New settings:
  Access Key: [PUT YOUR ACCESS KEY]
  Secret Key: [PUT YOUR SECRET KEY]
  Encryption password: [PUT YOUR PASSWORD]
  Path to GPG program: /usr/bin/gpg
  Use HTTPS protocol: False
  HTTP Proxy server name:
  HTTP Proxy server port: 0

Test access with supplied credentials? [Y/n] y
Please wait...
Success. Your access key and secret key worked fine :-) 

Now verifying that encryption works...
Success. Encryption and decryption worked fine :-) 

Save settings? [y/N] y
   * Configuration saved to '/home/ec2-user/.s3cfg'

一応、設定ファルのパスをメモっておく。

sync してみる

$ sudo s3cmd sync s3://deesea-bucket/test-dir/ ./test-s3fs/
(snip)
Done. Downloaded 20912437 bytes in 54.9 seconds, 372.27 kB/s

$ du -h --max-depth=1 test-s3fs/
18M     test-s3fs/wordpress
23M     test-s3fs/

23MBで55secくらいかかった。

作成されたディレクトリファイルは実行したユーザの所有権が付与される。

$ ll plugins
合計 20
drwxr-xr-x 2 root root 4096  7月  2 06:40 2013 testdir01
-rwxr-xr-x 1 root root 2262  7月  2 06:16 2013 testfile01.txt

パーミッションは 755。

テストの時は –dry-run つけると実際のファイルは更新せずに実行結果の出力をしてくれる。

sync コマンドの注意点は S3 にあってインスタンスにないファイル・ディレクトリは追加してくれるが、S3 になくてインスタンスにあるものは削除してくれない。sync と言いつつ実は追加・更新のみで削除はしてくれない。これを解消するために –delete-removed がある。

–delete-removed を試す

$ sudo s3cmd --delete-removed sync s3://deesea-bucket/test-dir/ ./test-s3fs/

ただこれも注意点があって、ファイルは削除するがディレクトリは残ったままになる。ディレクトリ内のファイルはなくなるがディレクトリまでは削除してくれるない。もしプログラム的に「ディレクトリがあったら」という条件式を書く場合は不具合が起きるので「ディレクトリ内のファイルが1つでもあれば」というようにすると良いだろう。

–exclude を試す

ある特定のディレクトリ・ファイルを sync の対象から外したい時は –exclude を付ける。
特定のファイル名なら –exclude=”testfile01.txt” とすればよいのだけど、特定のディレクトリ配下のファイルすべて除外するという指定する時が結構やっかいだった。
結局、–exclude=”*exclude-dir/*” で動いた。

$ sudo s3cmd --delete-removed --exclude="*exclude-dir/*" sync s3://deesea-bucket/test-dir/ ./test-s3fs/

これを継続的に回す cron に記述すれば定期的に処理できる。

$ sudo crontab -e

*/2 * * * * s3cmd --delete-removed sync s3://deesea-bucket/test-dir/ /usr/share/nginx/html/test-s3fs/

2分間隔で処理する記述。

AMIに仕込んでおけば、インスタンスが変わっても気にすることなくデプロイできる。うまく使えばとても楽にデプロイ環境が作れるので、オススメです。