S3で公開している静的コンテンツのアクセスログの設定と保存を行ないます。
前提条件
- [JAWS-UG CLI] 総合案内: http://qiita.com/tcsh/items/14c3278f69ab073afe0f を確認して、必要な手順を終えていること。
S3への権限
S3に対してフルアクセス権限があること。
AWS CLIのバージョン
以下のバージョンで動作確認済
- AWS CLI 1.10.1
- AWS CLI 1.7.39
- AWS CLI 1.7.12
aws --version
aws-cli/1.10.1 Python/2.7.5 Darwin/13.4.0 botocore/1.3.23
- 準備
=======
0.1. リージョンの決定
export AWS_DEFAULT_REGION='ap-northeast-1'
0.2. 変数の確認
aws configure list
Name Value Type Location
---- ----- ---- --------
profile s3Full-prjZ-mbp13 env AWS_DEFAULT_PROFILE
access_key ****************LOAQ shared-credentials-file
secret_key ****************I1O1 shared-credentials-file
region ap-northeast-1 env AWS_DEFAULT_REGION
AssumeRoleを利用している場合はprofileが '<not set>'と表示されます。
それ以外のときにprofileが '<not set>' と表示される場合は、以下を実行してください。
export AWS_DEFAULT_PROFILE=<IAMユーザ名>
0.3. コンテンツの公開
http://qiita.com/tcsh/items/70694da357c1738c6bf8 (ハイレベルS3コマンドで静的Webホスティング)の手順を実施しておいてください。
- 事前作業
=============
1.1. AWSアカウント(メールアドレス)の指定
AWS_ACCOUNT='example@example.jp'
1.2. 対象バケットの決定
${S3_BUCKET_NAME}に、静的コンテンツのバケット名が定義されていることを確認してください。
S3_BUCKET_NAME=<バケット名>
aws s3 ls s3://${S3_BUCKET_NAME}/
example-handson-20160201
2. [ログ用バケット] 作成
まず最初に、ログ保存用のバケットの作成とACL設定をします。
cat << ETX
AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION}
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
ETX
aws s3api create-bucket \
--create-bucket-configuration LocationConstraint=${AWS_DEFAULT_REGION} \
--bucket accesslog-${S3_BUCKET_NAME}
{
"Location": "http://accesslog-example-handson-20160201.s3.amazonaws.com/"
}
aws s3api get-bucket-location \
--bucket ${S3_BUCKET_NAME}
{
"LocationConstraint": "ap-northeast-1"
}
2. [ログ用バケット] ACL設定
-
http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/WhenToUseACLvsBucketPolicy.html
- ACL は大まかなアクセス許可モデルを提供し、単純にバケットまたはオブジェクトへのアクセス許可を付与します。
-
http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/ACLOverview.html
- 1 つの ACL には最大 100 個の許可を指定することができます。
2.1. ACL設定(デフォルト)の確認
バケットを作成したら、ACLを確認してみましょう。
aws s3api get-bucket-acl \
--bucket accesslog-${S3_BUCKET_NAME}
{
"Owner": {
"DisplayName": "example",
"ID": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"Grants": [
{
"Grantee": {
"DisplayName": "example",
"ID": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"Permission": "FULL_CONTROL"
}
]
}
管理者にフル制御の権限が割り当てられていますが、それ以外のリソースからはアクセスできない状態になっています。
2.2. ACLの変更
S3のログが書き込めるようにACLの設定を変更します。
cat << ETX
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
ETX
aws s3api put-bucket-acl \
--bucket accesslog-${S3_BUCKET_NAME} \
--grant-write 'URI="http://acs.amazonaws.com/groups/s3/LogDelivery"' \
--grant-read-acp 'URI="http://acs.amazonaws.com/groups/s3/LogDelivery"' \
--grant-full-control "EmailAddress=${AWS_ACCOUNT}"
(戻り値なし)
2.3. ACLの確認
変更をしたら、ACLの内容を確認します。
aws s3api get-bucket-acl \
--bucket accesslog-${S3_BUCKET_NAME}
{
"Owner": {
"DisplayName": "example",
"ID": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"Grants": [
{
"Grantee": {
"DisplayName": "example",
"ID": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"Permission": "FULL_CONTROL"
},
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/s3/LogDelivery"
},
"Permission": "WRITE"
},
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/s3/LogDelivery"
},
"Permission": "READ_ACP"
}
]
}
-
S3のログについて、バケットへの書き込み(WRITE)およびACL情報の読み取り(READ_ACP)が許可されていることがわかります。
- log-delivery-write(既定ACL)と同じ設定
3. [コンテンツ用バゲット] ログ保存設定
3.1. 設定ファイルの作成
FILE_S3_LOGGING='s3-logging.json'
cat << ETX
FILE_S3_LOGGING: ${FILE_S3_LOGGING}
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
AWS_ACCOUNT: ${AWS_ACCOUNT}
ETX
cat << EOF > ${FILE_S3_LOGGING}
{
"LoggingEnabled": {
"TargetBucket": "accesslog-${S3_BUCKET_NAME}",
"TargetPrefix": "Logs/",
"TargetGrants": [
{
"Grantee": {
"Type": "AmazonCustomerByEmail",
"EmailAddress": "${AWS_ACCOUNT}"
},
"Permission": "FULL_CONTROL"
},
{
"Grantee": {
"Type": "Group",
"URI": "http://acs.amazonaws.com/groups/global/AllUsers"
},
"Permission": "READ"
}
]
}
}
EOF
cat ${FILE_S3_LOGGING}
{
"LoggingEnabled": {
"TargetBucket": "accesslog-example-01",
"TargetPrefix": "Logs/",
"TargetGrants": [
{
"Grantee": {
"Type": "AmazonCustomerByEmail",
"EmailAddress": "example@example.jp"
},
"Permission": "FULL_CONTROL"
},
{
"Grantee": {
"Type": "Group",
"URI": "http://acs.amazonaws.com/groups/global/AllUsers"
},
"Permission": "READ"
}
]
}
}
JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。
jsonlint -q ${FILE_S3_LOGGING}
(戻り値なし)
3.2. ログ設定
cat << ETX
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
FILE_S3_LOGGING: ${FILE_S3_LOGGING}
ETX
aws s3api put-bucket-logging \
--bucket ${S3_BUCKET_NAME} \
--bucket-logging-status file://${FILE_S3_LOGGING}
(戻り値なし)
3.3. ログ設定の確認
aws s3api get-bucket-logging \
--bucket ${S3_BUCKET_NAME}
{
"LoggingEnabled": {
"TargetPrefix": "Logs/",
"TargetBucket": "accesslog-example-handson-20160201",
"TargetGrants": [
{
"Grantee": {
"DisplayName": "example",
"ID": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"Permission": "FULL_CONTROL"
},
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/global/AllUsers"
},
"Permission": "READ"
}
]
}
}
3.4. コンテンツにアクセスする。
Webブラウザで、コンテンツにアクセスしてみましょう。
S3_BUCKET_ENDPOINT="${S3_BUCKET_NAME}.s3-website-`aws s3api get-bucket-location --bucket ${S3_BUCKET_NAME} --output text`.amazonaws.com" \
&& echo ${S3_BUCKET_ENDPOINT}
example-handson-20160201.s3-website-ap-northeast-1.amazonaws.com
Webブラウザで EndPoint が開くと、アクセスログが書き込まれます。
3.5. ログ保存の確認
30分から1時間ほど待つと、15分前までのログが書き出されているはずです。
aws s3 ls s3://accesslog-${S3_BUCKET_NAME}/
PRE Logs/
aws s3 ls s3://accesslog-${S3_BUCKET_NAME}/Logs/
2014-08-24 18:23:27 290 2014-08-24-09-23-26-XXXXXXXXXXXXXXXX
2014-08-24 18:24:12 292 2014-08-24-09-24-11-YYYYYYYYYYYYYYYY
-
ログはベストエフォート設計のため、全てのアクセスが記録される保証は無いようです。
4. [ログ用バケット] ログアーカイブの設定
4.1. 設定ファイルの作成
FILE_S3_LIFECYCLE='s3-lifecycle.json'
S3_LIFECYCLE_EXPIRE_DAYS='6000'
S3_LIFECYCLE_TRANS_DAYS='3000'
S3_LIFECYCLE_ID="accesslog-${S3_BUCKET_NAME}-Log-Archive"
- S3_LIFECYCLE_IDは、Lifecycle RulesのRule Nameになります。(マネジメントコンソール上ではオプション扱い)
cat << ETX
FILE_S3_LIFECYCLE: ${FILE_S3_LIFECYCLE}
S3_LIFECYCLE_EXPIRE_DAYS: ${S3_LIFECYCLE_EXPIRE_DAYS}
S3_LIFECYCLE_ID: ${S3_LIFECYCLE_ID}
S3_LIFECYCLE_TRANS_DAYS: ${S3_LIFECYCLE_TRANS_DAYS}
ETX
cat << EOF > ${FILE_S3_LIFECYCLE}
{
"Rules": [
{
"Expiration": {
"Days": ${S3_LIFECYCLE_EXPIRE_DAYS}
},
"ID": "${S3_LIFECYCLE_ID}",
"Prefix": "Logs/",
"Status": "Enabled",
"Transition": {
"Days": ${S3_LIFECYCLE_TRANS_DAYS},
"StorageClass": "GLACIER"
}
}
]
}
EOF
{
"Rules": [
{
"Expiration": {
"Days": 60
},
"ID": "accesslog-example-handson-20160201-Log-Archive",
"Prefix": "Logs/",
"Status": "Enabled",
"Transition": {
"Days": 30,
"StorageClass": "GLACIER"
}
}
]
JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。
jsonlint -q ${FILE_S3_LIFECYCLE}
(戻り値なし)
4.2. ログアーカイブの設定
cat << ETX
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
FILE_S3_LIFECYCLE: ${FILE_S3_LIFECYCLE}
ETX
aws s3api put-bucket-lifecycle \
--bucket accesslog-${S3_BUCKET_NAME} \
--lifecycle-configuration file://${FILE_S3_LIFECYCLE}
(戻り値なし)
4.3. ログアーカイブ設定の確認
aws s3api get-bucket-lifecycle \
--bucket accesslog-${S3_BUCKET_NAME}
{
"Rules": [
{
"Status": "Enabled",
"Prefix": "Logs/",
"Transition": {
"Days": 30,
"StorageClass": "GLACIER"
},
"Expiration": {
"Days": 60
},
"ID": "accesslog-example-handson-20160201-Log-Archive"
}
]
}