
One day I decided to create a backup of all mydev.to
posts. Programmers are lazy, so I wanted to do as little work as possible, and wanted the final result to look as nice as possible (or at least nicer than Markdown reader on GitHub).
Final requirements for the project were the following:
- Fully static (cheap/free to host)
- Markdown support (copy and paste existing material)
- Continuous deployment (automation is good)
- Easy to maintain (easy is good)
Based on the requirements, I decided on this simple workflow:
- The website is build withHugo
- The source code is stored inBitBucket
- The deployment is done viaCircleCi
- The website is deployed and hosted inAWS S3
- The AWS resources are managed byTerraform
Step 1: Generate a New Hugo Website
This step is straightforward, but also was the most time-consuming. I had to manually copy all of my posts into new Hugo project. If you are following my steps, Hugo has a greatGetting Started guide.
Step 2: Create the AWS Resources
I will be using Terraform to simplify this step. If you are not familiar with the tool, I have anintroductory level article to get you going. For more detailed introduction, refer toTerraform learning center. Also, you can alwayscreate resources by hand.
provider"aws"{version="~> 2.0"region="us-east-1"}variable"static_bucket_name"{type=stringdefault="aakatev-blog"}resource"aws_s3_bucket""static_bucket"{bucket=var.static_bucket_nameacl="public-read"force_destroy=truewebsite{index_document="index.html"}policy=<<-EOT { "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::${var.static_bucket_name}/*" ] } ] } EOT}resource"aws_iam_user""circle_ci_user"{name="circle-ci"}resource"aws_iam_access_key""circle_ci_access_key"{user=aws_iam_user.circle_ci_user.name}resource"aws_iam_user_policy""circle_ci_policy"{name="circle-ci-policy"user=aws_iam_user.circle_ci_user.namepolicy=<<-EOT { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:*", "Resource": [ "arn:aws:s3:::${var.static_bucket_name}", "arn:aws:s3:::${var.static_bucket_name}/*" ] } ] } EOT}output"circle_ci_access_key"{value=aws_iam_access_key.circle_ci_access_key.id}output"circle_ci_access_key_secret"{value=aws_iam_access_key.circle_ci_access_key.secret}
If everything went well, your output for this step should look like this:
Applycomplete! Resources: 4 added, 0 changed, 0 destroyed.Outputs:circle_ci_access_key= SOME_AWS_KEY_IDcircle_ci_access_key_secret= SOME_AWS_KEY_SECRET
These keys will need to be exported as environmental variables during CircleCI build.
Terraform will store the keys in itsstate as a plaintext. You are responsible for keeping their secrecy.
Step 3: Store the Source Code
I will be using BitBucket as my version control, but GitHub will do the trick too. AFAIK there are no differences in CircleCI integration with both.
Create a file.circleci/config.yml
with the following content:
version:2jobs:build:docker:-image:cibuilds/hugo:0.73working_directory:/home/circleci/hugoenvironment:HUGO_DIR:/home/circleci/hugoS3_BUCKET:aakatev-blogsteps:-checkout-run:git submodule sync && git submodule update --init-run:name:install AWS CLI (first install pip, the Python package manager)command:|sudo apt install python-pippip install awscli-run:HUGO_ENV=production hugo -v -s $HUGO_DIR-run:name:test our generated HTML filescommand:|htmlproofer $HUGO_DIR/public --allow-hash-href --check-html \--empty-alt-ignore --disable-external-deploy:name:deploy to AWScommand:|if [ "${CIRCLE_BRANCH}" = "master" ]; thenaws s3 sync $HUGO_DIR/public \s3://$S3_BUCKET/ --deleteelseecho "Not master branch, dry run only"fi
Step 4: Configure the CircleCI pipeline
Besidesconfig.yml
CircleCI needs access keys, in order to have administrator access to the S3 bucket. Visit yourProject Settings section:
For more information refer to CircleCI docs onenvironmental variables.
Step 5: Enjoy the Result
At this point, the website is available for public, and you can view minehere.
In case, you followed, and want to see yours, the pattern for S3 domains ishttp://<bucket_name>.s3-website-<region>-<zone>.amazonaws.com
.
Since my website is a backup, I didn't really care about domain name, nor some other features a real blog should have. That said, it would be a logical future additions to the project.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse