Skip to content

Instantly share code, notes, and snippets.

@alanzhaonys
Last active September 8, 2021 15:35
Show Gist options
  • Save alanzhaonys/aa749751885e1639c998dffaa5659355 to your computer and use it in GitHub Desktop.
Save alanzhaonys/aa749751885e1639c998dffaa5659355 to your computer and use it in GitHub Desktop.
Create a new AWS Account
1. Gmail account
2. Create AWS account
3. Create nac.fpmstaging.com NS records on the subaccount
3. Add NS records to the main account under nac.fpmstaging.com
4. Create a SSL cert for nac.fpmstaging.com
5. Create an IAM role `lambda-execute-role-cloudfront-basic-auth`
AWSLambdaExecute permission
Role need to have TrustedPolicy below(under Trust Relationships tab)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"edgelambda.amazonaws.com",
"lambda.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
6. Create a fpm-codebuild-role with following access
- CloudFront
- CloudWatch
- CodeBuild
- S3
7. Create a DevOps role with
- Admin access
- A trusted policy below, description "Allow root DevOps user to assume this role"
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ROOT-ACCOUNT-ID:user/DevOps"
},
"Action": "sts:AssumeRole"
}
]
}
8. Go back to root account, find DevOps user
- The user should have admin access
- The user should have a managed policy name "DevOpsTrustedPolicy", policy below:
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::NEW-ACCOUNT-ID:role/DevOpsRole"
}
}
To create a S3 website with basic auth
=====
1. Create a S3 bucket name matches: project.nac.fpmstaging.com
2. Create a CloudFront distrubtion
a. Use S3 bucket URL as origin
b. Restrict Bucket Access
- Yes use OAI (bucket can restrict access to only CloudFront
- And Yes on update S3 policy
c. Update Bucket permission
d. Configure to use custom SSL
e. add project.nac.fpmstaging.com as alternative domain name
3. Create a lambda function `fpm-basic-auth` with code below
exports.handler = (event, context, callback) => {
// Get the request and its headers
const request = event.Records[0].cf.request;
const headers = request.headers;
// Specify the username and password to be used
const user = 'fingerpaint';
const pw = 'fingerpaint';
// Build a Basic Authentication string
const authString = 'Basic ' + new Buffer(user + ':' + pw).toString('base64');
// Challenge for auth if auth credentials are absent or incorrect
if (typeof headers.authorization == 'undefined' || headers.authorization[0].value != authString) {
const response = {
status: '401',
statusDescription: 'Unauthorized',
body: 'Unauthorized',
headers: {
'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
},
};
callback(null, response);
}
// User has authenticated
callback(null, request);
};
4. In the upper menu, select Actions -> Deploy to Lambda@Edge.
In the modal that appears select the CloudFront distribution you created earlier from the drop down menu,
Cache Behavior: *,
CloudFront Event: Viewer Request"
Select: Include Body
Select :Confirm deploy to Lambda@Edge
Click "Deploy".
(to delete this lambda function, you must unassociate the function from Cloudfront distbution -> behavior -> Edit, you might have to wait a while before you can delete)
5. Create a A record(alias) in Route53 to point to distribution in CloudFront.
To configure index.html redirect for S3 bucket websites(useful for S3 non-static website)
====
1. Create a new lambda function below:
'use strict';
exports.handler = (event, context, callback) => {
// Extract the request from the CloudFront event that is sent to Lambda@Edge
var request = event.Records[0].cf.request;
// Extract the URI from the request
var olduri = request.uri;
// Match any '/' that occurs at the end of a URI. Replace it with a default index
var newuri = olduri.replace(/\/$/, '\/index.html');
// Log the URI as received by CloudFront and the new URI to be used to fetch from origin
console.log("Old URI: " + olduri);
console.log("New URI: " + newuri);
// Replace the received URI with the URI that includes the index page
request.uri = newuri;
// Return to CloudFront
return callback(null, request);
};
2. Deploy to lambda edge like the basic auth method
3. Configure CloudFront -> Behavior -> Function association -> Origin Request -> Lambda@Edge -> Enter the function ARN and version (not Include Body)
To create a public production site
====
1. Create a S3 bucket, make sure bucket has public access, name matches: project.nac.fpmstaging.com
2. Add permission below
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/*"
}
]
}
3. Configure S3 bucket to host static website
4. Create CloudFront distribution
a. Use stastic website URL as origin
b. Configure to use custom SSL
c. add project.nac.fpmstaging.com as alternative domain name
See BMS account for examples
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment