Parameters: CoreStack: Description: The foundational stack Type: String Hl7ParsingLibKey: Description: Key for our HL7 parsing library Type: String TriggerLambdaKey: Type: String TriggerLambdaVersion: Type: String TriggerHandler: Type: String PrepareLambdaKey: Type: String PrepareLambdaVersion: Type: String PrepareHandler: Type: String ParseLambdaKey: Type: String ParseLambdaVersion: Type: String ParseHandler: Type: String Resources: #-------------------------------------------------------------- Lambda to connect SNS and Step Function TriggerLambdaFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub "${AWS::StackName}_trigger" Description: Function to connect SNS to Step Function Code: S3Bucket: Fn::ImportValue: !Sub "${CoreStack}-ArtifactBucket" S3Key: !Ref TriggerLambdaKey S3ObjectVersion: !Ref TriggerLambdaVersion Handler: !Ref TriggerHandler Role: !GetAtt TriggerLambdaRole.Arn Runtime: python3.9 Environment: Variables: bucket_name: Fn::ImportValue: !Sub "${CoreStack}-Bucket" topic: Fn::ImportValue: !Sub "${CoreStack}-Topic" state_machine: !Ref StateMachine TriggerLambdaLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Join ['/', ['/aws/lambda', !Ref TriggerLambdaFunction]] RetentionInDays: 1 # Keep logs for a short duration TriggerLambdaRole: 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 # Provides access to CloudWatch for logging Policies: - PolicyName: sns PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: ['sns:publish'] Resource: - Fn::ImportValue: !Sub "${CoreStack}-Topic" - PolicyName: step_function PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: ['states:StartSyncExecution'] Resource: !Ref StateMachine # Permission for SNS topic to invoke this Lambda TriggerLambdaResourcePolicy: Type: AWS::Lambda::Permission Properties: FunctionName: !Ref TriggerLambdaFunction Principal: sns.amazonaws.com Action: "lambda:InvokeFunction" SourceArn: Fn::ImportValue: !Sub "${CoreStack}-Topic" # Subscription to SNS topic Subscription: Type: AWS::SNS::Subscription Properties: TopicArn: Fn::ImportValue: !Sub "${CoreStack}-Topic" Endpoint: !GetAtt TriggerLambdaFunction.Arn FilterPolicy: protocol: [hl7v2] format: [er7] Protocol: lambda #-------------------------------------------------------------- Lambda Layer Hl7apyLayer: Type: AWS::Lambda::LayerVersion Properties: CompatibleRuntimes: [python2.7, python3.6, python3.7, python3.8, python3.9] Content: S3Bucket: Fn::ImportValue: !Sub "${CoreStack}-ArtifactBucket" S3Key: !Ref Hl7ParsingLibKey LayerName: hl7apy Description: "HL7apy parser library" LicenseInfo: MIT #-------------------------------------------------------------- Preparing Lambda PrepareLambdaFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub ${AWS::StackName}_prepare Description: Prepares our ER7 message by applying common syntax corrections Code: S3Bucket: Fn::ImportValue: !Sub "${CoreStack}-ArtifactBucket" S3Key: !Ref PrepareLambdaKey S3ObjectVersion: !Ref PrepareLambdaVersion Handler: !Ref PrepareHandler Role: !GetAtt PrepareLambdaRole.Arn Runtime: python3.9 PrepareLambdaLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Join ['/', ['/aws/lambda', !Ref PrepareLambdaFunction]] RetentionInDays: 1 # Keep logs for a short duration PrepareLambdaRole: 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 # Provides access to CloudWatch for logging #-------------------------------------------------------------- Parsing Lambda ParseLambdaFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub ${AWS::StackName}_parse Description: Parse an ER7 message to JSON Layers: [!Ref Hl7apyLayer] Code: S3Bucket: Fn::ImportValue: !Sub "${CoreStack}-ArtifactBucket" S3Key: !Ref ParseLambdaKey S3ObjectVersion: !Ref ParseLambdaVersion Handler: !Ref ParseHandler Role: !GetAtt ParseLambdaRole.Arn Runtime: python3.9 ParseLambdaLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Join ['/', ['/aws/lambda', !Ref ParseLambdaFunction]] RetentionInDays: 1 # Keep logs for a short duration ParseLambdaRole: 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 # Provides access to CloudWatch for logging #-------------------------------------------------------------- Step Function StateMachine: Type: AWS::StepFunctions::StateMachine Properties: StateMachineName: !Sub ${AWS::StackName}_step_function StateMachineType: EXPRESS RoleArn: !GetAtt StateMachineRole.Arn TracingConfiguration: Enabled: true Definition: StartAt: PrepareEr7 States: PrepareEr7: Type: Task Resource: !GetAtt PrepareLambdaFunction.Arn InputPath: $.Message # What to pass to the Lambda ResultPath: $.er7 # Where to append Lambda results Next: ParseEr7 ParseEr7: Type: Task Resource: !GetAtt ParseLambdaFunction.Arn InputPath: $.er7 ResultPath: $.json OutputPath: $.json # Filter the output End: true LoggingConfiguration: Destinations: - CloudWatchLogsLogGroup: LogGroupArn: !GetAtt StateMachineLogGroup.Arn IncludeExecutionData: True Level: ALL StateMachineRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: ['sts:AssumeRole'] Effect: Allow Principal: Service: [states.amazonaws.com] ManagedPolicyArns: [] Policies: - PolicyName: StateMachineRolePolicy PolicyDocument: Statement: - Action: ['lambda:InvokeFunction', 'logs:*'] Resource: "*" Effect: Allow StateMachineLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Join ['/', ['/aws/stepfunction', !Sub "${AWS::StackName}_step_function"]] # Cannot use !Ref as that would create a circular dependency RetentionInDays: 14 Outputs: StateMachine: Value: !Ref StateMachine Export: Name: !Sub ${AWS::StackName}-StateMachine