AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: "Sub template"
Parameters:
  ResourceTag:
    Type: String
    Description: Tag applied to all resources
Globals:
  Function:
    Timeout: 3
    Runtime: python3.7
    Tags:
      Project: !Ref ResourceTag
    Environment:
      Variables:
        ResourceTag: !Ref ResourceTag
Resources:
  BootstrapCerts:
    Type: AWS::S3::Bucket
    Properties:
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256

  FleetProvisioningFunction:
    Type: AWS::Serverless::Function
    Properties:
      Description: Sets up fleet provisioning
      CodeUri: Lambdas/provision_device/
      Handler: app.handler
      Timeout: 360
      MemorySize: 3008
      Environment:
        Variables:
          BootstrapCertsBucket: !Ref BootstrapCerts
          Account: !Ref AWS::AccountId
          Region: !Ref AWS::Region
          RegistrationRoleArn: !Sub ${ThingsRegistrationRole.Arn}
          ProdLambdaHookArn: !Sub ${FleetProvisioningHookFunction.Arn}
          RotateLambdaHookArn: !Sub ${CertRotationHookFunction.Arn}
      Policies:
        - AWSLambdaBasicExecutionRole
        - AdministratorAccess

  FleetProvisioningCustom:
    Type: Custom::FleetProvisioning
    Properties:
      ServiceToken: !GetAtt FleetProvisioningFunction.Arn  
  
  ThingsRegistrationRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${ResourceTag}-ThingRegistration
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: iot.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSIoTThingsRegistration

  FleetProvisioningHookFunction:
    Type: AWS::Serverless::Function
    Properties:
      Description: Lambda hook for provisioning acceptance logic
      CodeUri: Lambdas/provision_hook/
      Handler: app.handler
      Timeout: 10
      Policies:
        - AWSLambdaBasicExecutionRole
      Environment:
        Variables:
          ENV: dev

        
  FleetProvisioningHookPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      Principal: iot.amazonaws.com
      FunctionName: !Ref FleetProvisioningHookFunction
      SourceAccount: !Ref AWS::AccountId
  
  CertMonitorFunction:
    Type: AWS::Serverless::Function
    Properties:
      Description: Lambda to monitor expired certs
      CodeUri: Lambdas/cert_rotation_monitor/
      Handler: app.handler
      Timeout: 10
      Events:
        CheckCertExpiryEvent:
          Type: Schedule
          Properties:
            Schedule: rate(1 minute)  
      Policies:
        - AWSLambdaBasicExecutionRole
        - Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
              - cloudwatch:PutMetricData
              - iot:Receive
              - logs:CreateLogStream
              - logs:CreateLogGroup
              - iot:DescribeThing
              - iot:SearchIndex
              - iot:ListThingsInThingGroup
              - iot:ListThingPrincipals
              - iot:DescribeCertificate
              - iot:UpdateCertificate
              - iot:DetachThingPrincipal
              - iot:PutLogEvents
              - iot:Publish
              Resource: "*"    
  CertRotationHookFunction:
    Type: AWS::Serverless::Function
    Properties:
      Description: Lambda to manage provisioning of rotating certs
      CodeUri: Lambdas/cert_rotation_hook/
      Handler: app.handler
      Timeout: 10
      Policies:
        - AWSLambdaBasicExecutionRole
        - Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
              - cloudwatch:PutMetricData
              - iot:Receive
              - logs:CreateLogStream
              - logs:CreateLogGroup
              - iot:DescribeThing
              - iot:SearchIndex
              - iot:ListThingsInThingGroup
              - iot:ListThingPrincipals
              - iot:DescribeCertificate
              - iot:UpdateCertificate
              - iot:DetachThingPrincipal
              - iot:PutLogEvents
              - iot:Publish
              Resource: "*"    
               
  CertRotationHookPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      Principal: iot.amazonaws.com
      FunctionName: !Ref CertRotationHookFunction
      SourceAccount: !Ref AWS::AccountId
  
  BootstrapGeneratorFunction:
    Type: AWS::Serverless::Function
    Properties:
      Description: Creates bootstraps for each model type presented
      CodeUri: Lambdas/bootstrap_generator/
      Handler: app.handler
      Timeout: 360
      MemorySize: 3008
      Environment:
        Variables:
          Region: !Ref AWS::Region
      Policies:
        - AWSLambdaBasicExecutionRole
        - Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
              - cloudwatch:PutMetricData
              - iot:CreateKeysAndCertificate
              - iot:AttachPolicy
              - logs:CreateLogStream
              - logs:CreateLogGroup
              - iot:ListThingPrincipals
              - iot:DescribeCertificate
              - iot:PutLogEvents
              Resource: "*"    
Outputs:
  BootstrapBucket:
    Description: 'Bucket with bootstrap certificates' 
    Value: !Ref BootstrapCerts
    Export: 
      Name: BootstrapBucket