Close

Deploy AWS CloudWatch alarms with GitHub

Warren Marusiak headshot
Warren Marusiak

Senior Technical Evangelist

To demonstrate how to develop, deploy, and manage applications using Jira Software and various connected tools, our team created ImageLabeller, a simple demo application built on AWS that uses machine learning to apply labels to images.

This page covers how to setup an AWS SageMaker predefined model, a prerequisite for ImageLabeller to successfully process images. Before you begin, we recommend reading the ImageLabeller architecture and Deploy ImageLabeller with GitHub pages for context.


Add an alarms repository for Opsgenie integration

Go to Jira and create a new Jira issue for adding AWS CloudWatch alarms repository to GitHub. In this example the Jira issue ID is IM-10.

screenshot of jira issue to add github repository

Go to GitHub and click New. Choose the appropriate organization for Owner. Click Create repository to proceed.

screenshot of creating alarms repository in github

Click Settings, then Secrets. Add your AWS access key id as AWS_ACCESS_KEY_ID, and your AWS secret access key as AWS_SECRET_ACCESS_KEY.

screenshot of adding aws access keys in github

In your terminal go to your CloudWatchAlarms repository, and run the following to push your AWS CloudFormation code to GitHub.

git add --all
git commit -m "IM-10 add CloudWatchAlarms to github"
git remote add origin git@github.com:PmmQuickStartGuides01/CloudWatchAlarms.git
git branch -m mainline
git push -u origin mainline

Alarms template.yml

Description: 'A description'

Resources:
  OpsGenieSNS:
    Type: AWS::SNS::Topic
    Properties: 
      DisplayName: 'Opsgenie'
      Subscription:
        - Endpoint: 'https://api.opsgenie.com/v1/json/cloudwatch?apiKey=a4449509-6998-4d55-841d-2e6b363520c7'
          Protocol: 'HTTPS'
      TopicName: 'Opsgenie'

  SubmitImageLambdaAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties: 
      AlarmActions:
        - !Ref 'OpsGenieSNS'
      AlarmDescription: 'SubmitImage Too Many Invocations'
      ComparisonOperator: 'GreaterThanThreshold'
      Dimensions:
        - Name: FunctionName
          Value: !ImportValue 'SubmitImageFunctionName'
      EvaluationPeriods: 1
      MetricName: 'Invocations'
      Namespace: 'AWS/Lambda'
      Period: 60
      Statistic: 'Sum'
      Threshold: 10

Set the SNS topic subscription endpoint to the endpoint URL you copied from Opsgenie. The SubmitImageLambdaAlarm monitors a single metric emitted by the submitImage AWS Lambda. If there are more than 10 invocations in a minute the alarm is raised.

GitHub actions for deploying to AWS

Go to your CloudWatchAlarms repository in your terminal, create a branch named after your Jira issue ID, and create a .github/workflows directory.

git checkout -b IM-10
mkdir -p .github/workflows && cd .github/workflows

Create deploy-test-staging.yml with the following yaml. This defines a deployment workflow for your Test, and Staging environments that runs during pushes to branches other than mainline.

name: deploy-cloudwatchalarms-test-staging
on:
  push:
    branches:
      - '*'
      - '!mainline'

jobs:
  deploy-us-west-1:
    runs-on: ubuntu-latest
    outputs:
      env-name: ${{ steps.env-name.outputs.environment }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Configure AWS credentials
        id: creds
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: "us-west-1"
      - name: Deploy to AWS CloudFormation
        uses: aws-actions/aws-cloudformation-github-deploy@v1
        with:
          name: OpenDevOpsAlarms
          template: template.yml
          no-fail-on-empty-changeset: "1"

  deploy-us-east-2:
    runs-on: ubuntu-latest
    needs: deploy-us-west-1
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Configure AWS credentials
        id: creds
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: "us-east-2"
      - name: Deploy to AWS CloudFormation
        uses: aws-actions/aws-cloudformation-github-deploy@v1
        with:
          name: OpenDevOpsAlarms
          template: template.yml
          no-fail-on-empty-changeset: "1"

Then create deploy-prod.yml with the following yaml. This defines a deployment workflow for your Production environments that runs when a pull request merges changes into mainline.

name: deploy-cloudwatchalarms-prod
on:
  pull_request:
    branches:
      - mainline

jobs:
  deploy-us-west-2:
    runs-on: ubuntu-latest
    outputs:
      env-name: ${{ steps.env-name.outputs.environment }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Configure AWS credentials
        id: creds
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: "us-west-2"
      - name: Deploy to AWS CloudFormation
        uses: aws-actions/aws-cloudformation-github-deploy@v1
        with:
          name: OpenDevOpsAlarms
          template: template.yml
          no-fail-on-empty-changeset: "1"

  deploy-ca-central-1:
    runs-on: ubuntu-latest
    needs: deploy-us-west-2
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Configure AWS credentials
        id: creds
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: "ca-central-1"
      - name: Deploy to AWS CloudFormation
        uses: aws-actions/aws-cloudformation-github-deploy@v1
        with:
          name: OpenDevOpsAlarms
          template: template.yml
          no-fail-on-empty-changeset: "1"

  deploy-us-east-1:
    runs-on: ubuntu-latest
    needs: deploy-ca-central-1
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Configure AWS credentials
        id: creds
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: "us-east-1"
      - name: Deploy to AWS CloudFormation
        uses: aws-actions/aws-cloudformation-github-deploy@v1
        with:
          name: OpenDevOpsAlarms
          template: template.yml
          no-fail-on-empty-changeset: "1"

Pushing to a feature branch

From the command line run the following to push your code to the IM-10 branch of your CloudWatchAlarms repository.

git add --all
git commit -m "IM-10 add github actions to CloudWatchAlarms"
git push -u origin IM-10

Click Actions to see running workflows.

screenshot of running workflows in github

Create a pull request

Click Create pull request to merge into mainline.

screenshot of creating pull request in github

Click Actions to monitor the Production deployment.

screenshot of production deployment in github

Testing the Alarm

Generate an alert by triggering the AWS CloudWatch alarm you just set up, or by clicking Create alert.

screenshot of creating alert in opsgenie

Check Slack to see that the notification appeared.

screenshot of slack notification in opsgenie

Bravo! You did it. ImageLabeller is now up and running.

Warren Marusiak
Warren Marusiak

Warren is a Canadian developer from Vancouver, BC with over 10 years of experience. He came to Atlassian from AWS in January of 2021.


Share this article

Recommended reading

Bookmark these resources to learn about types of DevOps teams, or for ongoing updates about DevOps at Atlassian.

Devops illustration

DevOps community

Devops illustration

DevOps learning path

Map illustration

Get started for free

Sign up for our DevOps newsletter

Thank you for signing up