S3に画像をuploadする.shファイルをAutomatorでGUI化してつかってもらう


# 本記事のサマリ
s3に特定のローカルフォルダをawsコマンド経由でs3にアップロードして、外部に公開するshellスクリプトを非エンジニア向けに使ってもらうようにAutomatorでラッピングしたので紹介します。

## 経緯
元々、画像を定期的にs3に上げて公開するような運用をしていて、cyberduckで上げて公開権限するというのもだるかったので、awscliでローカルにある画像フォルダを転送して公開状態にするようなshellを作って運用していました。それを非エンジニアの方に巻き取ってもらうようなことになり、黒い画面は拒絶反応がありそうだったので、とりあえず手間をかけずに実現したかったので、Automatorで黒い画面をださなけりゃいいだろうという安直な考えで作ってみました。かなりニッチな需要だと思っていますが。。。

ニッチだと思っている理由↓

 * bucketが分けられるのであれば、bucketのpolicyをデフォルト「public read」にしてcyberduckとか使ってアップしてもらうでよい
 * AutomatorでやっているのでMAC前提だ
 * 今回は元々shellを作ってしまっていたというのでshellをラッピングしているけど、shellじゃない方がカスタマイズしやすい。（例えばJavaならJavaFXとかつかえばええやんってなる。）

## 対象読者
Macユーザの非エンジニアの方に、定期的にs3に画像アップして公開状態にしてもらいたくてawsコマンド叩いて欲しいなぁと思っているが、黒い画面は拒絶されるような状況の人向け(うわぁ、ニッチそう...)また黒い画面は使わずにGUIツール使ってもらおうにも、s3のバケットポリシーをデフォルトで「public read」にできず、GUIで権限変更する手間が嫌って言われそうな人向け

## 動作確認バージョン
```sh
aws --version
# -> aws-cli/1.11.89 Python/2.7.10 Darwin/16.6.0 botocore/1.5.52

```

## 前提条件
### awscliのインストール
awscliがインストールされている。されていない人は、Homebrewが入っていれば、`brew install awscli`でOKです。
この辺が参考になりそうでした。
http://qiita.com/maimai-swap/items/999eb69b7a4420d6ab64

### アクセスキーID・シークレットアクセスキーの払い出し
awscliでアクセスするためのs3のアップロード用の権限を持ったIAMを作成し、そのIAMユーザーのアクセスキーIDとシークレットアクセスキーが払い出されていることが大前提です。他のs3オブジェクトに悪影響しないように操作できる対象が絞られていることが望ましいです。
http://dev.classmethod.jp/etc/specify_s3_folder_iam_cyberduck/

## ローカルのディレクトリをs3に丸ごとコピーするようなshell

とりあえずローカルのフォルダを転送してpublic-readにするshellです。

### 構成
${HOME}/Desktop/tools/
├ transfer_image.sh
├ transfer_to_s3
  ┝画像フォルダ1
  ┝画像フォルダ2
  ...
└ aws.txt


### 画像を転送するshell↓

```bash:transfer_image.sh
#/bin/bash
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
BASE_DIR=`dirname ${0}`
LOG_FILE=${BASE_DIR}/result.log
export AWS_CONFIG_FILE=${BASE_DIR}/aws.txt

echo '----------------------------------------' | tee -a ${LOG_FILE}
echo `DATE` | tee -a ${LOG_FILE}
if [ ! -e ${AWS_CONFIG_FILE} ]
then
  echo "Can't find ${BASE_DIR}/aws.txt!!!!" | tee -a ${LOG_FILE}
  exit 1
fi

if [ $# -ne 1 ]
then
  echo 'please input image directory!!' | tee -a ${LOG_FILE}
  echo 'ex) sh images_transfer.sh hoge_dir' | tee -a ${LOG_FILE}
  echo "current input is arg1=[$1] arg_size is $#" | tee -a ${LOG_FILE}
  exit 1
fi
TARGET_IMAGE_DIR=$1
UPLOAD_TARGET_DIR_PATH=${BASE_DIR}/transfer_to_s3/${TARGET_IMAGE_DIR}

if [ ! -d ${UPLOAD_TARGET_DIR_PATH} ]
then
  echo "target directory not exist [${BASE_DIR}/${TARGET_IMAGE_DIR}]" | tee -a ${LOG_FILE}
  exit 1
fi

DESTINATION_S3_BUCKET='hogehoge-test-bucket'
UPLOAD_DESTINATION="s3://${DESTINATION_S3_BUCKET}/for_ami_test/images/${TARGET_IMAGE_DIR}"
echo "upload to ${UPLOAD_DESTINATION}" | tee -a ${LOG_FILE}

echo "aws s3 cp ${UPLOAD_TARGET_DIR_PATH} ${UPLOAD_DESTINATION} --recursive --acl public-read" | tee -a ${LOG_FILE}
aws s3 cp ${UPLOAD_TARGET_DIR_PATH} ${UPLOAD_DESTINATION} --recursive --acl public-read  2>&1 | tee -a ${LOG_FILE}
exit 0
```

Automatorで呼び出したときにデバッグしやすいように、teeでログ出力するようにしていて見づらい部分もありますが、引数で渡されたディレクトリ名(ディレクトリはaws_to_s3配下に置いてもらう前提)を渡すとs3の所定のバケット内のディレクトリに同じ名前で放り込んでpublic-read権限を付与するといったものになっています。
DESTINATION_S3_BUCKETでバケットを指定していて、UPLOAD_DESTINATIONでバケット以下のディレクトリを指定しているので、適宜変更してください。


また、aws.txtは、aws configureで設定したくなかったので都度環境変数に設定するために外だししたファイルで以下のようになっています。

```aws.txt
[default]
aws_access_key_id=XXXXXXXXXXXXXX
aws_secret_access_key=XXXXXXXXXXXXXXXXXXXXX
```

## Automatorのスクリプト

上記shellを黒い画面を見せずに呼び出すのに以下のようにAutomatorを組みます。

1. applescriptでアップロードする対象のディレクトリ名を入力させるダイアログを表示する。

1. 上記で受け取ったディレクトリ名を引数として転送用のshellファイルを実行する。


![Kobito.mx8VyL.png](https://qiita-image-store.s3.amazonaws.com/0/47854/0d336537-6cdc-1c75-8921-7d552246a015.png "Kobito.mx8VyL.png")

コードは以下の通りです。

```applescript:appleスクリプトを実行
on run {input, parameters}
	tell application "System Events"
		display dialog "アップロードするフォルダを入力してください" default answer "hoge" buttons {"OK", "Cancel"}
		if button returned of result = "OK" then
			set target_dir to text returned of the result
		end if
	end tell
	return {target_dir}
end run
```

```bash:shellスクリプトを実行
# Automatorでのパス取得は困難であるため固定的に配置
TARGET_SHELL_PATH_BASE=${HOME}/Desktop/tools
TARGET_SHELL_PATH=${TARGET_SHELL_PATH_BASE}/images_transfer.sh
# Automatorでは/usr/local/binにパスが通っておらずhomebrewでインストールしたaws
# コマンドが使えないので、パスを通す
export PATH=/usr/local/bin:$PATH

sh ${TARGET_SHELL_PATH} ${1}
```

Automatorからshellを呼び出すのが、相対パスで呼び出すのが難しそう(Automatorのパスは取得できるが、そこにshell達を置くのはいや）だったので、制約にはなっていますが${HOME}/Desktop/toolsに書くファイルを配置してもらうようにしました。
上記Automatorをアプリケーションとして保存してあげればOKです。

${HOME}/Desktop/tools/
├ transfer_image.sh
├ transfer_to_s3
  ┝画像フォルダ1
  ┝画像フォルダ2
  ...
├ aws.txt
└ image_transfer.app

実行するとこんな感じ

![Kobito.ENrOwk.png](https://qiita-image-store.s3.amazonaws.com/0/47854/e7ed8e8d-9d7c-106f-c1b3-3ddf356c99af.png "Kobito.ENrOwk.png")


image_transfer.app実行
![Kobito.QF7Gix.png](https://qiita-image-store.s3.amazonaws.com/0/47854/81e43b33-7976-541d-97d7-ba6bfb39cfff.png "Kobito.QF7Gix.png")

OK押下

awsのコンソールから確認
![Kobito.J1WrM1.png](https://qiita-image-store.s3.amazonaws.com/0/47854/14acced1-685a-e806-26c6-92bc724eeaaa.png "Kobito.J1WrM1.png")

画像は載せませんが、ちゃんとブラウザからURLを叩いてアクセスすることもできました。