Minimum Viable Release Notifications with AWS
How a small project team can notify stakeholders of new releases, with minimal effort.
I can still recall working in a 10 person software team.
Every release was meticulously planned and could not fail. Hence, the developers often feared screwing it up. There was a big SOP we had to follow.
One of the items was to send an email after a new version was live.
This email was triple-checked, because it went out to the CEO. And yet, it was often done wrong. Typos and wrong version numbers often happened.
This took a lot of brain power from the developers.
Can we automate this?
Our mission in making Cliptill is to document the process. We apply management in public
, meaning we show all the surrounding activities in order to bring a new project online.
For releases, we want to have the simplest solution possible.
This is what we need:
- Release notifications are sent via email.
- Automatic triggers after versions being deployed
- We use AWS Lambda, no hosting required.
Just simple solution can be set up in 2-4 hours. It cost almost nothing to host, and almost doesn’t need maintenanance.
The end result
After every deploy we get emails like this:
This is an email whenvere we deploy on our preview system. We only send this to the dev team.
This is the email that goes out to other stakeholders and the marketing team.
I am working on a YouTube video with better explanations. You can also ask your developer to use this post as a starting point. I’m adding the code snippets below.
Hopefully this helps a couple of people get better with their release management.
How did your last project team run releases? Please leave a comment on linkedin or Youtube!
Till
P.S. I’m not certified in AWS. This is a minimal thing that works for us, and we are probably violating some best practices. Especially secret management and authentication is not done perfect. I’m posting this anyway and will make a v2 once I get feedback from AWS devs. Thanks!
Implementation
AWS Lambda
Copy this into a lambda function. You also need an authenticated email domain in Simple Email Service.
import json
import boto3
import os
import logging
# Initialize logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
try:
logger.info("---------------------------------")
logger.info(f"Received event: {event}")
# Parse the JSON body from the event
body = event.get('body', '{}')
if isinstance(body, str):
body = json.loads(body)
# Validate the token
if os.environ.get('SECRET_TOKEN') != body.get('token'):
raise ValueError("Invalid token")
# Extract appname, version and tag
appname = body.get('appname', 'Unknown App')
version = body.get('version', 'Unknown Version')
tag = body.get('tag')
display_version = tag if tag else (version[:7] if version and len(version) > 7 else version)
# Build email body from key-value pairs, excluding appname and version
email_body = "Deployment Details:\n\n"
for key, value in body.items():
if key not in ['appname', 'version', 'token', 'recipients']:
email_body += f"{key}: {value}\n"
recipients_str = body.get('recipients', '')
# Convert recipients string to a list
if recipients_str and isinstance(recipients_str, str):
recipients = recipients_str.split(',')
else:
raise ValueError("No valid recipients given")
logger.info(f"New version of {appname} released: {recipients}")
ses_client = boto3.client('ses')
response = ses_client.send_email(
Source=os.environ.get('NOTIFIER_EMAIL'),
Destination={'ToAddresses': recipients},
Message={
'Subject': {'Data': f'Version {display_version} of {appname} deployed.'},
'Body': {'Text': {'Data': email_body}}
}
)
return {
'statusCode': 200,
'body': json.dumps('Email sent successfully!')
}
except Exception as e:
logger.error(f"Got exception: {e}")
return {
'statusCode': 500,
'body': json.dumps(f'Error: {str(e)}')
}
The Lambda also needs environment variables
# Make sure to change this. Else someone could use your endpoint to spam people.
NOTIFIER_EMAIL=[email protected]
SECRET_TOKEN=12345678
Add a policy
Make a policy to give the lambda function access to SES
Choose any name, like AuthorizeSESPairingDeployNotifier
Make sure to replace the “Resource” section with your SES email, and adjust the email address accordingly.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendTemplatedEmail",
"ses:SendRawEmail"
],
"Resource": "arn:aws:ses:us-east-1:151345295272518:identity/pairing.dev",
"Condition": {
"StringEquals": {
"ses:FromAddress": "[email protected]"
}
}
}
]
}
Finally test it in Insomnia.
Once it works, add this to your pipeline.
Gitlab CI
Copy this into your .gitlab-ci.yml
:
notify_deployed_version:
stage: deploy
script:
- apk add --no-cache curl
- COMMIT_MESSAGE=$(echo "$CI_COMMIT_MESSAGE" | sed 's/"/\"/g' | tr -d '\n')
- PIPELINE_URL=$(echo "$CI_PIPELINE_URL" | sed 's/"/\"/g')
- >
curl -X POST $DEPLOY_NOTIFICATION_ENDPOINT
-H "Content-Type: application/json"
-d '{
"token": "'"${DEPLOY_NOTIFICATION_TOKEN}"'",
"appname": "'"${CI_PROJECT_NAME}"'",
"version": "'$CI_COMMIT_SHA'",
"message": "'"${COMMIT_MESSAGE}"'",
"pipeline_url": "'"${PIPELINE_URL}"'",
"deployment_time": "'"$(date -u)"'",
"author": "'"${CI_COMMIT_AUTHOR}"'",
"branch_name": "'"${CI_COMMIT_REF_NAME}"'",
"environment_name": "'"${CI_ENVIRONMENT_NAME}"'",
"recipients": "'$DEPLOY_NOTIFICATION_RECIPIENTS'"
}'
dependencies:
- deploy_production
And set these environment variables:
DEPLOY_NOTIFICATION_RECIPIENTS=[email protected],[email protected]
DEPLOY_NOTIFICATION_TOKEN=12345678
DEPLOY_NOTIFICATION_ENDPOINT=https://dl52656d2g24whatever.execute-api.us-east-1.amazonaws.com/default/deploy-notifications