AWS CLIを利用して、S3上にPOST可能なWebサイトを作成してみます。
前提条件
S3への権限
- S3に対してフル権限があること。
AWS CLIのバージョン
-
以下のバージョンで動作確認済
- AWS CLI 1.8.3
aws --version
aws-cli/1.8.3 Python/2.7.5 Darwin/13.4.0
- 準備
=======
0.1. リージョンの決定
Webサイトを構築するリージョンを決めます。
(カレントユーザが利用するカレントリージョンも切り変わります。)
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
- 事前作業
===========
1.1. サイト名の決定
組織名-handson-今日の日付とします。
ORG=<組織名>
HOSTNAME_WEBSITE="${ORG}-handson-`date +%Y%m%d`"
echo ${HOSTNAME_WEBSITE}
1.2. コンテンツ用バケット名の決定
S3_BUCKET_SITE="${HOSTNAME_WEBSITE}" \
&& echo ${S3_BUCKET_SITE}
同名のバケットが存在しないことを確認します。
aws s3 ls s3://${S3_BUCKET_SITE}
A client error (NoSuchBucket) occurred when calling the ListObjects operation: The specified bucket does not exist
1.3. ログ用バケット名の決定
S3_BUCKET_LOG="${S3_BUCKET_SITE}-log" \
&& echo ${S3_BUCKET_LOG}
同名のバケットが存在しないことを確認します。
aws s3 ls s3://${S3_BUCKET_LOG}
A client error (NoSuchBucket) occurred when calling the ListObjects operation: The specified bucket does not exist
1.4. ローカルディレクトリ作成
DIR_LOCAL_CONTENTS="$(pwd)/file-bucket" \
&& echo ${DIR_LOCAL_CONTENTS}
mkdir -p ${DIR_LOCAL_CONTENTS} \
&& cd ${DIR_LOCAL_CONTENTS}
1.5. index.html, error.html作成
cd ${DIR_LOCAL_CONTENTS}
cat << EOF > index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Title</title>
</head>
<body>
<h1>Hello!</h1>
<!-- comment -->
</body>
</html>
EOF
cat index.html
cat << EOF > error.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>404 File Not Found</h1>
<p>お探しのページは見つかりません。</p>
</body>
</html>
EOF
cat error.html
- コンテンツ用バケットの作成
=============================
S3_BUCKET_NAME="${S3_BUCKET_SITE}" \
&& echo ${S3_BUCKET_NAME}
cat << ETX
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
ETX
aws s3 mb s3://${S3_BUCKET_NAME}
make_bucket: s3://www.example.jp/
aws s3api get-bucket-location --bucket ${S3_BUCKET_NAME}
{
"LocationConstraint": "ap-northeast-1"
}
- ログ用バケットの作成/設定
============================
3.1. ログ用バケットの作成
S3_BUCKET_NAME="${S3_BUCKET_LOG}" \
&& echo ${S3_BUCKET_NAME}
cat << ETX
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
ETX
aws s3 mb s3://${S3_BUCKET_NAME}
make_bucket: s3://www.example.jp-log/
aws s3api get-bucket-location --bucket ${S3_BUCKET_NAME}
{
"LocationConstraint": "ap-northeast-1"
}
3.2. バケットACLの確認
aws s3api get-bucket-acl \
--bucket ${S3_BUCKET_NAME}
{
"Owner": {
"DisplayName": "prjz",
"ID": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"Grants": [
{
"Grantee": {
"DisplayName": "prjz",
"ID": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"Permission": "FULL_CONTROL"
}
]
}
3.3. バケットACLの変更
cat << ETX
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
ETX
aws s3api put-bucket-acl \
--bucket ${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で指定する。)
3.4. バケットACLの確認
aws s3api get-bucket-acl \
--bucket ${S3_BUCKET_NAME}
{
"Owner": {
"DisplayName": "prjz",
"ID": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
"Grants": [
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/s3/LogDelivery"
},
"Permission": "WRITE"
},
{
"Grantee": {
"URI": "http://acs.amazonaws.com/groups/s3/LogDelivery"
},
"Permission": "READ_ACP"
}
]
}
- ログ用バケットの設定 (ログローテーションの設定)
==================================================
4.1. 設定の確認
cat << ETX
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
ETX
aws s3api get-bucket-lifecycle \
--bucket ${S3_BUCKET_NAME}
A client error (NoSuchLifecycleConfiguration) occurred when calling the GetBucketLifecycle operation: The lifecycle configuration does not exist
4.2. 設定ファイルの作成
FILE_S3_LIFECYCLE='s3-lifecycle.json'
S3_LIFECYCLE_EXPIRE_DAYS='60'
S3_LIFECYCLE_TRANS_DAYS='30'
S3_LIFECYCLE_ID="${S3_BUCKET_NAME}-Archive"
S3_LIFECYCLE_IDは、Lifecycle RulesのRule Nameになります。(マネジメントコンソール上ではオプション扱い)
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
JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。
jsonlint -q ${FILE_S3_LIFECYCLE}
(戻り値なし)
4.3. 設定
cat << ETX
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
FILE_S3_LIFECYCLE: ${FILE_S3_LIFECYCLE}
ETX
aws s3api put-bucket-lifecycle \
--bucket ${S3_BUCKET_NAME} \
--lifecycle-configuration file://${FILE_S3_LIFECYCLE}
(戻り値なし)
4.4. 設定の確認
aws s3api get-bucket-lifecycle \
--bucket ${S3_BUCKET_NAME}
{
"Rules": [
{
"Status": "Enabled",
"Prefix": "/Logs",
"Transition": {
"Days": 1,
"StorageClass": "GLACIER"
},
"Expiration": {
"Days": 2
},
"ID": "www.example.jp-log-Archive"
}
]
}
- コンテンツ用バケットの設定 (ログ保存)
========================================
S3_BUCKET_NAME="${S3_BUCKET_SITE}" \
&& echo ${S3_BUCKET_NAME}
5.1. ログ保存設定の確認
aws s3api get-bucket-logging \
--bucket ${S3_BUCKET_NAME}
(戻り値なし)
5.2. ログ保存設定ファイルの作成
FILE_S3_LOGGING='s3-logging.json'
cat << EOF > ${FILE_S3_LOGGING}
{
"LoggingEnabled": {
"TargetBucket": "${S3_BUCKET_LOG}",
"TargetPrefix": "/Logs"
}
}
EOF
JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。
jsonlint -q ${FILE_S3_LOGGING}
(戻り値なし)
5.3. ログ保存の設定
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}
(戻り値なし)
5.4. ログ保存設定の確認
aws s3api get-bucket-logging \
--bucket ${S3_BUCKET_NAME}
{
"LoggingEnabled": {
"TargetPrefix": "/Logs",
"TargetBucket": "www.example.jp-log"
}
}
- コンテンツ用バケットの設定 (バケットポリシ)
==============================================
6.1. 設定の確認
cat << ETX
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
ETX
aws s3api get-bucket-policy \
--bucket ${S3_BUCKET_NAME} |\
sed 's/\\//g' |\
sed 's/"{/{/' |\
sed 's/}"/}/' |\
jq .
A client error (NoSuchBucketPolicy) occurred when calling the GetBucketPolicy operation: The bucket policy does not exist
6.2. 設定ファイルの作成
FILE_POLICY='s3-policy-readonly.json'
cat << EOF > ${FILE_POLICY}
{
"Version":"2012-10-17",
"Statement":[{
"Sid":"AddPerm",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::${S3_BUCKET_NAME}/*"]
}
]
}
EOF
JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。
jsonlint -q ${FILE_POLICY}
(戻り値なし)
6.3. 設定
cat << ETX
S3_BUCKET_NAME ${S3_BUCKET_NAME}
FILE_POLICY: ${FILE_POLICY}
ETX
aws s3api put-bucket-policy \
--bucket ${S3_BUCKET_NAME} \
--policy file://${FILE_POLICY}
(戻り値なし)
6.4. 設定の確認
aws s3api get-bucket-policy \
--bucket ${S3_BUCKET_NAME} |\
sed 's/\\//g' |\
sed 's/"{/{/' |\
sed 's/}"/}/' |\
jq .
{
"Policy": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::www.example.jp/*"
}
]
}
}
- コンテンツ用バケットの設定 (Website設定)
===========================================
7.1. 設定の確認
aws s3api get-bucket-website \
--bucket ${S3_BUCKET_NAME}
A client error (NoSuchWebsiteConfiguration) occurred when calling the GetBucketWebsite operation: The specified bucket does not have a website configuration
7.2. 設定
cat << ETX
S3_BUCKET_NAME: ${S3_BUCKET_NAME}
ETX
aws s3 website "s3://${S3_BUCKET_NAME}" \
--index-document index.html \
--error-document error.html
(戻り値なし)
7.4. 設定の確認
aws s3api get-bucket-website \
--bucket ${S3_BUCKET_NAME}
{
"IndexDocument": {
"Suffix": "index.html"
},
"ErrorDocument": {
"Key": "error.html"
}
}
- コンテンツ転送
=================
cd ${DIR_LOCAL_CONTENTS}
aws s3 sync . "s3://${S3_BUCKET_NAME}/" \
--exclude ".git*" \
--exclude ".hg*"
- アクセス確認
===============
バケットのURLを確認します。
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}
www.example.jp.s3-website-ap-northeast-1.amazonaws.com
ブラウザでアクセスできることを確認しましょう。
- CORSの設定
==============
10.1. 設定の確認
aws s3api get-bucket-cors \
--bucket ${S3_BUCKET_NAME}
A client error (NoSuchCORSConfiguration) occurred when calling the GetBucketCors operation: The CORS configuration does not exist
10.2. 設定ファイルの作成
FILE_CORS_RULE="${S3_BUCKET_NAME}-cors.json"
cat << EOF > ${FILE_CORS_RULE}
{
"CORSRules": [
{
"AllowedHeaders": [
"*"
],
"MaxAgeSeconds": 3000,
"AllowedMethods": [
"PUT"
],
"AllowedOrigins": [
"http://${S3_BUCKET_ENDPOINT}"
]
}
]
}
EOF
cat ${FILE_CORS_RULE}
JSONファイルを作成したら、フォーマットが壊れてないか必ず確認します。
jsonlint -q ${FILE_CORS_RULE}
(戻り値なし)
10.3. 設定
aws s3api put-bucket-cors \
--bucket ${S3_BUCKET_NAME} \
--cors-configuration file://${FILE_CORS_RULE}
(戻り値なし)
10.4. 設定の確認
aws s3api get-bucket-cors \
--bucket ${S3_BUCKET_NAME}
{
"CORSRules": [
{
"AllowedHeaders": [
"*"
],
"MaxAgeSeconds": 3000,
"AllowedMethods": [
"PUT"
],
"AllowedOrigins": [
"http://example-handson-20150928.s3-website-ap-northeast-1.amazonaws.com"
]
}
]
}
完了
Cognitoで識別子プールを作成し、コンテンツを置きます。