{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "AWS CloudFormation to create a SAP Router EC2 instance",

  "Parameters" : {

    "KeyName": {
      "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instance",
      "Type": "AWS::EC2::KeyPair::KeyName",
      "ConstraintDescription" : "must be the name of an existing EC2 KeyPair."
    },

    "VPCID": {
        "Description": "The existing Amazon VPC where you want to deploy SAP Router.",
        "Type": "AWS::EC2::VPC::Id"
    },

    "DMZSubnet": {
        "Description": "The existing public subnet in your VPC where you want to deploy SAP Router.",
        "Type": "AWS::EC2::Subnet::Id"
    },

    "InstanceType" : {
      "Description" : "SAP router EC2 instance type",
      "Type" : "String",
      "Default" : "m5.large",
      "AllowedValues" : [ "t3.medium", "m4.large", "m5.large", "m5.xlarge"],
      "ConstraintDescription" : "must be a valid EC2 instance type."
    },

    "SAPPIntLocation" : {
      "Description" : " The IP address range for external accessaccess (SAP Protocols and ssh)",
      "Type": "String",
      "MinLength": "9",
      "MaxLength": "18",
      "Default": "0.0.0.0/0",
      "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
      "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
    },

  "SAPPExtLocation" : {
    "Description" : " The IP address range for internal access (SAP Protocols and ssh)",
    "Type": "String",
    "MinLength": "9",
    "MaxLength": "18",
    "Default": "0.0.0.0/0",
    "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
    "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
  },

  "SAPRouterInstallMedia": {
      "Description": "Path to Amazon S3 location of SAP Router software files (e.g., s3://mysoftware).",
      "Type": "String",
      "Default": ""
  },
  "PublicIP": {
      "Type": "String",
      "Description": "Create a public IP address?",
      "Default": "Yes",
      "AllowedValues": [
          "Yes",
          "No"
      ]
  }
  },
  "Metadata": {
    "AWS::CloudFormation::Interface": {
        "ParameterGroups": [
        {
            "Label": {
                "default": "Existing network infrastructure details"
            },
            "Description": {
                "default": ""
            },
            "Parameters": [
                "VPCID",
                "DMZSubnet",
                "SAPPExtLocation",
                "SAPPIntLocation"
            ]
        },
        {
            "Label": {
                "default": "Other information"
            },
            "Description": {
                "default": ""
            },
            "Parameters": [
                "KeyName",
                "InstanceType",
                "SAPRouterInstallMedia",
                "PublicIP"
            ]
          }
      ],
    "ParameterLabels": {
          "VPCID": {
              "default": "Choose VPC ID"
          },
          "DMZSubnet": {
              "default": "Choose subnet with Internet access"
          },
          "SAPPExtLocation": {
              "default": "Pick CIDR range in public Internet to reach saprouter"
          },
          "SAPPIntLocation": {
              "default": "Choose CIDR range of SAP systems in VPC to be reached"
          },
          "KeyName": {
              "default": "Pick certificate"
          },
          "InstanceType": {
              "default": "Select instance type"
          },
          "PublicIP": {
              "default": "You want to create a public reachable SAP router?"
          },
          "SAPRouterInstallMedia": {
              "default": "S3 bucket with installation media"
          }
        }
    }
  },
  "Conditions": {
    "IfPublicIP": {
        "Fn::Equals": [
            {
                "Ref": "PublicIP"
            },
            "Yes"
        ]
    }
  },

  "Mappings" : {
    "AWSInstanceType2Arch" : {
      "m5.large"    : { "Arch" : "HVM64"  },
      "m5.xlarge"   : { "Arch" : "HVM64"  }
    },

    "AWSRegionArch2AMI" : {
      "eu-north-1"	: {"HVM64": "ami-066053b3de855b517" },
      "ap-south-1"	: {"HVM64": "ami-04a615d193c180659" },
      "eu-west-3"	: {"HVM64": "ami-0f8ace1880473d63c" },
      "eu-west-2"	: {"HVM64": "ami-0609bcfcda5bc165e" },
      "eu-west-1"	: {"HVM64": "ami-00f5a8d33f66b703a" },
      "ap-northeast-3"	: {"HVM64": "ami-0c966772c4ad93119" },
      "ap-northeast-2"	: {"HVM64": "ami-04c990ed48997bd9b" },
      "ap-northeast-1"	: {"HVM64": "ami-0422285172d16dc72" },
      "sa-east-1"	: {"HVM64": "ami-0ad4c5bc28cb33e21" },
      "ca-central-1"	: {"HVM64": "ami-05b860eb5240560fa" },
      "ap-southeast-1"	: {"HVM64": "ami-0f9ecfd36e41420c7" },
      "ap-southeast-2"	: {"HVM64": "ami-030a0dd5a754f5800" },
      "eu-central-1"	: {"HVM64": "ami-007c7cdf4ecbe7be7" },
      "us-east-1"	: {"HVM64": "ami-0c55353c85ac52c96" },
      "us-east-2"	: {"HVM64": "ami-0a482f45855ec8158" },
      "us-west-1"	: {"HVM64": "ami-0db3029701bbef0cd" },
      "us-west-2"	: {"HVM64": "ami-0a84aae978d86555d" }
    }

  },
"Resources" : {
    "SAPRouterIAMRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
          "RoleName": {
            "Fn::Join": [
                "", [
                    "SAPRemoteSupportRole",
                    {
                      "Ref": "AWS::StackName"
                    }
                  ]
            ]
          },
          "AssumeRolePolicyDocument": {
              "Statement": [
                  {
                      "Effect": "Allow",
                      "Principal": {
                          "Service": [
                              "ec2.amazonaws.com",
                              "ssm.amazonaws.com"
                          ]
                      },
                      "Action": [
                          "sts:AssumeRole"
                      ]
                  }
              ]
          },
          "Path": "/",
          "ManagedPolicyArns": [
              "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
          ],
          "Policies": [
            {
                  "PolicyName": {
                      "Fn::Join": [
                          "", [
                              "SAP-Router",
                              {
                                "Ref": "AWS::StackName"
                              }
                            ]
                      ]
                    },
                  "PolicyDocument": {
                      "Statement": [
                          {
                              "Effect": "Allow",
                              "Action": [
                                  "s3:GetObject"
                              ],
                              "Resource": {
                                "Fn::Join": [
                                    "", [
                                        "arn:aws:s3:::",
                                        {
                                          "Ref": "SAPRouterInstallMedia"
                                        },
                                        "/*"
                                      ]
                                ]
                              }
                          },
                          {
                              "Effect": "Allow",
                              "Action": ["S3:ListBucket",
                                         "S3:HeadBucket"
                                ],
                              "Resource": {
                                "Fn::Join": [
                                    "", [
                                        "arn:aws:s3:::",
                                        {
                                          "Ref": "SAPRouterInstallMedia"
                                        }
                                      ]
                                ]
                              }
                          }
                      ]
                  }
              }
          ]
      }
  },
    "SAPRouterIAMProfile" : {
            "DependsOn": [ "SAPRouterIAMRole" ],
            "Type": "AWS::IAM::InstanceProfile",
            "Properties": {
                "Path": "/",
                "Roles": [
                  {
                    "Fn::Join": [
                        "", [
                            "SAPRemoteSupportRole",
                            {
                              "Ref": "AWS::StackName"
                            }
                          ]
                    ]
                  }
                ]
           }
    },
    "SAProuterSecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Enable SAP ports and ssh",
        "SecurityGroupIngress" : [
          {"IpProtocol" : "tcp", "FromPort" : "3200", "ToPort" : "3600", "CidrIp" : { "Ref" : "SAPPIntLocation"}},
          {"IpProtocol" : "tcp", "FromPort" : "3200", "ToPort" : "3600", "CidrIp" : { "Ref" : "SAPPExtLocation"}},
          {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SAPPIntLocation"}},
          {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SAPPExtLocation"}}
        ],
        "Tags" :[
          {
            "Key": "Name",
            "Value": "ST: Test SG saprouter"
          }
        ],
        "VpcId" : { "Ref" : "VPCID" }
      }
    }
  ,
  "SAPRouterMasterInterface": {
            "Type": "AWS::EC2::NetworkInterface",
            "Properties": {
                "Description": "Network Interface for SAP Router",
                "SubnetId": {
                    "Ref": "DMZSubnet"
                },
                "GroupSet": [ { "Ref": "SAProuterSecurityGroup" } ],
                "SourceDestCheck": "true",
                "Tags": [
                    {
                        "Key": "Network",
                        "Value": "Private"
                    }
                ]
            }
        },
    "SapRouterInstance": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },
                          { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] },
        "InstanceType"   : { "Ref" : "InstanceType" },
        "KeyName"        : { "Ref" : "KeyName" },
        "NetworkInterfaces": [
                    {
                        "NetworkInterfaceId": {
                            "Ref": "SAPRouterMasterInterface"
                        },
                        "DeviceIndex": "0"
                    }
                ],
        "IamInstanceProfile": { "Ref" : "SAPRouterIAMProfile" },
        "UserData"       : { "Fn::Base64" : { "Fn::Join" : ["", [
             "#!/bin/bash \n",
             "# take a nap before the S3 download\n",
             "sleep 1\n",
             "touch /tmp/ssc","\n",
              "echo \"[Unit]\" >> /etc/systemd/system/saprouter.service\n",
              "echo \"Description=SAP Router Configuration\" >> /etc/systemd/system/saprouter.service\n",
              "echo \"After=syslog.target network.target\" >> /etc/systemd/system/saprouter.service\n",
              "echo \" \" >> /etc/systemd/system/saprouter.service\n",
              "echo \"[Service]\" >> /etc/systemd/system/saprouter.service\n",
              "echo \"Type=simple\" >> /etc/systemd/system/saprouter.service\n",
              "echo \"RemainAfterExit=yes\" >> /etc/systemd/system/saprouter.service\n",
              "echo \"WorkingDirectory=/usr/sap/saprouter\" >> /etc/systemd/system/saprouter.service\n",
              "echo \"ExecStart=/usr/sap/saprouter/saprouter -r\" >> /etc/systemd/system/saprouter.service\n",
              "echo \"ExecStop=/usr/sap/saprouter/saprouter -s\" >> /etc/systemd/system/saprouter.service\n",
              "echo \"KillMode=none\" >> /etc/systemd/system/saprouter.service\n",
              "echo \"Restart=no\" >> /etc/systemd/system/saprouter.service\n",
              "echo \" \" >> /etc/systemd/system/saprouter.service\n",
              "echo \"[Install]\" >> /etc/systemd/system/saprouter.service\n",
              "echo \"WantedBy=multi-user.target\" >> /etc/systemd/system/saprouter.service \n",
             "aws s3 cp ", { "Ref" : "SAPRouterInstallMedia" }, "/install.sh /tmp/install.sh \n",
              "echo \"*** 1. Create /usr/sap/saprouter\"\n",
              "mkdir -p /usr/sap/saprouter/install \n",
              "echo \"*** 2. Download files\"\n",
              "aws s3 sync ", { "Ref" : "SAPRouterInstallMedia" }, " /usr/sap/saprouter/install\n",
              "cd  /usr/sap/saprouter/install \n",
              "echo \"*** 3. All files will become lower case files\" \n",
              "for f in `find`; do mv -v \"$f\" \"`echo $f | tr '[A-Z]' '[a-z]'`\"; done \n",
              "echo \"*** 4. Normalize file names \" \n",
              "for f in `find . -name saprouter*.sar`; do mv -v $f saprouter.sar; done\n",
              "for f in `find . -name sapcryptolib*.sar`; do mv -v $f sapcryptolib.sar; done\n",
              "for f in `find . -name sapcar*`; do mv -v $f sapcar; done\n",
              "chmod u+x sapcar\n",
              "mv saprouttab ..\n",
              "chmod u+x /tmp/install.sh\n",
              "echo \"*** 5. Unpack files\"\n",
              "cd /usr/sap/saprouter \n",
              "./install/sapcar -xf /usr/sap/saprouter/install/saprouter.sar \n",
              "./install/sapcar -xf /usr/sap/saprouter/install/sapcryptolib.sar \n",
              "echo \"*** 6. Start service\" \n",
              "systemctl daemon-reload \n",
              "systemctl enable saprouter.service \n",
              "systemctl start saprouter.service \n",
              "echo \"7. Done...\" \n",
              "echo \"#!/usr/bin/env bash\" >> /usr/sap/saprouter/uninstall.sh \n",
              "echo \"# version 0.1\" >> /usr/sap/saprouter/uninstall.sh \n",
              "echo \"# December, 2018\" >> /usr/sap/saprouter/uninstall.sh \n",
              "echo \"## Not tested!\" >> /usr/sap/saprouter/uninstall.sh \n",
              "echo \"## Run as super user:\" >> /usr/sap/saprouter/uninstall.sh \n",
              "echo \"systemctl stop saprouter.service\" >> /usr/sap/saprouter/uninstall.sh \n",
              "echo \"systemctl disable saprouter.service\" >> /usr/sap/saprouter/uninstall.sh \n",
              "echo \"systemctl daemon-reload\" >> /usr/sap/saprouter/uninstall.sh \n",
              "echo \"rm /etc/systemd/system/saprouter.service\" >> /usr/sap/saprouter/uninstall.sh \n",
              "echo \"rm -rf /usr/sap/saprouter\" >> /usr/sap/saprouter/uninstall.sh \n",
              "chmod ugo+x /usr/sap/saprouter/uninstall.sh \n"
        ]]}}
      }
    },
    "MyEIP" : {
      "Type" : "AWS::EC2::EIP",
      "Condition": "IfPublicIP",
      "Properties" : {
        "Domain" : "vpc"
      }
    },
    "AssociateMyIP" : {
      "Type" : "AWS::EC2::EIPAssociation",
      "Condition": "IfPublicIP",
      "Properties" : {
        "AllocationId" : { "Fn::GetAtt" : [ "MyEIP", "AllocationId" ]},
        "NetworkInterfaceId" : { "Ref" : "SAPRouterMasterInterface" }
      }
    }
  },

  "Outputs" : {
    "PublicAccess" : {
      "Description" : "Public access to the newly created Instance",
      "Value" : { "Fn::Join" : ["", ["Public DNS Name: ", { "Fn::GetAtt" : [ "SapRouterInstance", "PublicDnsName" ]}]] }
    },
    "PublicIP" : {
      "Description" : "Public IP to the newly created Instance",
      "Value" : { "Fn::Join" : ["", ["Public IP: ", { "Fn::GetAtt" : [ "SapRouterInstance", "PublicIp" ]}]] }
    },
    "PrivateAccess" : {
      "Description" : "Private access to the newly created Instance",
      "Value" : { "Fn::Join" : ["", ["Private IP: ", { "Fn::GetAtt" : [ "SapRouterInstance", "PrivateIp" ]}]] }
    }
  }
}
