{
    "AWSTemplateFormatVersion":"2010-09-09", 
    "Description":"Security Lake - OpenSearch Integration - Lambda Reference Stack.  **Attention** This template creates AWS resources that will incur charges on your account.",
    "Parameters":{
        "OpenSearchEndpoint": {
            "Description": "Endpoint for the cluster - example - https://vpc-my-cluster-yjktso3ovp2u6d2yypvw2mvcbm.us-east-1.es.amazonaws.com/",
            "Type": "String"
        },
        "OpenSearchARN": {
            "Description": "ARN for the cluster for IAM permissions for scripts",
            "Type": "String"
        },
        "OpenSearchVPCID":{
            "Description": "VPC ID of the OpenSearch cluster",
            "Type": "String"
        },
        "OpenSearchSubnet":{
            "Description": "Private subnet in the VPC of the OpenSearch cluster",
            "Type": "String"
        },              
        "AssumeRoleARN":{
            "Description": "Cross account Security Lake role ARN.",
            "Type": "String"
        },
        "AssumeRoleExternalID":{
            "Description": "Cross account Security Lake external ID.",
            "Type": "String"
        },
        "QueueARN":{
            "Description":"SQS queue ARN for the events that Security Lake publishes.",
            "Type" : "String"
        },
        "JARFileName" :{
            "Description": "Name of the JAR file to be used with AWS Lambda pushed via init scripts in this template.",
            "Type": "String",
            "Default" : "lambda-s3-objecthandler-0.2.8.jar"
        }             
    },
    "Mappings":{
        "AWSEC2AMILinux":{
            "us-east-1":{"AmiId":"ami-0b0dcb5067f052a63"},
            "us-east-2":{"AmiId":"ami-0beaa649c482330f7"},
            "us-west-1":{"AmiId":"ami-0f5e8a042c8bfcd5e"},
            "us-west-2":{"AmiId":"ami-094125af156557ca2"},
            "ap-south-1":{"AmiId":"ami-074dc0a6f6c764218"},
            "ap-southeast-1":{"AmiId":"ami-0af2f764c580cc1f9"},
            "ap-southeast-2":{"AmiId":"ami-06bb074d1e196d0d4"},
            "ap-northeast-1":{"AmiId":"ami-072bfb8ae2c884cc4"},
            "ap-northeast-2":{"AmiId":"ami-0eddbd81024d3fbdd"},
            "ap-northeast-3":{"AmiId":"ami-0e0cbf0f03ba99ee7"},
            "ca-central-1":{"AmiId":"ami-0ee679ef733e3b8e7"},
            "eu-central-1":{"AmiId":"ami-076309742d466ad69"},
            "eu-west-1":{"AmiId":"ami-01cae1550c0adea9c"},
            "eu-west-2":{"AmiId":"ami-04706e771f950937f"},
            "eu-west-3":{"AmiId":"ami-0f15e0a4c8d3ee5fe"},
            "eu-north-1":{"AmiId":"ami-02aeff1a953c5c2ff"},
            "sa-east-1":{"AmiId":"ami-0b7101e993ea27f3a"}
        }
    },
    "Resources":{
    
        "JARBucketCleanupLambdaExecutionRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [{
                        "Effect": "Allow",
                        "Principal": {"Service": ["lambda.amazonaws.com"]},
                        "Action": ["sts:AssumeRole"]
                    }]
                },
                "Path": "/",
                "Policies": [{
                    "PolicyName": "JARBucketCleanupLambdaExecutionPolicy",
                    "PolicyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                            "Effect": "Allow",
                            "Action": ["s3:List*","s3:DeleteObject"],
                            "Resource": [
                                {"Fn::Join":["", [ "arn:aws:s3:::",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref" :"AWS::StackId"}]}]},"-securitylake-jarbucket"]]},                        
                                {"Fn::Join":["", [ "arn:aws:s3:::",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref" :"AWS::StackId"}]}]},"-securitylake-jarbucket/*"]]}                        
                                ]
                            },
                            {
                            "Effect": "Allow",
                            "Action": ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents","logs:DeleteLog*"],
                            "Resource": "*"
                            }                       
                                                
                        ]
                    }
                }]
            }
        },    
        "JARBucketCleanupLambda": {
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Code": {
                    "ZipFile":{
                        "Fn::Join":["\n",
                            [    
                                "from __future__ import print_function",
                                "import json",
                                "import boto3",
                                "import cfnresponse",
                                "def delete_handler(event, context):",
                                "    try:",
                                "        bucket = event['ResourceProperties']['BucketName']",
                                "        if event['RequestType'] == 'Delete':",
                                "            s3 = boto3.resource('s3')",
                                "            bucket = s3.Bucket(bucket)",
                                "            for obj in bucket.objects.filter():",
                                "                print('Deleting -> ' + obj.key)",
                                "                s3.Object(bucket.name, obj.key).delete()",
                                "        send_response(event, context, cfnresponse.SUCCESS)",
                                "    except Exception as e:",
                                "        print(e)",
                                "        send_response(event, context, cfnresponse.FAILED)",
                                "def send_response(event, context, status_code):",
                                "    response_data = {}",
                                "    response_data['Data'] = 'done'",
                                "    cfnresponse.send(event, context, status_code, response_data, \"CustomResourcePhysicalID\")"
                            ]
                        ]
                    }
                },
                "Description": "Cleanup handler to nuke files in a bucket (not done normally with bucket deletes)",
                "FunctionName": {"Fn::Join":["",[{"Fn::Select":["0",{"Fn::Split":["-",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref":"AWS::StackId"}]}]}]}]},"-NukeJARBucketObjects"]]},
                "Handler": "index.delete_handler",
                "MemorySize": "128",
                "Role": {"Fn::GetAtt":["JARBucketCleanupLambdaExecutionRole","Arn"]},
                "Runtime": "python3.9",
                "Timeout": 900
            }
        },
        "NukeJARBucketObjects": {
            "Type": "Custom::NukeJARBucketObjects",
            "Properties": {
                "ServiceToken": {"Fn::GetAtt" : ["JARBucketCleanupLambda", "Arn"]},
                "BucketName": {"Ref":"JARBucket"}
            }
        },
        "JARBucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "BucketName": {"Fn::Join":["", [{"Fn::Select":["2",{"Fn::Split":["/",{"Ref" :"AWS::StackId"}]}]},"-securitylake-jarbucket"]]}, 
                "BucketEncryption": {
                    "ServerSideEncryptionConfiguration": [{
                        "ServerSideEncryptionByDefault": {
                            "SSEAlgorithm": "AES256"
                        }
                    }]
                }            },
            "DeletionPolicy": "Delete"
        },
        "ProxySecurityGroup":{
            "Type":"AWS::EC2::SecurityGroup",
            "Properties":{
                "GroupDescription":"Rules for allowing access to the proxy",
                "VpcId" : {"Ref":"OpenSearchVPCID"},               
                "SecurityGroupIngress":
                [
                    {
                        "IpProtocol":"tcp",
                        "FromPort":"443",
                        "ToPort":"443",
                        "CidrIp":"0.0.0.0\/0"
                    }
                ],
                "SecurityGroupEgress":
                [
                    {
                        "IpProtocol":"-1",
                        "FromPort":"0",
                        "ToPort":"65535",
                        "CidrIp":"0.0.0.0\/0"
                    }
                ],
                "Tags":[
                    {"Key": "Name","Value": {"Fn::Join":["",[{"Fn::Select":["0",{"Fn::Split":["-",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref":"AWS::StackId"}]}]}]}]},"-proxy-sg"]]}}
                ]
            }
        },
        "ProxyNetworkInterface":{
            "Type":"AWS::EC2::NetworkInterface",
            "Properties":{
                "Description":"Proxy ENI",
                "GroupSet":[{"Ref":"ProxySecurityGroup"}],
                "SubnetId": {"Ref":"OpenSearchSubnet"},
                "Tags":[
                    {"Key": "Name","Value": {"Fn::Join":["",[{"Fn::Select":["0",{"Fn::Split":["-",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref":"AWS::StackId"}]}]}]}]},"-proxy-if"]]}}
                ]
            }
        },
        "ProxyRole":{
            "Type":"AWS::IAM::Role",
            "Properties":{
                "RoleName": {"Fn::Join":["",[{"Fn::Select":["0",{"Fn::Split":["-",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref":"AWS::StackId"}]}]}]}]},"-proxy-role"]]},
                "AssumeRolePolicyDocument":{
                    "Version":"2012-10-17",
                    "Statement":[{
                       "Effect":"Allow",
                       "Principal":{"Service":["ec2.amazonaws.com"]},
                       "Action":["sts:AssumeRole"]
                    }]
                },
                "Path":"/",
                "ManagedPolicyArns":["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"],
                "Policies": [{
                    "PolicyName": {"Fn::Join":["",[{"Fn::Select":["0",{"Fn::Split":["-",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref":"AWS::StackId"}]}]}]}]},"-proxy-policy"]]},
                    "PolicyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect":"Allow",
                                "Action":"ec2:Describe*",
                                "Resource":"*"
                            },
                            {
                                "Effect": "Allow",
                                "Action": ["es:ESHttp*"],
                                "Resource": {"Fn::Join":["",[{"Ref":"OpenSearchARN"},"/*"]]}
                            },
                            {
                                "Effect": "Allow",
                                "Action": ["s3:List*","s3:DeleteObject","s3:GetObject","s3:PutObject"],
                                "Resource":[
                                    {"Fn::GetAtt" : ["JARBucket", "Arn"]},
                                    {"Fn::Join":["",[{"Fn::GetAtt" : ["JARBucket", "Arn"]},"/*"]]}
                                ]
                            }
                        ]
                    }
                }]
            }
        },  
        "ProxyInstanceProfile":{
            "Type": "AWS::IAM::InstanceProfile",
            "Properties": {
                "Path": "/",
                "Roles": [{"Ref": "ProxyRole"}]
            }   
        },      
        "Proxy":{
            "Type":"AWS::EC2::Instance",
            "CreationPolicy": {
                "ResourceSignal": {
                    "Timeout": "PT5M"
                }
            },      
            "Metadata":{
                "Comment":"Install a simple application",
                "AWS::CloudFormation::Init":{
                    "configSets":{
                        "default":["step1","step2","step3"]
                    },   
                    
                    "step1":{
                        "files":{
                            "/usr/share/es-scripts/templates/ocsf_actor_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_actor_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_api_details_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_api_details_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_attacks_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_attacks_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_base_event_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_base_event_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_cloud_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_cloud_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_compliance_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_compliance_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_device_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_device_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_dns_answer_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_dns_answer_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_dns_query_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_dns_query_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_dst_endpoint_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_dst_endpoint_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_enrichments_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_enrichments_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_entity_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_entity_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_entity_result_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_entity_result_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_finding_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_finding_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_http_request_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_http_request_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_identity_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_identity_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_logon_process_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_logon_process_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_malware_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_malware_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_metadata_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_metadata_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_network_connection_information_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_network_connection_information_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_network_proxy_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_network_proxy_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_network_traffic_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_network_traffic_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },                                              
                            "/usr/share/es-scripts/templates/ocsf_observables_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_observables_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_process_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_process_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },                                              
                            "/usr/share/es-scripts/templates/ocsf_resources_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_resources_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_session_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_session_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_src_endpoint_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_src_endpoint_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_user_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_user_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_user_result_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_user_result_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },                      
                            "/usr/share/es-scripts/templates/ocsf_vulnerabilities_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_vulnerabilities_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_1000_defaults_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_1000_defaults_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_4000_defaults_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_4000_defaults_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            "/usr/share/es-scripts/templates/ocsf_5000_defaults_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_5000_defaults_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            
                            "/usr/share/es-scripts/templates/ocsf_2001_security_finding_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_2001_security_finding_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            
                            "/usr/share/es-scripts/templates/ocsf_3001_account_change_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_3001_account_change_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },

                            "/usr/share/es-scripts/templates/ocsf_3002_authentication_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_3002_authentication_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },

                            "/usr/share/es-scripts/templates/ocsf_3003_authorization_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_3003_authorization_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            
                            "/usr/share/es-scripts/templates/ocsf_3004_entity_management_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_3004_entity_management_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },

                            "/usr/share/es-scripts/templates/ocsf_3005_api_activity_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_3005_api_activity_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },

                            "/usr/share/es-scripts/templates/ocsf_3006_access_activity_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_3006_access_activity_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },
                            
                            "/usr/share/es-scripts/templates/ocsf_4001_network_activity_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_4001_network_activity_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },

                            "/usr/share/es-scripts/templates/ocsf_4003_dns_activity_body.json":{
                                "source" : "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/scripts/ocsf_4003_dns_activity_body.json",
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            },

                            "/usr/share/es-scripts/code/lambda-s3-objecthandler.jar":{
                                "source" : 
                                    {"Fn::Join":[
                                        "",
                                        [
                                            "https://aws-blogs-artifacts-public.s3.amazonaws.com/artifacts/BDB-2978/code/",
                                            {"Ref":"JARFileName"}
                                        ]
                                    ]},
                                "mode":"000644",
                                "owner":"root",
                                "group":"root"
                            }
                        }               
                    },
                    "step2":{
                        "files":{
                            "/usr/share/es-scripts/es-commands.sh":{
                                "content":{
                                    "Fn::Join":[
                                        "",
                                        [
                                            "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash\n",
                                            ". ~/.nvm/nvm.sh\n",
                                            "nvm install 16\n",
                                            "npm install -g npm@9.6.2\n",
                                            "npm install aws-es-curl -g\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_actor_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_actor'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_api_details_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_api_details'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_attacks_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_attacks'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_base_event_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_base_event'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_cloud_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_cloud'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_compliance_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_compliance'\n",
                                            
                                            "cat /usr/share/es-scripts/templates/ocsf_device_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_device'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_dns_answer_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_dns_answer'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_dns_query_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_dns_query'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_dst_endpoint_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_dst_endpoint'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_enrichments_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_enrichments'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_entity_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_entity'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_entity_result_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_entity_result'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_finding_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_finding'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_http_request_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_http_request'\n",
                                            
                                            "cat /usr/share/es-scripts/templates/ocsf_identity_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_identity'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_logon_process_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_logon_process'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_malware_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_malware'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_metadata_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_metadata'\n",
                                            
                                            "cat /usr/share/es-scripts/templates/ocsf_network_connection_information_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_network_connection_information'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_network_proxy_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_network_proxy'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_network_traffic_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_network_traffic'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_observables_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_observables'\n",
                                            
                                            "cat /usr/share/es-scripts/templates/ocsf_process_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_process'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_resources_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_resources'\n",
                                            
                                            "cat /usr/share/es-scripts/templates/ocsf_session_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_session'\n",
                                            
                                            "cat /usr/share/es-scripts/templates/ocsf_src_endpoint_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_src_endpoint'\n",
                                            
                                            "cat /usr/share/es-scripts/templates/ocsf_user_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_user'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_user_result_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_user_result'\n",
                                            
                                            "cat /usr/share/es-scripts/templates/ocsf_vulnerabilities_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_component_template/ocsf_vulnerabilities'\n",
                                            
                                            "cat /usr/share/es-scripts/templates/ocsf_1000_defaults_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_1000_defaults'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_2001_security_finding_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_2001_security_finding'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_3001_account_change_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_3001_account_change'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_3002_authentication_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_3002_authentication'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_3003_authorization_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_3003_authorization'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_3004_entity_management_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_3004_entity_management'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_3005_api_activity_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_3005_api_activity'\n",
                                            
                                            "cat /usr/share/es-scripts/templates/ocsf_3006_access_activity_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_3006_access_activity'\n",
                                            
                                            "cat /usr/share/es-scripts/templates/ocsf_4000_defaults_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_4000_defaults'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_4001_network_activity_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_4001_network_activity'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_4003_dns_activity_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_4003_dns_activity'\n",

                                            "cat /usr/share/es-scripts/templates/ocsf_5000_defaults_body.json | aws-es-curl --region ",
                                            {"Ref":"AWS::Region"},
                                            " -X PUT '",
                                            {"Ref":"OpenSearchEndpoint"},
                                            "_index_template/ocsf_5000_defaults'\n"

                                        ]
                                    ]
                                },
                                "mode":"000755",
                                "owner":"root",
                                "group":"root"
                            }                               
                        }               
                    },
                    "step3":{
                        "commands":{
                            "put_jar_in_s3_bucket" : {
                                "command" : {"Fn::Join":[
                                    "",
                                    [
                                        "aws s3 cp lambda-s3-objecthandler.jar",
                                        " s3://",
                                        {"Ref":"JARBucket"},
                                        "/",
                                        {"Ref":"JARFileName"}                                    
                                    ]
                                ]},    
                                "ignoreErrors" : "false",
                                "cwd" : "/usr/share/es-scripts/code"
                            }
                        },
                        "services":{
                            "sysvinit":{
                                "amazon-ssm-agent":{
                                    "enabled":"true",
                                    "ensureRunning":"true"
                                }
                            }
                        }
                    }
                }
            },
            "Properties":{
                "Tags":[
                    {"Key": "Name","Value": {"Fn::Join":["",[{"Fn::Select":["0",{"Fn::Split":["-",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref":"AWS::StackId"}]}]}]}]},"-proxy"]]}}
                ],                            
                "ImageId":{
                    "Fn::FindInMap":[
                        "AWSEC2AMILinux",
                        {"Ref":"AWS::Region"},
                        "AmiId"
                    ]
                },
                "InstanceType":"c5.large",
                "IamInstanceProfile":{ "Ref":"ProxyInstanceProfile"},
                "UserData":{
                    "Fn::Base64":{
                        "Fn::Join":[
                            "",
                            [
                                "#!/bin/bash -xe\n",
                                "yum update -y aws-cfn-bootstrap\n",
                                "yum update -y aws-cli\n",
                                "yum update -y amazon-ssm-agent\n",
                                "mkdir /usr/share/es-scripts\n",
                                "mkdir /usr/share/es-scripts/templates\n",
                                "mkdir /usr/share/es-scripts/code\n",
                                "yum install -y python-pip\n",
                                "/opt/aws/bin/cfn-init -c default -v",
                                " --stack ",
                                {"Ref":"AWS::StackName"},
                                " --resource Proxy ",
                                " --region ",
                                {"Ref":"AWS::Region"},
                                "\n",
                                "/opt/aws/bin/cfn-signal -e $? ",
                                " --stack ",
                                {"Ref":"AWS::StackName"},
                                " --resource Proxy ",
                                " --region ",
                                {"Ref":"AWS::Region"},
                                "\n"
                            ]
                        ]
                    }
                    
                },    
                "NetworkInterfaces":[
                    {
                        "DeviceIndex":"0",
                        "NetworkInterfaceId":{"Ref":"ProxyNetworkInterface"}
                    }
                ]
            }
        },      
        "SecurityLakeLogsToOpenSearchExecutionRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [{
                        "Effect": "Allow",
                        "Principal": {"Service": ["lambda.amazonaws.com"]},
                        "Action": ["sts:AssumeRole"]
                    }]
                },
                "Path": "/",
                "Policies": [{
                    "PolicyName": "SecurityLakeLogsToOpenSearchExecutionPolicy",
                    "PolicyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Effect": "Allow",
                                "Action": [
                                    "logs:CreateLogGroup",
                                    "logs:CreateLogStream",
                                    "logs:PutLogEvents",
                                    "logs:DeleteLog*",
                                    "ec2:CreateNetworkInterface",
                                    "ec2:DescribeNetworkInterfaces",
                                    "ec2:DeleteNetworkInterface"
                                ],
                                "Resource": "*"
                            },
                            {
                                "Effect": "Allow",
                                "Action": ["es:ESHttp*"],
                                "Resource": {"Fn::Join":["",[{"Ref":"OpenSearchARN"},"/*"]]}
                            },
                            {
                                "Effect": "Allow",
                                "Action": ["sqs:ReceiveMessage","sqs:DeleteMessage","sqs:Get*","sqs:List*"],
                                "Resource": {"Ref":"QueueARN"}
                            },
                            {
                                "Effect": "Allow",
                                "Action": ["sts:assumeRole"],
                                "Resource": {"Ref":"AssumeRoleARN"}
                            }
                    
                        ]
                    }
                }]
            }
        },    
        "SecurityLakeLogsToOpenSearchSecurityGroup":{
            "Type":"AWS::EC2::SecurityGroup",
            "Properties":{
                "GroupDescription":"Rules for enabling Lambda to talk to OpenSearch / SQS / S3 over 443",
                "VpcId":{"Ref":"OpenSearchVPCID"},
                "SecurityGroupIngress" : [
                    {
                        "IpProtocol" : "-1",
                        "CidrIp" : "0.0.0.0/0"
                    }
                ],
                "SecurityGroupEgress" : [
                    {
                        "IpProtocol" : "tcp",
                        "FromPort" : "443",
                        "ToPort" : "443",
                        "CidrIp" : "0.0.0.0/0"
                    }
                ],
                "Tags":[
                   {"Key":"Name","Value":{"Fn::Join":["",[{"Fn::Select":["0",{"Fn::Split":["-",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref":"AWS::StackId"}]}]}]}]},"-lambda-sg"]]}}
                ]
            }
        },
        "SecurityLakeLogsToOpenSearchLambda": {
            "DependsOn":"Proxy",
            "Type": "AWS::Lambda::Function",
            "Properties": {
                "Environment":{
                    "Variables" : {
                        "SEARCH_ENDPOINT" : {"Ref":"OpenSearchEndpoint"},
                        "CROSS_ACCOUNT_S3_SQS_SUBSCRIBER_ARN" : {"Ref":"AssumeRoleARN"},
                        "EXTERNAL_ID" : {"Ref":"AssumeRoleExternalID"}
                    }           
                },
                "Code": {
                    "S3Bucket" : {"Ref":"JARBucket"},
                    "S3Key" : {"Ref":"JARFileName"}
                },
                "VpcConfig":{
                    "SubnetIds":[{"Ref":"OpenSearchSubnet"}],          
                    "SecurityGroupIds":[ {"Ref":"SecurityLakeLogsToOpenSearchSecurityGroup"}]
                },
                "ReservedConcurrentExecutions":0,
                "Description": "Process Security Lake logs in OCSF format and send them to OpenSearch Service",
                "FunctionName": {"Fn::Join":["",[{"Fn::Select":["0",{"Fn::Split":["-",{"Fn::Select":["2",{"Fn::Split":["/",{"Ref":"AWS::StackId"}]}]}]}]},"-SecurityLakeLogsToOpenSearch"]]},
                "Handler": "com.amazonaws.sa.lambda.s3objects.handler.ocsf.OCSFSecurityLakeNotificationHandler::handleRequest",
                "MemorySize": "768",
                "Role": {"Fn::GetAtt":["SecurityLakeLogsToOpenSearchExecutionRole","Arn"]},
                "Runtime": "java11",
                "Timeout": 300
            }
        },
        "SecurityLakeLogsToOpenSearchEventSource": {
            "Type" : "AWS::Lambda::EventSourceMapping",
            "Properties": {
                "EventSourceArn":{"Ref":"QueueARN"},
                "BatchSize":10,
                "FunctionName":{"Fn::GetAtt":["SecurityLakeLogsToOpenSearchLambda","Arn"]},
                "Enabled":"false"
            }
        }
    },
    "Outputs":{
        "ProxyRoleArn":{
            "Description":"Proxy role ARN for FGAC role mapping.",
            "Value": {"Fn::GetAtt" : ["ProxyRole", "Arn"] },
            "Export" : { "Name" : {"Fn::Sub": "${AWS::StackName}-ProxyRoleArn" }}
        },
        "LambdaRoleArn":{
            "Description":"ARN of the Lambda role created for SL integration.",
            "Value": {"Fn::GetAtt" : ["SecurityLakeLogsToOpenSearchExecutionRole", "Arn"] },
            "Export" : { "Name" : {"Fn::Sub": "${AWS::StackName}-LambdaRoleArn" }}
        },
        "CommandProxyInstanceID":{
            "Description":"Instance ID for tools proxy for SL integration.",
            "Value": {"Ref":"Proxy"},
            "Export" : { "Name" : {"Fn::Sub": "${AWS::StackName}-CommandProxyInstanceID" }}
        },
        "JARBucketName":{
            "Description":"JAR Bucket Name",
            "Value":{"Ref":"JARBucket"},
            "Export" : { "Name" : {"Fn::Sub": "${AWS::StackName}-JARBucketName" }}
        }            
    }
}    

