はじめに
AWS CloudFormationを利用してS3のクロスリージョン相互レプリケーション構築のテンプレートのサンプルです。
東京リージョンと大阪リージョンにS3バケットを作成し、相互レプリケーションの設定をします。
S3バケットのARNを相互参照するため、一度作成した後に、変更セットでレプリケーションルールを設定します。
テンプレートの概要が分からない場合は、はじめてのAWS CloudFormationテンプレートを理解するを参考にしてください。
コードはGitHubにもあります。
今回は、akane というシステムの dev 環境を想定しています。
同じ構成で違う環境を作成する場合は、{環境名}-parameters.jsonを別途作成します。
ディレクトリ構成
akane (システム)
├── s3 (スタック)
│ ├── dev-parameters.json (dev 環境のパラメータ)
│ └── s3.yml (CFnテンプレート)
└── s3-replication (スタック)
├── dev-parameters.json (dev 環境のパラメータ)
└── s3-replication.yml -> ../s3/s3.yml (CFnテンプレートのシンボリックリンク)
AWS リソース構築内容
- s3スタック
- IAMロール (s3)
- s3バケット (akane-dev-s3)
実行環境の準備
AWS CloudFormationを動かすためのAWS CLIの設定を参考にしてください。
AWS リソース構築手順
-
下記を実行してスタックを作成
./create_stacks.sh
-
下記を実行してスタックを削除
./delete_stacks.sh
構築テンプレート
1. s3スタック
s3.yml
AWSTemplateFormatVersion: 2010-09-09
Description: S3 For Akane
# Metadata:
Parameters:
SystemName:
Type: String
AllowedPattern: '[a-zA-Z0-9-]*'
EnvType:
Description: Environment type.
Type: String
AllowedValues: [all, dev, stg, prod]
ConstraintDescription: must specify all, dev, stg, or prod.
IsFirstTime:
Type: String
AllowedValues: [true, false]
Mappings:
AnotherAz:
ap-northeast-1:
Region: ap-northeast-3
ap-northeast-3:
Region: ap-northeast-1
Conditions:
IsFirstTime: !Not [ !Equals [ !Ref IsFirstTime, true ] ]
# Transform
Resources:
# ロール作成
akaneS3ReplicationRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- s3.amazonaws.com
Action:
- sts:AssumeRole
Description: !Sub
- ${SystemName}-${EnvType}-role-s3-replication-${AWS::Region}
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
Path: /
Policies:
- PolicyName: !Sub
- ${SystemName}-${EnvType}-policy-s3-replication-${AWS::Region}
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- s3:Get*
- s3:ListBucket
Resource:
- !Join
- ''
- - 'arn:aws:s3:::'
- !Sub
- ${SystemName}-${EnvType}-s3-${AWS::Region}
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
- !Join
- ''
- - 'arn:aws:s3:::'
- !Sub
- ${SystemName}-${EnvType}-s3-${AWS::Region}
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
- /*
- Effect: Allow
Action:
- s3:ReplicateObject
- s3:ReplicateDelete
- s3:ReplicateTags
- s3:GetObjectVersionTagging
Resource:
- !Join
- ''
- - 'arn:aws:s3:::'
- !Sub
- ${SystemName}-${EnvType}-s3-
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
- !FindInMap [AnotherAz, !Ref AWS::Region, Region]
- /*
RoleName: !Sub
- ${SystemName}-${EnvType}-role-s3-replication-${AWS::Region}
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
Tags:
- Key: Name
Value: !Sub
- ${SystemName}-${EnvType}-role-s3-replication-${AWS::Region}
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
- Key: SystemName
Value: !Ref SystemName
- Key: EnvType
Value: !Ref EnvType
# S3 Bucket作成
akaneS3Bucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: Private
BucketName: !Sub
- ${SystemName}-${EnvType}-s3-${AWS::Region}
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
VersioningConfiguration:
Status: Enabled
ReplicationConfiguration: !If
- IsFirstTime
- Role: !GetAtt akaneS3ReplicationRole.Arn
Rules:
- Destination:
Bucket: !Join
- ''
- - !Sub arn:aws:s3:::${SystemName}-${EnvType}-s3-
- !FindInMap [AnotherAz, !Ref AWS::Region, Region]
Id: ClossRegionSync
Prefix: ''
Status: Enabled
- !Ref AWS::NoValue
Tags:
- Key: Name
Value: !Sub
- ${SystemName}-${EnvType}-s3-${AWS::Region}
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
- Key: SystemName
Value: !Ref SystemName
- Key: EnvType
Value: !Ref EnvType
Outputs:
akaneS3BucketArn:
Value: !GetAtt akaneS3Bucket.Arn
Export:
Name: !Sub
- ${SystemName}-${EnvType}-s3-arn-${AWS::Region}
- {SystemName: !Ref SystemName, EnvType: !Ref EnvType}
dev-parameters.json
{
"Parameters": [
{
"ParameterKey": "SystemName",
"ParameterValue": "akane"
},
{
"ParameterKey": "EnvType",
"ParameterValue": "dev"
},
{
"ParameterKey": "IsFirstTime",
"ParameterValue": "true"
}
],
"Capabilities": [
"CAPABILITY_NAMED_IAM"
]
}
2. s3スタック
s3-replication.yml
は、s3.yml
のシンボリックリンクのため記載を割愛する。
dev-parameters.json
{
"Parameters": [
{
"ParameterKey": "SystemName",
"ParameterValue": "akane"
},
{
"ParameterKey": "EnvType",
"ParameterValue": "dev"
},
{
"ParameterKey": "IsFirstTime",
"ParameterValue": "false"
}
],
"Capabilities": [
"CAPABILITY_NAMED_IAM"
]
}
3. 実行ファイル
create_stacks.sh
#!/bin/sh
cd `dirname $0`
SYSTEM_NAME=akane
create_stack () {
ENV_TYPE=$1
STACK_NAME=$2
export AWS_DEFAULT_REGION=$3
aws cloudformation create-stack \
--stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME} \
--template-body file://./${SYSTEM_NAME}/${STACK_NAME}/${STACK_NAME}.yml \
--cli-input-json file://./${SYSTEM_NAME}/${STACK_NAME}/${ENV_TYPE}-parameters.json
aws cloudformation wait stack-create-complete \
--stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME}
}
create_change_set () {
ENV_TYPE=$1
STACK_NAME=$2
export AWS_DEFAULT_REGION=$3
if [ ${STACK_NAME} == "s3-replication" ]; then
STACK_FULLNAME=${SYSTEM_NAME}-${ENV_TYPE}-s3
else
STACK_FULLNAME=${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME}
fi
aws cloudformation create-change-set \
--stack-name ${STACK_FULLNAME} \
--change-set-name ${STACK_FULLNAME}-change-set \
--template-body file://./${SYSTEM_NAME}/${STACK_NAME}/${STACK_NAME}.yml \
--cli-input-json file://./${SYSTEM_NAME}/${STACK_NAME}/${ENV_TYPE}-parameters.json
aws cloudformation wait change-set-create-complete \
--stack-name ${STACK_FULLNAME} \
--change-set-name ${STACK_FULLNAME}-change-set
aws cloudformation execute-change-set \
--stack-name ${STACK_FULLNAME} \
--change-set-name ${STACK_FULLNAME}-change-set
}
create_stack dev s3 ap-northeast-1
create_stack dev s3 ap-northeast-3
create_change_set dev s3-replication ap-northeast-1
create_change_set dev s3-replication ap-northeast-3
exit 0
delete_stacks.sh
#!/bin/sh
cd `dirname $0`
SYSTEM_NAME=akane
delete_stack () {
ENV_TYPE=$1
STACK_NAME=$2
export AWS_DEFAULT_REGION=$3
aws cloudformation delete-stack \
--stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME}
aws cloudformation wait stack-delete-complete \
--stack-name ${SYSTEM_NAME}-${ENV_TYPE}-${STACK_NAME}
}
delete_stack dev s3 ap-northeast-1
delete_stack dev s3 ap-northeast-3
exit 0