Deploy a hugo site automatically with AWS Lambda.
This is a packaged AWS Lambda function that will watch an S3 'inputBucket' for changes to a Hugo site. It will then run hugo within Lambda, and publish the results to a seperate, public S3 bucket.
This public S3 bucket will be enabled for static website hosting.
Bonus fun! Point a cloudfront instance at your static website hosting bucket to quickly and easily deploy your Hugo site with the AWS CDN.
Once set up, updating your Hugo website with this infrastructure is as simple as running an S3 sync command. e.g.
aws s3 sync --delete /home/user/hugoSite/ s3://input.yourwebsite.com/hugo
- Input bucket should be named 'input.yourwebsite.com'
- Store/sync your raw hugo files to s3://input.yourwebsite.com/hugo
- Website bucket should be named 'yourwebsite.com'
- Create a redirect website bucket for 'www.yourwebsite.com' if needed
You should create a role for running this Lambda function. Give it the following two policies:
- AWSLambdaBasicExecutionRole
- Create Inline policy with the following access:-
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": [
"arn:aws:s3:::*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::input.yourwebsite.com"
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::input.yourwebsite.com/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::yourwebsite.com"
]
},
{
"Effect": "Allow",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject",
"s3:GetObjectAcl",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::yourwebsite.com/*"
]
}
]
}
- Create a new lambda function
- Upload package.zip
- Set handler as 'lambda_function.lambda_handler'
- Add S3 triggers for 'ObjectCreated' & 'ObjectRemoved' against your input bucket
- Configure lambda function to use the IAM role above
- 60 Second timeout
- Runtime = python3.6
package.zip contains the hugo executable, the AWS CLI program and lambda_function.py as well as the usual python libraries.
You can recreate this package with the following:
- Spin up an EC2 Amazon Linux instance
- Install python3.6
wget https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tar.xz
tar xJf Python-3.6.0.tar.xz
cd Python-3.6.0 && ./configure && make && sudo make install
- Create virtualenv for Python 3.6
sudo pip install --upgrade virtualenv
virtualenv -p python3 MYVENV
source MYVENV/bin/activate
- Download & extract Hugo's Linux x64 package
wget https://github.com/gohugoio/hugo/releases/download/v0.37.1/hugo_0.37.1_Linux-64bit.tar.gz
tar xfvz hugo_0.37.1_Linux-64bit.tar.gz
mv hugo ~
- Install AWS CLI
pip install awscli
cp ~/MYVENV/bin/aws ~
cd ~
- Modify AWS CLI shebang to play nice on Lambda
perl -pi -e '$_ = "#!/usr/bin/python\n" if $. == 1' aws
- Create deployment package .zip file
zip -g package.zip hugo
zip -g package.zip aws
zip -g package.zip lambda_function.py
cd $VIRTUAL_ENV/lib/python3.6/site-packages
zip -r9 ~/package.zip *
Big thanks to the following resources:
- https://alestic.com/2016/11/aws-lambda-awscli/
- https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html
- http://bezdelev.com/post/hugo-aws-lambda-static-website/
- https://medium.com/@bezdelev/how-to-test-a-python-aws-lambda-function-locally-with-pycharm-run-configurations-6de8efc4b206