AWSTemplateFormatVersion: 2010-09-09 Description: >- Amazon EC2 Global Dashboard. Monitor how many EC2 Instances are running across all regions with a CloudWatch dashboard. Outputs: Region: Description: Region the stack was launched in. Value: !Ref 'AWS::Region' TagBasedCounting: Description: Monitor all running EC2 Instances = 'all'. Monitor by tag = 'tag'. Value: !Ref TagBasedParameter Parameters: TagBasedParameter: Type: String Default: all Description: Monitor all running EC2 Instances = 'all'. Monitor by tag = 'tag'. TagKeyParameter: Type: String Default: tag:amazon-ec2-global-dashboard Description: The Tag Key which you would like to use. Must be formated like 'tag:YOUR_KEY_HERE'. TagValueParameter: Type: String Default: enabled Description: The Tag Value which you would like to use. Resources: AmazonEC2GlobalDashboardFunction: Type: 'AWS::Lambda::Function' Properties: FunctionName: amazon-ec2-global-dashboard Environment: Variables: TagEnabled: !Ref TagBasedParameter VarKey: !Ref TagKeyParameter VarValue: !Ref TagValueParameter Code: ZipFile: | import boto3 import os cloudwatch = boto3.client('cloudwatch') client = boto3.client('ec2') TagEnabled = os.environ['TagEnabled'] VarKey = os.environ['VarKey'] VarValue = os.environ['VarValue'] def lambda_handler(event, context): regions = [region['RegionName'] for region in client.describe_regions()['Regions']] for region in regions: x = region ec2 = boto3.resource('ec2', region_name=x) if TagEnabled == 'all': instances = ec2.instances.filter( Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]) instlist = list(instances) y = (len(instlist)) cloudwatch.put_metric_data( MetricData=[ { 'MetricName': 'running-state', 'Dimensions': [ { 'Name': 'region', 'Value': x }, ], 'Unit': 'Count', 'Value': y }, ], Namespace='Running-instances' ) else: instances = ec2.instances.filter( Filters=[{'Name': 'instance-state-name', 'Values': ['running']},{'Name': VarKey, 'Values': [VarValue]}]) instlist = list(instances) y = (len(instlist)) cloudwatch.put_metric_data( MetricData=[ { 'MetricName': 'running-state', 'Dimensions': [ { 'Name': 'region', 'Value': x }, ], 'Unit': 'Count', 'Value': y }, ], Namespace='Running-instances' ) Handler: index.lambda_handler Runtime: python3.6 Timeout: '30' Role: !GetAtt - LambdaExecutionRole - Arn LambdaExecutionRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - 'sts:AssumeRole' Path: / Policies: - PolicyName: root PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 'ec2:DescribeRegions' - 'ec2:DescribeInstances' - 'cloudwatch:PutMetricData' - 'cloudwatch:PutDashboard' - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: '*' ScheduledRule: Type: 'AWS::Events::Rule' Properties: Description: Amazon EC2 Global Dashboard rule. ScheduleExpression: rate(15 minutes) State: ENABLED Targets: - Arn: !GetAtt - AmazonEC2GlobalDashboardFunction - Arn Id: AmazonEC2GlobalDashboardFunction PermissionForEventsToInvokeLambda: Type: 'AWS::Lambda::Permission' Properties: FunctionName: !Ref AmazonEC2GlobalDashboardFunction Action: 'lambda:InvokeFunction' Principal: events.amazonaws.com SourceArn: !GetAtt - ScheduledRule - Arn Dashboard: Type: 'AWS::CloudWatch::Dashboard' Properties: DashboardName: Amazon_EC2_Global_Dashboard DashboardBody: !Join - '' - - >- {"widgets":[{"type":"metric","x":0,"y":0,"width":12,"height":16,"properties":{"metrics":[["Running-instances","running-state","region","us-east-1"],[".",".",".","us-east-2"],[".",".",".","us-west-1"],[".",".",".","us-west-2"],[".",".",".","ca-central-1"],[".",".",".","eu-central-1"],[".",".",".","eu-west-1"],[".",".",".","eu-west-2"],[".",".",".","eu-west-3"],[".",".",".","eu-north-1"],[".",".",".","ap-northeast-1"],[".",".",".","ap-northeast-2"],[".",".",".","ap-northeast-3"],[".",".",".","ap-southeast-1"],[".",".",".","ap-southeast-2"],[".",".",".","ap-south-1"],[".",".",".","sa-east-1"]],"region":" - !Ref 'AWS::Region' - >- ","view":"singleValue","period":900,"stat":"Maximum","title":"Running Instances"}}, {"type":"text","x":12,"y":0,"width":6,"height":16,"properties":{"markdown":"# Region mapping\nCode|Name\n----|----\n[us-east-1](https://us-east-1.console.aws.amazon.com/ec2/v2/home?region=us-east-1#Instances:sort=instanceId)|US East (N. Virginia)\n[us-east-2](https://us-east-2.console.aws.amazon.com/ec2/v2/home?region=us-east-2#Instances:sort=instanceId)|US East (Ohio)\n[us-west-1](https://us-west-1.console.aws.amazon.com/ec2/v2/home?region=us-west-1#Instances:sort=instanceId)|US West (N. California)\n[us-west-2](https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#Instances:sort=instanceId)|US West (Oregon)\n[ca-central-1](https://ca-central-1.console.aws.amazon.com/ec2/v2/home?region=ca-central-1#Instances:sort=instanceId)|Canada (Central)\n[eu-central-1](https://eu-central-1.console.aws.amazon.com/ec2/v2/home?region=eu-central-1#Instances:sort=instanceId)|EU (Frankfurt)\n[eu-west-1](https://eu-west-1.console.aws.amazon.com/ec2/v2/home?region=eu-west-1#Instances:sort=instanceId)|EU (Ireland)\n[eu-west-2](https://eu-west-2.console.aws.amazon.com/ec2/v2/home?region=eu-west-2#Instances:sort=instanceId)|EU (London)\n[eu-west-3](https://eu-west-3.console.aws.amazon.com/ec2/v2/home?region=eu-west-3#Instances:sort=instanceId)|EU (Paris)\n[eu-north-1](https://eu-north-1.console.aws.amazon.com/ec2/v2/home?region=eu-north-1#Instances:sort=instanceId)|EU (Stockholm)\n[ap-northeast-1](https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#Instances:sort=instanceId)|Asia Pacific (Tokyo)\n[ap-northeast-2](https://ap-northeast-2.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-2#Instances:sort=instanceId)|Asia Pacific (Seoul)\n[ap-northeast-3](https://ap-northeast-3.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-3#Instances:sort=instanceId)|Asia Pacific (Osaka-Local)\n[ap-southeast-1](https://ap-southeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-southeast-1#Instances:sort=instanceId)|Asia Pacific (Singapore)\n[ap-southeast-2](https://ap-southeast-2.console.aws.amazon.com/ec2/v2/home?region=ap-southeast-2#Instances:sort=instanceId)|Asia Pacific (Sydney)\n[ap-south-1](https://ap-south-1.console.aws.amazon.com/ec2/v2/home?region=ap-south-1#Instances:sort=instanceId)|Asia Pacific (Mumbai)\n[sa-east-1](https://sa-east-1.console.aws.amazon.com/ec2/v2/home?region=sa-east-1#Instances:sort=instanceId)|South America (São Paulo)\n"}}]}