Containers

Controlling and monitoring AWS App Runner applications with Amazon EventBridge

Many applications do not need to be available 24/7, such as those in development and QA environments. AWS App Runner supports this and allows applications to be paused, or deactivated, to lower costs when not in use. The applications can then be resumed or activated when they are needed. This blog post uses this example use case to demonstrate how App Runner applications can be controlled and monitored using Amazon EventBridge.

AWS App Runner is a fully managed service that makes it easy for developers to quickly deploy containerized web applications and APIs at scale and with no prior infrastructure experience required. Amazon EventBridge allows you to create rules to schedule automated actions that self-trigger at certain times. It delivers a near real-time stream of system events that describe changes in Amazon Web Services (AWS) resources.

Solution overview

The following diagram shows the high-level architecture created in this blog post. It includes an App Runner service, an AWS Lambda function to pause and resume the App Runner service, EventBridge rules to automatically invoke the function on a set schedule, and an Amazon Simple Notification Service (Amazon SNS) topic and EventBridge rule to automatically send email notifications when a successful or failed pause or resume event is detected.

You’ll perform the following steps to build this solution:

  1. Deploy a sample App Runner service.
  2. Deploy a Lambda function and EventBridge rules to pause and resume the App Runner service.
  3. Deploy an Amazon SNS topic and EventBridge rule to send notification emails.

Prerequisites

Before you get started, make sure you have the following prerequisites:

  • An AWS account
  • Access to the AWS Management Console
  • Permissions to deploy CloudFormation stacks and create the resources in this post

Deploy a sample App Runner service

To get started, deploy an App Runner service using AWS CloudFormation. The CloudFormation template below pulls an example hello-app-runner application from an Amazon Elastic Container Registry (Amazon ECR) public repository and deploys it to an App Runner service.

Copy the following CloudFormation template to a text editor and save it to a file named app-runner-service.yaml.

AWSTemplateFormatVersion: '2010-09-09'
Description: >
  Sample AWS App Runner application called 'hello-app-runner'.

Resources:
  AppRunnerApplication:
    Type: 'AWS::AppRunner::Service'
    Properties:
      ServiceName: 'hello-app-runner'
      SourceConfiguration: 
        ImageRepository:
          ImageIdentifier: 'public.ecr.aws/aws-containers/hello-app-runner:latest'
          ImageConfiguration:
            Port: 8080
          ImageRepositoryType: 'ECR_PUBLIC'
  
Outputs:
  ServiceArn:
    Description: The ARN of the sample App Runner application
    Value: !GetAtt AppRunnerApplication.ServiceArn
  ServiceName:
    Description: The name of the sample App Runner application
    Value: 'hello-app-runner'
  ServiceUrl:
    Description: The URL of the sample App Runner application
    Value: !Sub 'https://${AppRunnerApplication.ServiceUrl}'

This template creates the following resources:

  • AWS App Runner service

Follow these steps to deploy a CloudFormation stack from the template:

  • Open the CloudFormation console in a Region that supports App Runner, for example, us-east-1.
  • Choose Create stack, then select With new resources (standard).
  • On the Create stack page, select Upload a template file.
  • Select Choose file and choose your app-runner-service.yaml template file. Select Next.
  • Provide a Stack name, for example, app-runner-service, and select Next.
  • Choose Next on the Configure stack options page.
  • Review the configuration options and choose Create stack. The stack deploys in approximately five minutes.
  • Verify that the stack has a status of CREATE_COMPLETE.
  • Choose Outputs.
  • Copy the ServiceArn value to a text editor for use in the next step.
  • Open the ServiceURL link in your web browser to verify that the hello-app-runner application is running.

Deploy a Lambda function and EventBridge rules to pause and resume the App Runner service

Next, set up automation to pause and resume your App Runner service on a set schedule. The CloudFormation template below deploys a Python Lambda function to pause and resume the service and EventBridge rules that will invoke the function at set times. It also creates a Lambda execution role (IAM role) to allow the function to pause and resume the App Runner service and Lambda permissions to allow the EventBridge rules to invoke the function.

EventBridge uses schedule expressions to schedule rules that trigger at set times. All EventBridge schedules are based on UTC time zone. This example defines schedule expressions to pause the App Runner service daily at 6pm UTC (cron(0 18 * * ? *)) and resume it daily at 8am UTC (cron(0 8 * * ? *)). The cron expressions are input as parameters in the CloudFormation template below and can be modified for your time zone. For example, EST time zone is five hours behind UTC (UTC-05:00). The cron expression for 6pm EST is cron(0 13 * * ? *) and the cron expression for 8am EST is cron(0 3 * * ? *). For more information on creating your own schedules, see Creating an Amazon EventBridge rule that runs on a schedule.

Copy the following CloudFormation template to a text editor and save it to a file named app-runner-pause-resume.yaml:

AWSTemplateFormatVersion: '2010-09-09'
Description: >
  AWS Lambda function and Amazon EventBridge rules to pause and resume an AWS App Runner 
  application on a set schedule.

Parameters:
  AppRunnerServiceArn:
    Type: String
    Description: The ARN of the App Runner service
  PauseSchedule:
    Type: String
    Default: 'cron(0 18 * * ? *)'
    Description: The schedule expression for pausing the sample App Runner application
    # For more information on scheduled expressions see: 
    # https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html
  ResumeSchedule:
    Type: String
    Default: 'cron(0 8 * * ? *)'
    Description: The schedule expression for resuming the sample App Runner application
    # For more information on scheduled expressions see: 
    # https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html

Resources:
  # AWS Lambda function to pause and resume the App Runner service
  LambdaFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      Runtime: 'python3.9'
      Role: !GetAtt LambdaExecutionRole.Arn
      Handler: 'index.handler'
      Code:
        ZipFile: |
          import boto3

          client = boto3.client('apprunner')

          def handler(event, context):
            service_arn = event['arn']
            action = event['action']
            if action == 'pause':
              print(f'Pausing App Runner Service: {service_arn}')
              response = client.pause_service(ServiceArn=service_arn)
            elif action == 'resume':
              print(f'Resuming App Runner Service: {service_arn}')
              response = client.resume_service(ServiceArn=service_arn)
  
  # AWS IAM role to allow the Lambda function to pause and resume the App Runner service and output logs to Amazon CloudWatch
  LambdaExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - 'lambda.amazonaws.com'
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns: 
        - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
      Policies:
        - PolicyName: 'PauseResumeAppRunnerPolicy'
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - 'apprunner:PauseService'
                  - 'apprunner:ResumeService'
                Resource: !Ref AppRunnerServiceArn
  
  # Amazon EventBridge rule to pause the App Runner service on a set schedule
  PauseEventBridgeRule:
    Type: 'AWS::Events::Rule'
    Properties:
      Description: 'Pauses sample App Runner service'
      ScheduleExpression: !Ref PauseSchedule
      State: 'ENABLED'
      Targets: 
        - Arn: !GetAtt LambdaFunction.Arn
          Id: '1'
          Input: !Sub '{"arn": "${AppRunnerServiceArn}","action": "pause"}'
      
  # Amazon EventBridge rule to resume the App Runner service on a set schedule
  ResumeEventBridgeRule:
    Type: 'AWS::Events::Rule'
    Properties:
      Description: 'Resumes sample App Runner service'
      ScheduleExpression: !Ref ResumeSchedule
      State: 'ENABLED'
      Targets: 
        - Arn: !GetAtt LambdaFunction.Arn
          Id: '1'
          Input: !Sub '{"arn": "${AppRunnerServiceArn}","action": "resume"}'

  # AWS Lambda permissions to allow the pause rule to invoke the Lambda function
  PauseLambdaPermission:
    Type: 'AWS::Lambda::Permission'
    Properties:
      Action: 'lambda:InvokeFunction'
      FunctionName: !Ref LambdaFunction
      Principal: 'events.amazonaws.com'
      SourceArn: !GetAtt PauseEventBridgeRule.Arn  
  
  # AWS Lambda permissions to allow the resume rule to invoke the Lambda function
  ResumeLambdaPermission:
    Type: 'AWS::Lambda::Permission'
    Properties:
      Action: 'lambda:InvokeFunction'
      FunctionName: !Ref LambdaFunction
      Principal: 'events.amazonaws.com'
      SourceArn: !GetAtt ResumeEventBridgeRule.Arn

This template creates the following resources:

  • Lambda function
  • IAM role
  • EventBridge rules
  • Lambda permissions

Follow these steps to deploy a CloudFormation stack from this template:

  1. In the CloudFormation console, choose Create stack, then select With new resources (standard).
  2. On the Create stack page, select Upload a template file.
  3. Select Choose file and choose your app-runner-pause-resume.yaml template file. Select Next.
  4. Provide a Stack name, for example, app-runner-pause-resume, and select Next.
  5. Provide the required parameters for the CloudFormation template:
    1. The App Runner service ARN that was output from the app-runner-service CloudFormation stack.
    2. The schedule expression for the pause schedule.
    3. The schedule expression for the resume schedule.
  6. Select Next, then choose Next on the Configure stack options page.
  7. Review the configuration options, check I acknowledge that AWS CloudFormation might create IAM resources, and choose Create stack. The stack deploys in approximately three minutes.
  8. Verify that the stack has a status of CREATE_COMPLETE.

Congratulations! You’ve successfully configured the hello-app-runner App Runner service to be controlled by EventBridge. The application will be automatically paused every day at 18:00 UTC and automatically resumed at 08:00 UTC the following day. You can access the App Runner service URL after it is paused to verify that the service is no longer running. Visit the URL after the service is resumed to verify that it is running again.

Deploy an SNS topic and EventBridge rule to send notification emails

Next, add automated monitoring to send alert notifications when the App Runner service is paused or resumed. The CloudFormation template below deploys an SNS topic, subscribes your email address to the topic, and creates an EventBridge rule to publish notification messages to the topic. It also creates an SNS policy to allow EventBridge to publish messages to the topic.

The EventBridge rule will match any successful or failed pause or resume event from the hello-app-runner service and then publish the event details to the SNS topic. To create EventBridge rules that match other App Runner events, see Handling App Runner events in EventBridge for more options.

Copy the following CloudFormation template to a text editor and save it to a file named app-runner-notifications.yaml:

AWSTemplateFormatVersion: '2010-09-09'
Description: >
  Amazon SNS topic and Amazon EventBridge rule to send email notifications for AWS App Runner events.

Parameters:
  AppRunnerServiceName:
    Type: String
    Default: 'hello-app-runner'
    Description: The name of the App Runner service
  EmailAddress:
    Type: String
    Description: The email address to receive event notifications for the sample App Runner application

Resources:
  # Amazon SNS topic for App Runner event notifications
  SnsTopic:
    Type: 'AWS::SNS::Topic'
  
  # Amazon SNS policy to allow EventBridge to publish messages to the topic
  SnsTopicPublishPolicy:
    Type: 'AWS::SNS::TopicPolicy'
    Properties:
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action:
              - 'sns:Publish'
            Principal:
              Service:
                - events.amazonaws.com
            Resource: !Ref SnsTopic
      Topics:
        - !Ref SnsTopic
  
  # Subscribe email address to the SNS topic to receive notifications
  SnsTopicEmailSubscription:
    Type: 'AWS::SNS::Subscription'
    Properties:
      Endpoint: !Ref EmailAddress
      Protocol: 'email'
      TopicArn: !Ref SnsTopic
  
  # Amazon EventBridge rule to publish messages to the topic on successful or failed pause or resume events
  EventNotificationEventBridgeRule:
    Type: 'AWS::Events::Rule'
    Properties:
      Description: 'Publishes SNS message on successful or failed pause or resume events for the sample App Runner service'
      EventPattern: 
        source: 
        - 'aws.apprunner'
        detail: 
          serviceName:
            - !Ref AppRunnerServiceName
          operationStatus: 
            - 'PauseServiceCompletedSuccessfully'
            - 'PauseServiceFailed'
            - 'ResumeServiceCompletedSuccessfully'
            - 'ResumeServiceFailed'
      State: 'ENABLED'
      Targets: 
        - Arn: !Ref SnsTopic
          Id: '1'

This template creates the following resources:

  • SNS topic
  • SNS policy
  • SNS email subscription
  • EventBridge rule

Follow these steps to deploy a CloudFormation stack from this template:

  1. In the CloudFormation console, choose Create stack, and then choose With new resources (standard).
  2. On the Create stack page, select Upload a template file.
  3. Select Choose file and choose your app-runner-notifications.yaml template file. Select Next.
  4. Provide a Stack name, for example, app-runner-notifications.
  5. Provide the required parameters for the CloudFormation template:
    1. The App Runner service name: hello-app-runner.
    2. The email address where you will receive email notifications.
  6. Select Next, then choose Next on the Configure stack options page.
  7. Review the configuration options and choose Create stack. The stack deploys in approximately two minutes.
  8. Verify that the stack has a status of CREATE_COMPLETE.
  9. Check your email inbox and click Confirm subscription in the subscription confirmation email from Amazon SNS.

Congratulations! You’ve now configured automated monitoring for the hello-app-runner App Runner service using SNS and EventBridge. You’ll receive an email notification whenever the App Runner service is successfully or unsuccessfully paused or resumed.

Cleaning up

After you’ve completed all the steps in this blog post, follow these steps to delete the resources that you’ve deployed to avoid incurring costs:

  1. In the CloudFormation console, choose Stacks.
  2. Select the app-runner-notifications stack, then choose Delete.
  3. Select the app-runner-pause-resume stack, then choose Delete.
  4. Select the app-runner-service stack, then choose Delete.
  5. Verify that all stacks have been deleted successfully.

Conclusion

Amazon EventBridge makes it easy to automatically control and monitor an AWS App Runner service. EventBridge can be combined with AWS Lambda to automatically control an App Runner service, such as pausing and resuming it on a set schedule. EventBridge can be combined with other AWS services to automatically react to App Runner events, such as using Amazon SNS to send email notifications when App Runner events occur.

This example project can be used as a starting point to build your own automated solution with App Runner and EventBridge. Visit the AWS App Runner documentation and Amazon EventBridge documentation for more information on using these services.

Michael Massey

Michael Massey

Michael Massey is a Cloud Application Architect at Amazon Web Services. He helps AWS customers achieve their goals by building highly-available and highly-scalable solutions on the AWS Cloud.