A simple golang HelloWorld app with an accompanying Jenkins pipeline to build, test and deploy to AWS Lambda automatically on pull requests/branching, as well as Terraform templates to setup infrastructure.
Before we begin, you will need:
- An AWS account
- A Jenkins server.
- This guide can help set one up: https://d1.awsstatic.com/Projects/P5505030/aws-project_Jenkins-build-server.pdf. Remember to set security groups accordingly so you can access the machine; also setup a reasonable password and install any patches.
- (you can also spin up a docker container with:
docker run -d -p 8080:8080 -p 50000:50000 jenkins/jenkins
, if you prefer)
- You'll need to install the golang plugin so you have all the necessary build tools for go
- Manage Jenkins > Manage Plugins > Available > Go
- You'll need AWS keys, I set mine as environment variables
- Manage Jenkins > Configure System > Global Properties > Environment Variables > add AWS_ACCESS_KEY_ID/AWS_DEFAULT_REGION/AWS_SECRET_ACCESS_KEY
- The pipeline is set to run on Jenkins slave, but if you're lazy like me and don't want to setup Jenkins slaves, on your master head to Jenkins > Configure System > Labels > add 'slaves'
Now we've configured Jenkins, we can setup our project and point to our repo.
- Jenkins > New Item > Multibranch Pipeline
- Branch Sources > GitHub
- Credentials > Add > Username/PAT token
- Owner > jimmyjamesbaldwin
- Repository > GolangLambdaPipeline
- Behaviours
- Discover branches
- Strategy: Exclude branches that are also filed as PRs
- Discover branches
- Build Configuration
- Mode: by Jenkinsfile
- Script Path > Jenkinsfile
- Mode: by Jenkinsfile
- Branch Sources > GitHub
To make Jenkins build automatically when code is pushed to the repo, head to GitHub > Settings > Webhooks > Payload Url: http://jenkins_user:password@<dns_alias_of_jenkins_ec2_host> (in the real world don't authenticate like this...)
Afterwards you'll see any development branches appear and attempt to build:
Terraform needs some source to create the Lambda function, so run these commands to build the Go app:
git clone <repo>
cd repo/src
GOOS=linux go build -o main main.go
zip lambda.zip main && mv lambda.zip ../terraform/
Under repo/vars.tf, set your preferred s3 bucket name, and put the same at the top of your Jenkinsfile:
vars.tf
variable "bucket" {
default = "my_awesome_bucket"
}
Jenkinsfile
def bucket = 'my_awesome_bucket'
Under terraform/vars.tf, set your preferred s3 bucket name and put the same at the top of your Jenkinsfile.
A note on the terraform templates: I'm using a access/secret key attached to an IAM user that has the AdministratorAccess policy attached to it. Not great for security but useful for testing. Ideally IAM should roles should be configured properly but this is just a POC.
# download terraform binary...
cd repo/terraform
./terraform init
./terraform apply
When merging PR's, you should see a build kick off and update the lambda function:
If merging to master, you can see the production version alias on the lambda gets updated: