AWSTemplateFormatVersion: 2010-09-09
Description: >-
   This template deploys a lambda to monitor the state of the vMX and update the CW step functions.(qs-1srtkbc3s)
Parameters:
  VPCID:
    Description: 'ID of the VPC (e.g., vpc-0343606e)'
    Type: 'AWS::EC2::VPC::Id'
  AvailabilityZone1SubnetID:
    Description: Subnet ID to be used for the deployment of vMX-1 in Availability Zone 1
    Type: 'AWS::EC2::Subnet::Id'
  AvailabilityZone2SubnetID:
    Description: Subnet ID to be used for the deployment of vMX-2 in Availability Zone 2
    Type: 'AWS::EC2::Subnet::Id'
  QSS3BucketName:
    AllowedPattern: "^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$"
    ConstraintDescription: "Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-)."
    Default: aws-quickstart
    Description: "S3 bucket name for the Quick Start assets. Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-)."
    Type: String
  QSS3KeyPrefix:
    AllowedPattern: "^[0-9a-zA-Z-/]*$"
    ConstraintDescription: "Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/)."
    Default: quickstart-cisco-meraki-vmx-cloudwan/
    Description: "S3 key prefix for the Quick Start assets. Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash (/)."
    Type: String
  QSS3BucketRegion:
    Default: 'us-east-1'
    Description: 'The AWS Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. When using your own bucket, you must specify this value.'
    Type: String
  SDWANVPCRTID:
    Description: "The instance ID for the SD-WAN VPC route table"
    Type: String
  MerakiOrgID:
    Description: "The Meraki Org ID to be used for this quickstart"
    Type: String
  MerakiAPIKey:
    Description: "The API Key for your Meraki Organization"
    Type: String
    NoEcho: 'true'
  vMX1MerakiNetworkTag:
    Description: Tag used to identify the Meraki vMX1 Network on the dashboard
    Type: String
    Default: VMX1
  vMX2MerakiNetworkTag:
    Description: Tag used to identify the Meraki vMX2 Network on the dashboard
    Type: String
    Default: VMX2
  LambdaRate:
    Description: >
      The rate (frequency) that determines when CloudWatch Events runs the rule that
      triggers the Route Monitor Lambda function.
    Default: rate(10 minutes)
    AllowedValues:
      - rate(1 minute)
      - rate(10 minutes)
      - rate(60 minutes)
    Type: String
  GlobalNetworkName:
    Description: AWS CloudWAN Global Network Name
    Default: "meraki-gn"
    Type: String
  MerakiEventBusName:
    Description: Name of CustomEventBus for EventBridge
    Default: "MerakiEventBus"
    Type: String
  BaseRegionName:
    Type: String
    Description: Base region for the CloudWAN resource
    

Conditions:
  UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart']

Resources:
  MerakiApiKey:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: MerakiAPIKey
      Description: This is the API key for the meraki dashboard
      SecretString: !Sub '{"merakiapikey":"${MerakiAPIKey}" }'
      Tags:
        - Key: AppName
          Value: !Join
          - '-'
          - - !Ref 'AWS::StackName'
            - merakiapikey

  CopyLambdaStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Sub 
        - >-
          https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/copy-lambdas.yaml
        - S3Region: !If 
            - UsingDefaultBucket
            - !Ref 'AWS::Region'
            - !Ref QSS3BucketRegion
          S3Bucket: !If 
  
            - UsingDefaultBucket
            - !Sub '${QSS3BucketName}-${AWS::Region}'
            - !Ref QSS3BucketName
      Parameters:
        QSS3BucketName: !Ref QSS3BucketName
        QSS3KeyPrefix: !Ref QSS3KeyPrefix

  LambdaBasicExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
          Action: sts:AssumeRole
          Condition: {}
      Path: /
      Policies:
        - PolicyName: !Sub ${AWS::StackName}-vmxEc2Policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: !Sub arn:${AWS::Partition}:logs:*:*:*
              - Effect: Allow
                Action:
                  - "ec2:*"
                Resource: !Sub arn:${AWS::Partition}:ec2:*:*:*
              - Effect: Allow
                Action:
                  - secretsmanager:DescribeSecret
                  - secretsmanager:ListSecretVersionIds
                  - secretsmanager:GetResourcePolicy
                  - secretsmanager:GetSecretValue
                  - secretsmanager:GetRandomPassword
                Resource: !Sub arn:${AWS::Partition}:secretsmanager:*:*:*:*
              - Effect: Allow
                Action:
                  - ec2:DescribeInstances
                  - ec2:DescribeTransitGatewayRouteTables
                  - ec2:DescribeRouteTables
                  - ec2:DescribeInstanceStatus
                  - ec2:DescribeTransitGatewayAttachments
                Resource: "*"
              - Effect: Allow
                Action:
                  - "events:*"
                Resource: !Sub arn:${AWS::Partition}:events:*:*:*
              - Effect: Allow
                Action:
                  - "networkmanager:Describe*"
                  - "networkmanager:Get*"
                  - "networkmanager:List*"
                Resource: "*"
              

  PollingLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Handler: meraki_polling_lambda.main
      Timeout: 60
      Role: !GetAtt 'LambdaBasicExecutionRole.Arn'
      Runtime: python3.7
      Code:
        S3Bucket: !GetAtt 'CopyLambdaStack.Outputs.LambdaZipsBucket'
        S3Key: !Sub "${QSS3KeyPrefix}functions/packages/meraki_polling_lambda.zip"
      MemorySize: 3008
      Environment:
        Variables:
          meraki_org_id: !Ref 'MerakiOrgID'
          rt_id: !Ref 'SDWANVPCRTID'
          vmx1_tag: !Ref 'vMX1MerakiNetworkTag'
          vmx2_tag: !Ref 'vMX2MerakiNetworkTag'
          vpc_id: !Ref 'VPCID'
          vpc_arn: !Sub 
                    - arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${VPC_ID}
                    - VPC_ID: !Ref 'VPCID'
          az1_subnet_arn: !Sub
                    - arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:subnet/${AZ1SubnetID}
                    - AZ1SubnetID: !Ref 'AvailabilityZone1SubnetID'
          az2_subnet_arn: !Sub
                    - arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:subnet/${AZ2SubnetID}
                    - AZ2SubnetID: !Ref 'AvailabilityZone2SubnetID'
          global_network_name: !Ref 'GlobalNetworkName'
          event_bus_name: !Ref 'MerakiEventBusName'
          base_region_name: !Ref 'BaseRegionName'
  
  PollingLambdaSchedulePermission:
    Type: "AWS::Lambda::Permission"
    Properties:
      Action: 'lambda:InvokeFunction'
      FunctionName: !Sub ${PollingLambdaFunction.Arn}
      Principal: 'events.amazonaws.com'
      SourceArn: !Sub ${PollingLambdaSchedule.Arn}
    DependsOn:
      - PollingLambdaSchedule

  PollingLambdaSchedule:
    Type: "AWS::Events::Rule"
    Properties:
      Description: >
        A schedule for the TGW Route Monitor Lambda function..
      ScheduleExpression: !Ref LambdaRate
      State: ENABLED
      Targets:
        - Arn: !Sub ${PollingLambdaFunction.Arn}
          Id: LambdaSchedule
    DependsOn:
      - PollingLambdaFunction
  
Outputs:
  PollingLambda:
    Value: !Ref 'PollingLambdaFunction'