We completed building the bookstore in the primary region (Ireland) in the previous module. In this module, we will build the same Bookstore in Singapore region and configure the replication of Aurora MySQL for the Blog content, S3 bucket for static contects, and DynamoDB tables for the books/order/cart data from the primary region (Ireland) to the secondary region (Singapore).
Go back to your Cloud9 (that you created in Ireland
), and execute following commands. It will take around 15 mins.
Let's make sure your environment variable MYSUBDOMAIN is correctly set. Enter the same MYSUBDOMAIN as you did previously from module 1.
export MYSUBDOMAIN=<enter a 8 char unique subdomain name with lower case, eg: team1234>
Similar to Ireland region, before you do the S3 replication, let's create the new S3 bucket for the reactJS app in Singapore (ap-southeast-1) region.
aws s3api create-bucket \
--bucket arc309-singapore-$MYSUBDOMAIN-bookstore \
--region ap-southeast-1 \
--create-bucket-configuration LocationConstraint=ap-southeast-1
cd ~/environment/MultiRegion-Modern-Architecture/wordpress-lab/
export hostedZoneID=`aws cloudformation describe-stacks --stack-name hostedZone --region eu-west-1 \
--query "Stacks[0].Outputs[?OutputKey=='hostedZoneID'].OutputValue" --output text`
export hostedZoneName=$MYSUBDOMAIN.multi-region.xyz
export AWS_DEFAULT_REGION=ap-southeast-1
npx cdk@1.22.0 bootstrap
npx cdk@1.22.0 deploy Wordpress-Secondary
Do you wish to deploy these changes (y/n)?
. Enter "y"
Now, your Book Blog in Singapore is completed. However, you will find 503 Service Temporarily Unavailable
error if you verify https://secondary.blog.<MYSUBDOMAIN>.multi-region.xyz/
as the wordpress is not connected the Aurora MySQL in Singapore region yet. We will configure this in the next section.
In this section, we will configure the replication of Aurora MySQL for the Blog content, S3 bucket for static contents, and DynamoDB tables for the books/order/cart data from the primary region (Ireland) to the secondary region (Singapore).
However, replication of Aurora MySQL and S3 is optional configuration for the Bookstore Failover testing in the next module. Hence, you can skip it now if you have no time to configure.
Aurora MySQL Read replica helps you have a redundancy plan. The replica in `Singapore` region can be promoted as the primary database when the primary database in the primary region (`Ireland`) has issues.
Go back to Cloud9, and execute the following commands to enable the read replica of Aurora MySQL in Singapore
region
from Ireland region using the AWS CLI.
replication-source-identifier
: Get from Cloudformation stackWordpress-Primary
in Ireland Region. Or use the following command in Cloud9.
export ReplicationSourceIdentifier=`aws cloudformation describe-stacks --stack-name Wordpress-Primary --region eu-west-1 \
--query "Stacks[0].Outputs[?OutputKey=='RDSreplicationsourceidentifier'].OutputValue" --output text`
echo $ReplicationSourceIdentifier
vpc-security-group-ids
: Get from Cloudformation stackWordpress-Secondary
in Singapore Region. Or use the following command in Cloud9.
export VpcSecurityGroupIds=`aws cloudformation describe-stacks --stack-name Wordpress-Secondary --region ap-southeast-1 \
--query "Stacks[0].Outputs[?OutputKey=='WordpressDBsecurityGroupId'].OutputValue" --output text`
echo $VpcSecurityGroupIds
CLI to create read replica of Aurora MySQL in Singapore region.
aws rds create-db-cluster \
--db-cluster-identifier arc309-replica-cluster \
--engine aurora \
--replication-source-identifier $ReplicationSourceIdentifier \
--vpc-security-group-ids $VpcSecurityGroupIds \
--db-subnet-group-name secondaryregion-wordpressdb-subnetgroup \
--source-region eu-west-1 \
--region ap-southeast-1
Verify the RDS replication cluster is created in Singapore region.
aws rds describe-db-clusters --db-cluster-identifier arc309-replica-cluster --region ap-southeast-1
Create RDS read replica instance.
aws rds create-db-instance \
--db-instance-identifier arc309-replica-instance \
--db-cluster-identifier arc309-replica-cluster \
--db-instance-class db.t3.small \
--engine aurora \
--region ap-southeast-1
Verify RDS cluster creation in RDS console in Singapore region.
Provisioning the Aurora replica instance can take a while takes for a while, you can procced the next step while the instance is being deployed.
This S3 replication will replicate the static contents from Ireland region to Singapore whenever there is an update.
Follow the steps to enable the S3 replication using the AWS CLI in Cloud9. The destination bucket name should be your bucket name in Singarpore
that you created above such as arc309-singapore-$MYSUBDOMAIN-bookstore
.
aws s3api put-bucket-versioning \
--bucket arc309-singapore-$MYSUBDOMAIN-bookstore \
--versioning-configuration Status=Enabled
aws s3 website s3://<arc309-singapore-$MYSUBDOMAIN-bookstore>/ --index-document index.html
Add replication configuration to the source bucket in Ireland region. Save the following JSON in a file called replication.json to the your Cloud9. You need S3 replication role ARN for this exercise. You can find it in the output table of your CloudFormation stack (MyBookstoreIreland) in Ireland or execute following command in the Cloud9.
export ReplicationArnRole=`aws cloudformation describe-stacks --stack-name MyBookstoreIreland --region eu-west-1 \
--query "Stacks[0].Outputs[?OutputKey=='S3replicationRole'].OutputValue" --output text`
copy and paste the following command to create a replication.json file:
echo '{
"Role": "'$ReplicationArnRole'",
"Rules": [
{
"Status": "Enabled",
"Priority": 1,
"DeleteMarkerReplication": { "Status": "Disabled" },
"Filter": {},
"Destination": {
"Bucket": "arn:aws:s3:::arc309-singapore-'$MYSUBDOMAIN'-bookstore"
}
}
]
}' > replication.json
aws s3api put-bucket-replication \
--replication-configuration file://replication.json \
--bucket arc309-ireland-$MYSUBDOMAIN-bookstore
You can check the replication configuration in S3 console.
S3 doesn't replicate objects retroactively. S3 Objects that existed before you added the replication configuration to the bucket aren't replicated to the new desination bucket. Hence, you need to sync the existing content to the new bucket in Singapore with following command.
aws s3 sync s3://arc309-ireland-$MYSUBDOMAIN-bookstore s3://arc309-singapore-$MYSUBDOMAIN-bookstore
Let's take a look at continuous replicating the data in DynamoDB from the primary region (Ireland) to the secondary region (Singapore) so that there is always a backup.
We will be using a feature of DynamoDB Global Tables
for this. Any changes
made to any items in any replica tables will be replicated to all of the other
replicas within the same global table. In a global table, a newly-written item is
usually propagated to all replica tables within seconds.
However, conflicts can arise if applications update the same item in different regions at about the same time. To ensure eventual consistency, DynamoDB global tables use a “last writer wins” reconciliation between concurrent updates, where DynamoDB makes a best effort to determine the last writer.
Follow the steps to create a global table of Book, Order, Cart form the Ireland to Singapore regions using the console.
Go to DynamoDB in Ireland. Select Books
table, go to Global Tables
tab, and click Add region
Select Singapore
, and click Continue
.
If you get the Internal Error
message in the creation, please close the window and try again.
Do the same steps or bookstore-Orders
and bookstore-Cart
tables.
Now, you completed the replication across two regions for Aurora MySQL, S3, and DynamoDB. It's time to build the Bookstore eb/App layer in Singapore.
Step-by-step instructions
- Let's "grep" all the variables we need from the Wordpress-Primary stack in Cloudformation via the commands below:
export vpcSingapore=`aws cloudformation describe-stacks --stack-name Wordpress-Secondary \
--region ap-southeast-1 \
--query "Stacks[0].Outputs[?OutputKey=='SecondaryRegionVpcIdapsoutheast1'].OutputValue" \
--output text`
echo $vpcSingapore
export subnetSingapore=`aws cloudformation describe-stacks --stack-name Wordpress-Secondary \
--region ap-southeast-1 \
--query "Stacks[0].Outputs[?OutputKey=='SecondaryRegionprivatesubnetforElasticache'].OutputValue" \
--output text`
echo $subnetSingapore
export orderDdbArn=`aws dynamodb describe-table --table-name bookstore-Orders \
--region ap-southeast-1 \
--query 'Table.LatestStreamArn'`
echo $orderDdbArn
export cognitoIrelandPool=`aws cloudformation describe-stacks --stack-name MyBookstoreIreland \
--region eu-west-1 \
--query "Stacks[0].Outputs[?OutputKey=='UserPool'].OutputValue" \
--output text`
echo $cognitoIrelandPool
- Let's create the ReactJS app with this aws command via AWS cloudformation:
aws cloudformation create-stack --stack-name MyBookstoreSingapore \
--template-url https://arc309-bookstore-ap-southeast-1.s3-ap-southeast-1.amazonaws.com/arc309_secondary.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--parameters ParameterKey=ProjectName,ParameterValue=bookstore \
ParameterKey=AssetsBucketName,ParameterValue=arc309-singapore-$MYSUBDOMAIN-bookstore \
ParameterKey=bookstoreVPC,ParameterValue=$vpcSingapore \
ParameterKey=bookstoreSubnet1,ParameterValue=$subnetSingapore \
ParameterKey=OrderTableStreamARN,ParameterValue=$orderDdbArn \
ParameterKey=UserPool,ParameterValue=$cognitoIrelandPool
This CloudFormation template may take around 10 mins. You can proceed the next steps.
As we mentioned above, the replication of Aurora MySQL is optional configuration for the Bookstore Failover testing in the next module. Hence, you can skip it now if you have no time to configure.
Update Blog DB connection with Read Replica in Singapore (Optional)
You remember the Book Blog you created above had 503 Service Temporarily Unavailable
error due to the Fargate didn't connect to Aurora MySQL in Singapore
. You can find the endpoint of Read Replica in Singapore with the following commands:
aws rds describe-db-instances \
--db-instance-identifier arc309-replica-instance \
--region ap-southeast-1 \
--query "DBInstances[0].Endpoint.Address" --output text
Go to ECS
in Singapore region, select WordpressSecondarywordpresssvcTaskDefXXXXXXXX
task in Task Definition
, and click Create new revision
.
Select web
container and update WORDPRESS_DB_HOST
with the above Aurora Read Replica endpoint. Click Update
.
It goes back to Create new revision of Task Definition
screen. Please scroll down and click Create
button.
And we need to update the password in AWS Secrets Manager in Singapore to connect the Aurora Read Replica in Singapore.
The following command will update the Secrets Manager wordpressDBPassword
in Singapore to the same value as the wordpressDBPassword
in Ireland:
AWS_ACCOUNTID=$(aws sts get-caller-identity --query Account --output text)
aws secretsmanager update-secret \
--secret-id arn:aws:secretsmanager:ap-southeast-1:$AWS_ACCOUNTID:secret:wordpressDBPassword \
--secret-string \
$(aws secretsmanager get-secret-value \
--secret-id arn:aws:secretsmanager:eu-west-1:$AWS_ACCOUNTID:secret:wordpressDBPassword \
--region eu-west-1 \
--query "SecretString" --output text) \
--region ap-southeast-1
- Go to
ECS
inSingapore
Region, select the clusterWordpress-Secondary-ecscluster6XXXXXXX
- Select the
Wordpress-Secondary-wordpresssvcSXXXXX
service and clickUpdate
, make sure the latest task definition is selected. - Click
Next
3 times and finallyUpdate Service
.
Your blog in the secondary region is now configured, it will be in Read-only mode as it is connected to the read-replica of our Aurora RDS cluster in Singapore.
Find your code repo in CodeCommit
and edit wordpressconfig.ts
(under bookstore-WebAssets/src/wordpressconfig.ts) in Ireland
region with your own domain name.
Update http://<FQDN of your Wordpress Application Load Balancer>
to
export default {
wordpress: {
WPURL: 'https://blog.<your subdomain>.multi-region.xyz'
}
};
Enter any Author name
and Email address
, and click Commit changes
. You can check the progress in CodePipeline and CodeBuild.
Origin Failover of CloudFront distributions improves the availability of content delivered to end users. However, this is an optional configuration for the Bookstore Failover testing in the next module. Hence, you can skip it now if you have no time to configure.
Create CloudFront Origin Group (Optional)
With CloudFront’s Origin Failover capability, your content is served from your secondary origin (Singapore) if CloudFront detects that your primary origin (Ireland) is unavailable.
Click your CloudFront Distributions, and click on the "Origins and Origin Groups" tab.
Create the second origin (in Singapore).
Type your Orgin Domain Name
with <your Singapore S3 bucket name>.s3-ap-southeast-1.amazonaws.com
and select the options like the following.
Next, create an origin group. CloudFront automatically switches to the secondary origin when the primary origin returns specific HTTP status code failure responses.
Congratulations! You have successfully deployed Bookstore applications in Ireland and Singapore. In the next module you will configure active/active solution using Route53.
Module 3: Configure Active-Active Route53