Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomfun/e097b81866068daf58cb2755046fc75f to your computer and use it in GitHub Desktop.
Save tomfun/e097b81866068daf58cb2755046fc75f to your computer and use it in GitHub Desktop.
Cloudformation template for AWS S3 Bucket, CloudFront, private access for static hosting of angular frontend project (with client side routing). Every 403 request replies with index.html. For some reason it takes a lot of time after end to start work well
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters" : {
"MainDomainName": {
"Description": "public pretty FQDN for cloudfront",
"Type": "String",
"Default": "example.com"
},
"AcmCertificateArn": {
"Description": "AWS certificate ID for cloudfront",
"Default": "arn:aws:acm:us-east-1:2xxxxxxxxx44:certificate/0aaeba7b-7edb-4d9e-8abb-yyyyyyyyy351",
"Type": "String"
}
},
"Resources": {
"staticWebBucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"AccessControl": "Private",
"VersioningConfiguration": {
"Status": "Suspended"
}
}
},
"staticWebCloudFrontNetAccessIdentity": {
"Type": "AWS::CloudFront::CloudFrontOriginAccessIdentity",
"Properties": {
"CloudFrontOriginAccessIdentityConfig": {
"Comment": {
"Fn::Join": [
"",
[
"https://",
{ "Ref" : "MainDomainName" },
"/ access-identity-",
{
"Fn::GetAtt": [
"staticWebBucket",
"DomainName"
]
}
]
]
}
}
}
},
"staticWebCloudFrontDistribution": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"Aliases": [
{ "Ref" : "MainDomainName" }
],
"Enabled": true,
"PriceClass": "PriceClass_All",
"CustomErrorResponses": [
{
"ErrorCachingMinTTL": 300,
"ErrorCode": 403,
"ResponseCode": "404",
"ResponsePagePath": "/index.html"
}
],
"DefaultCacheBehavior": {
"TargetOriginId": {
"Fn::Join": [
"-",
[
"S3",
{
"Ref": "staticWebBucket"
}
]
]
},
"ViewerProtocolPolicy": "redirect-to-https",
"MinTTL": 0,
"AllowedMethods": [
"HEAD",
"GET"
],
"CachedMethods": [
"HEAD",
"GET"
],
"ForwardedValues": {
"Cookies": {
"Forward": "none"
},
"QueryString": false
}
},
"Origins": [
{
"Id": {
"Fn::Join": [
"-",
[
"S3",
{
"Ref": "staticWebBucket"
}
]
]
},
"DomainName": {
"Fn::GetAtt": [
"staticWebBucket",
"DomainName"
]
},
"S3OriginConfig": {
"OriginAccessIdentity": {
"Fn::Join": [
"",
[
"origin-access-identity/cloudfront/",
{
"Ref": "staticWebCloudFrontNetAccessIdentity"
}
]
]
}
}
}
],
"Restrictions": {
"GeoRestriction": {
"RestrictionType": "none",
"Locations": [
]
}
},
"ViewerCertificate": {
"SslSupportMethod": "sni-only",
"AcmCertificateArn" : {
"Ref": "AcmCertificateArn"
},
"MinimumProtocolVersion": "TLSv1.2_2018"
}
}
}
},
"staticWebBucketPolicy": {
"Type": "AWS::S3::BucketPolicy",
"Properties": {
"Bucket": {
"Ref": "staticWebBucket"
},
"PolicyDocument": {
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"CanonicalUser": {
"Fn::GetAtt": [
"staticWebCloudFrontNetAccessIdentity",
"S3CanonicalUserId"
]
}
},
"Action": "s3:GetObject",
"Resource": {
"Fn::Join": [
"",
[
"arn:aws:s3:::",
{
"Ref": "staticWebBucket"
},
"/*"
]
]
}
}
]
}
}
}
},
"Outputs": {
"WebsiteUglyURL": {
"Value": {
"Fn::GetAtt": [
"staticWebCloudFrontDistribution",
"DomainName"
]
},
"Description": "URL for website hosted on S3"
},
"CloudfrontDistributionId": {
"Value": {
"Ref": "staticWebCloudFrontDistribution"
},
"Description": "URL for website hosted on S3"
},
"staticWebBucketSecureURL": {
"Value": {
"Fn::Join": [
"",
[
"https://",
{
"Fn::GetAtt": [
"staticWebBucket",
"DomainName"
]
}
]
]
},
"Description": "Name of S3 bucket to hold website content"
},
"staticWebBucketName": {
"Value": {
"Ref": "staticWebBucket"
},
"Description": "Name of S3 bucket to hold website content"
}
},
"Description": "S3 Bucket, CloudFront, private access for static hosting for frontend project"
}
@tomfun
Copy link
Author

tomfun commented Oct 24, 2019

Some ugly peace of .gitlab-ci.yml

variables:
    CI_REGISTRY_IMAGE_WD: /home/node/app
    CI_REGISTRY_IMAGE_c: $CI_REGISTRY_IMAGE/dev:${CI_COMMIT_SHORT_SHA}
    CI_REGISTRY_IMAGE_l: $CI_REGISTRY_IMAGE/dev:latest
    CI_REGISTRY_IMAGE_WAITFORIT: $CI_REGISTRY_IMAGE/waitfoit:latest
    CI_REGISTRY_IMAGE_NODE_MODULES: $CI_REGISTRY_IMAGE/node_modules:latest
    CI_REGISTRY_IMAGE_i: static-web-app_${CI_BUILD_ID}_app

build-dev:
    tags:
        - dind
    stage: build
    image: tmaier/docker-compose
    script:
        - |
            docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
        - time docker build --target=waitforit --cache-from ${CI_REGISTRY_IMAGE_WAITFORIT} -f docker/app-dev/Dockerfile -t ${CI_REGISTRY_IMAGE_WAITFORIT} .
        - time docker build --target=node_modules --cache-from ${CI_REGISTRY_IMAGE_WAITFORIT} --cache-from ${CI_REGISTRY_IMAGE_NODE_MODULES} -f docker/app-dev/Dockerfile -t ${CI_REGISTRY_IMAGE_NODE_MODULES} .
        - time docker build --cache-from ${CI_REGISTRY_IMAGE_WAITFORIT} --cache-from ${CI_REGISTRY_IMAGE_NODE_MODULES} --cache-from ${CI_REGISTRY_IMAGE_l} -f docker/app-dev/Dockerfile -t ${CI_REGISTRY_IMAGE_c} -t ${CI_REGISTRY_IMAGE_l} .
        - time docker push ${CI_REGISTRY_IMAGE_c}

.x-job-deploy: &x-job-deploy
    tags:
        - dind
    stage: deploy
    when: manual
    image: tmaier/docker-compose
    script:
        - aws_docker_args=" -e AWS_REGION -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY gitlab.paydock.com:4567/envoyrecharge/docker-aws-deploy aws"
        - aws="docker run --rm $aws_docker_args"
        - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
        - time docker pull ${CI_REGISTRY_IMAGE_c}
        - BUILD_C_ID="build-pos-artifacts-${CI_BUILD_ID}"
        - docker run --name=${BUILD_C_ID} ${CI_REGISTRY_IMAGE_c} npm --loglevel warn --color=always run build -- --prod=true --configuration=${CI_ENVIRONMENT_SLUG}
        - docker cp ${BUILD_C_ID}:${CI_REGISTRY_IMAGE_WD}/dist ./
        - docker rm ${BUILD_C_ID}
        - DEPLOY_C_ID="deploy-pos-artifacts-${CI_BUILD_ID}"
        - docker create --name=${DEPLOY_C_ID} $aws_docker_args s3 cp /aws/root s3://${S3_BUCKET}/ --recursive
        - docker cp ./dist/static-web-app/ ${DEPLOY_C_ID}:/aws/root
        - docker start --attach ${DEPLOY_C_ID}
        - docker rm ${DEPLOY_C_ID}
        - $aws cloudfront create-invalidation --distribution-id ${CLOUDFRONT_DISTRIBUTION_ID} --paths "/*"

deploy_production:
    <<: *x-job-deploy
    variables:
        GIT_STRATEGY: none
        AWS_REGION: "eu-central-1"
        AWS_ACCESS_KEY_ID: ${PRODUCTION_AWS_ACCESS_KEY_ID}
        AWS_SECRET_ACCESS_KEY: ${PRODUCTION_AWS_SECRET_ACCESS_KEY}
        CLOUDFRONT_DISTRIBUTION_ID: "E2XLWGP4OHEA6N"
        S3_BUCKET: static-app-prod-staticWebBucket-1d4fsjugv51ej
    environment:
        name: production
        url: https://web.example.com/
    when: manual
    only:
        - master
        - /^RC-.*$/
        - tags

deploy_staging:
    <<: *x-job-deploy
    variables:
        GIT_STRATEGY: none
        AWS_REGION: "ap-southeast-2"
        AWS_ACCESS_KEY_ID: ${STAGING_AWS_ACCESS_KEY_ID}
        AWS_SECRET_ACCESS_KEY: ${STAGING_AWS_SECRET_ACCESS_KEY}
        CLOUDFRONT_DISTRIBUTION_ID: "EOMO6BOVDBN0O"
        S3_BUCKET: static-app-staging-staticWebBucket-1d4fsjugv51ej
    environment:
        name: staging
        url: https://web.staging.example.com/

@tomfun
Copy link
Author

tomfun commented Oct 24, 2019

It is ok to see first time error:
curl https://auth.paydock.com/index.html

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>TemporaryRedirect</Code><Message>Please re-send this request to the specified temporary endpoint. Continue to use the original request endpoint for future requests.</Message><Endpoint>static-app-staging-staticWebBucket-1d4fsjugv51ej.s3-ap-southeast-2.amazonaws.com</Endpoint><Bucket>static-app-staging-staticWebBucket-1d4fsjugv51ej</Bucket><RequestId>4D197C8F5004BFFB</RequestId><HostId>NmNBkclXy+Alqth8PTAcbllsXFnBEkrORLliZdRywC0DAqLjR5m48Fd4M3MTY+KrFXjs8nG7r1w=</HostId></Error>

But after some time it works well. Do not forget to place index.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment