LoginSignup
4

More than 5 years have passed since last update.

S3のバケットポリシーを更新するスクリプト

Last updated at Posted at 2014-12-05

S3のポリシー変更スクリプト

インスタンスの増減に合わせてバケットポリシーの変更するのが面倒なので自動化!

supported by sebastian

利用例

インスタンスに付与されているタグを見てIPを取得する対象を判断します。

対象のPublicIPを取得して、S3のバケットポリシーを適用します。

ポリシーはスクリプト内にベタ書きしてます。

bash s3_bucket_policy.sh -t tagkey -r rolename -b bucket

スクリプト

bash
#!/bin/sh
# -----------------------------------------------------------------------------
# AWS CLIの確認
#
# retval 0 OK
# retval 1 パスが通っていないのでパスを通した
# retval 2 見つからなかった
# -----------------------------------------------------------------------------
function checkcli() {
    aws --version &> /dev/null
    if [ $? -eq 127 ] ; then
        awspath=$(which aws)
        if [ ! $? -eq 0 ]; then
            echo 'aws-cliが見つかりません'
            exit 2
        else
            addpath=$(echo $awspath |  sed -e 's/aws//g')
            PATH="$PATH":$addpath
            exit 1
        fi
    fi
    exit 0
}
# -----------------------------------------------------------------------------
# 実行しているインスタンス情報の取得
#
# retstd PublicIp 現在処理を行っているインスタンスのPublicIpを返す
# retval 正常終了
# retval 10 インスタンス上で実行されていない
# retval 11 インスタンスのリージョン取得失敗
# -----------------------------------------------------------------------------
function getregion() {
    # メタデータの疎通確認
    curl -s http://169.254.169.254  > /dev/null
    if [ ! $? -eq 0 ] ; then
        echo 'メタ情報にアクセス出来ません。EC2インスタンス上で実行して下さい'
        return 10
    fi
    # インスタンスリージョン取得
    REGION=$(curl -s http://169.254.169.254/latest/meta-data/local-hostname | cut -d '.' -f2)
    if [ -z "${REGION}" ] ; then
        echo 'メタ情報からリージョンの取得に失敗しました'
        return 11
    fi
}

# -----------------------------------------------------------------------------
#
# ヘルプ用書式表示
#
# -----------------------------------------------------------------------------
function syntax() {
    echo "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
    echo "                                                               2014 sato(supported by sebastian)"
    echo
    echo " Purpose"
    echo "   指定されたタグのインスタンスのIPをS3バケットポリシー登録に登録します。"
    echo
    echo " Syntax:"
        echo " $0 [-t tagkey] [-r rolename] [-b bucket] "
    echo
    echo "   tagkey: TagKeyを入力"
    echo "   rolename: TagKeyで指定したValueを入力"
    echo "   bucket: ポリシーを変更したいバケット名を入力"
    echo
    echo "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
    exit 0
}

# ----------------------------------------------------------------------------
# Main
# -----------------------------------------------------------------------------
#
# 初期値
#

FILE_S3_BUCKET_POLICY="s3-policy-readonly-stg.json"
BUCKET=""
TAGKEY=""
ROLENAME=""


#
#  引数の処理
#

while [ ! -z "$1" ]; do
    if [ "$1" == "help" ]; then
        syntax
    else
        flag=$1
        shift
        if [ -z "$1" ] ; then
            syntax
        fi
        case $flag in
            '-e' )
                ENV=$1
            ;;
        esac
    fi
    shift
done

if [ -z "${TAGKEY}" ] ; then
    echo "TAGKEYを指定して下さい[-t tagkey]"
    exit 0
fi
if [ -z "${ROLENAME}" ] ; then
    echo "ROLENAMEを指定して下さい[-r rolename]"
    exit 0
fi

if [ -z "${BUCKET}" ] ; then
    echo "BUCKETを指定して下さい[-b bucket]"
    exit 0

#
# AWS CLIの有無
#
check=`checkcli`
result=$?
if [ ! $result -eq 0 ] ; then
    echo $check
    exit $result
fi

#
# リージョンの処理
#
if [ -z "$getregion" ] ; then
    getregion
    result=$?
    if [ ! $result -eq 0 ] ; then
        echo $pip
        exit $result
    fi
fi

#
# 対象環境のIPリスト取得、置換
#
HOSTLIST_TMP=`aws ec2 describe-instances --region ${REGION} --filters "Name=tag-key,Values=${TAGKEY}" "Name=tag-value,Values=${ROLENAME}" | jq '.Reservations[].Instances[].PublicIpAddress'`
if [ ! $? -eq 0 ] ; then
  echo 'PublicIPの取得に失敗しました'
  exit
fi

HOSTLIST=`echo $HOSTLIST_TMP | sed 's/null//g' | sed 's/"  *"/","/g'`

#
# IPリスト確認
#
echo $HOSTLIST
echo "S3に登録するIPはこちらでよろしいですか? [Y/n]"
read ANSWER

case $ANSWER in
    "" | "Y" | "y" | "yes" | "Yes" | "YES" ) echo "YES!!";;
    * ) exit;;
esac

#
#バケットポリシーのバックアップ
#
DATE=$(date +"%Y%m%d%H%M")
aws s3api get-bucket-policy --bucket ${BUCKET} --region ${REGION} | jq -r '.Policy' | jq .  >  tmp/${FILE_S3_BUCKET_POLICY}_${DATE}.json
if [ ! $? -eq 0 ] ; then
  echo 'ポリシーのバックアップに失敗しました'
  exit
fi

#
# バケットポリシー作成
#
cat << EOF > ${FILE_S3_BUCKET_POLICY}
{
  "Statement": [
    {
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": [${HOSTLIST}]
        }
      },
      "Resource": "arn:aws:s3:::${BUCKET}/*",
      "Action": "s3:GetObject",
      "Principal": {
        "AWS": "*"
      },
      "Effect": "Allow",
      "Sid": "2"
    }
  ],
  "Id": "Policy EC2andCF",
  "Version": "2008-10-17"
}    
EOF

#
# ポリシー出力
#
echo "========================適用予定のポリシー====================================="

cat ${FILE_S3_BUCKET_POLICY} | jq .

echo "============================================================="

echo "========================現在のポリシー====================================="

cat tmp/${FILE_S3_BUCKET_POLICY}_${DATE}.json | jq .

echo "============================================================="A


echo "========================DIFF====================================="

diff -y tmp/${FILE_S3_BUCKET_POLICY}_${DATE}.json  ${FILE_S3_BUCKET_POLICY}

echo "============================================================="

#
# IPリスト確認
#
echo "こちらでよろしいですか? [Y/n]"
read ANSWER

case $ANSWER in
    "" | "Y" | "y" | "yes" | "Yes" | "YES" ) echo "YES!!";;
    * ) exit;;
esac

#
# バケットポリシー適用
#
aws s3api put-bucket-policy --bucket ${BUCKET} --policy file://${FILE_S3_BUCKET_POLICY} --region ${REGION}
if [ $? -eq 255 ] ; then
    echo "ポリシーの更新に失敗しました"
fi

#
# ポリシー確認
#
aws s3api get-bucket-policy --bucket ${BUCKET} --region ${REGION} | jq -r '.Policy' | jq .

GitHub

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4