{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "This template creates one linux and one windows server installation for running windows FVs.",

  "Parameters" : {
   "CurrentVPC": {
        "Description" : "Id of current VPC",
        "Type"        : "String"
    },

   "CurrentSubnet": {
        "Description" : "current subnet from VPC",
        "Type": "String"
    },

    "CurrentNodesSg": {
      "Description" : "current kubernetes nodes security group",
      "Type": "String"
    },

    "KubeVersion": {
      "Description" : "version of kubernetes",
      "Type": "String"
    },

    "BackEnd": {
      "Description" : "calico-bgp, flannel-host-gw, or flannel-vxlan",
      "Type": "String"
    },

    "PPKConfig": {
      "Description" : "PPK key file for pscp",
      "Type": "String"
    },

    "WindowsOS": {
      "Description" : "windows OS",
      "Type": "String"
    },

    "KeyName" : {
      "Description" : "Name of an existing EC2 KeyPair",
      "Type" : "AWS::EC2::KeyPair::KeyName",
      "ConstraintDescription" : "must be the name of an existing EC2 KeyPair."
    },

    "SourceCidrForRDP" : {
      "Description" : "IP Cidr from which you are likely to RDP into the instances. You can add rules later by modifying the created security groups e.g. 54.32.98.160/32",
      "Type" : "String",
      "MinLength" : "9",
      "MaxLength" : "18",
      "AllowedPattern" : "^([0-9]+\\.){3}[0-9]+\\/[0-9]+$"
    }
  },

  "Mappings" : {
    "AWSRegion2AMI" : {
      "us-west-2"        : {"Windows1809container" : "ami-0ea9f92e8a473c37f", "Windows2022container": "ami-0de8a8dd91337a7cc", "ubuntu2004": "ami-0d26e1fbc75664845"},
      "us-east-2"        : {"Windows1809container" : "ami-0b2153301a21b82f0", "Windows2022container": "ami-0bb4ff38c83f26428", "ubuntu2004": "ami-09b0e7e86badffe0e"}
    }

  },

  "Resources" : {
    "HybridClusterSecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "VpcId" : {"Ref" : "CurrentVPC"},
        "GroupDescription" : "Enable RDP",
        "SecurityGroupIngress" : [
          {"IpProtocol" : "tcp", "FromPort" : "3389", "ToPort" : "3389", "CidrIp" : { "Ref" : "SourceCidrForRDP" }}
        ]
      }
    },

    "HybridCluster0EIP" : {
      "Type" : "AWS::EC2::EIP",
      "Properties" : {
        "InstanceId" : { "Ref" : "HybridCluster0" }
      }
    },

    "HybridCluster1EIP" : {
      "Type" : "AWS::EC2::EIP",
      "Properties" : {
        "InstanceId" : { "Ref" : "HybridCluster1" }
      }
    },

    "HybridCluster0": {
      "Type" : "AWS::EC2::Instance",
      "Metadata" : {
        "AWS::CloudFormation::Init" : {
          "configSets": {
            "calico": [
              "1-install"
             ]
          },

          "1-install" : {
            "commands" : {
              "1-docker-pull" : {
                "command" : "docker pull busybox",
                "waitAfterCompletion": "0"
              }
            }
          }
        }
      },
      "Properties": {
        "InstanceType" : "t2.medium",
        "ImageId" : { "Fn::FindInMap" : [ "AWSRegion2AMI", { "Ref" : "AWS::Region" }, "ubuntu2004" ]},
        "SecurityGroupIds" : [ {"Ref" : "CurrentNodesSg"}, {"Ref" : "HybridClusterSecurityGroup"} ],
        "KeyName" : { "Ref" : "KeyName" },
        "SubnetId": { "Ref": "CurrentSubnet" },
        "SourceDestCheck": false,
        "Tags" : [ {"Key" : "Name", "Value" : { "Fn::Join" : [ "-", [ { "Ref": "AWS::StackName" }, "linux" ]]}} ],
        "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
          "#!/bin/bash -xe\n",
          "apt-get update -y\n",
          "apt-get -y install python3-pip\n",
          "pip3 install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-py3-latest.tar.gz\n",

          "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -\n",
          "sudo add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable\"\n",

          "apt-get update -qq\n",
          "apt-get install -y docker-ce\n",
          "usermod -aG docker ubuntu\n",

          "cfn-init -v ",
          "         --stack ", { "Ref" : "AWS::StackName" },
          "         --resource HybridCluster0 ",
          "         --configsets calico ",
          "         --region ", { "Ref" : "AWS::Region" }, "\n"
         ]]}}
        }
    },

    "HybridCluster1": {
      "Type" : "AWS::EC2::Instance",
      "Metadata" : {
        "AWS::CloudFormation::Init" : {
          "configSets": {
            "calico": [
              "1-download",
              "2-unzip",
              "3-install"
             ]
          },
          "1-download" : {
            "files" : {
              "c:\\k\\linux-node.ppk" : {
                "content" : "{{config0}}",
                "context" : { "config0" : { "Ref" : "PPKConfig"} }
              },
              "c:\\k\\backend" : {
                "content" : "{{config0}}",
                "context" : { "config0" : { "Ref" : "BackEnd"} }
              },
              "c:\\k\\etcd-endpoints" : {
                "content" : { "Fn::GetAtt" : [ "HybridCluster0", "PrivateIp" ] }
              },
              "c:\\k\\cf-debug-copy-exe.ps1" : {
                "content" : "echo y | c:\\k\\pscp.exe -r -2 -i c:\\k\\linux-node.ppk ubuntu@{{linuxip}}:/home/ubuntu/*.exe .",
                "context" : { "linuxip" : { "Fn::GetAtt" : [ "HybridCluster0", "PrivateIp" ] } }
              },
              "c:\\k\\cf-debug-copy-zip.ps1" : {
                "content" : "echo y | c:\\k\\pscp.exe -r -2 -i c:\\k\\linux-node.ppk ubuntu@{{linuxip}}:/home/ubuntu/*.zip .",
                "context" : { "linuxip" : { "Fn::GetAtt" : [ "HybridCluster0", "PrivateIp" ] } }
              },
              "c:\\k\\cf-copy-all-from-linux.ps1" : {
                "content" : "echo y | c:\\k\\pscp.exe -r -2 -i c:\\k\\linux-node.ppk ubuntu@{{linuxip}}:/home/ubuntu/winfv/* c:\\k",
                "context" : { "linuxip" : { "Fn::GetAtt" : [ "HybridCluster0", "PrivateIp" ] } }
              },
              "c:\\k\\cf-copy-ready-from-linux.ps1" : {
                "content" : "echo y | c:\\k\\pscp.exe -2 -i c:\\k\\linux-node.ppk ubuntu@{{linuxip}}:/home/ubuntu/winfv/file-ready c:\\k",
                "context" : { "linuxip" : { "Fn::GetAtt" : [ "HybridCluster0", "PrivateIp" ] } }
              },
              "c:\\k\\cf-wait-till-ready.ps1" : {
                "content" : "while (!(Test-Path 'c:\\k\\file-ready')) { Start-Sleep 3; c:\\k\\cf-copy-ready-from-linux.ps1 }"
              },
              "C:\\k\\pscp.exe" : {
                "source" : "https://the.earth.li/~sgtatham/putty/0.73/w64/pscp.exe"
              }
            }
          },

          "2-unzip" : {
            "commands" : {
              "1-config-script" : {
                "command" : "powershell.exe -File c:\\k\\cf-wait-till-ready.ps1",
                "waitAfterCompletion": "0"
              },
              "2-config-script" : {
                "command" : "powershell.exe -File c:\\k\\cf-copy-all-from-linux.ps1",
                "waitAfterCompletion": "0"
              }
            }
          },

          "3-install" : {
            "commands" : {
              "1-install-bgp0" : {
                "command" : "powershell.exe -Command \"Install-WindowsFeature RemoteAccess\"",
                "test" : "findstr calico-bgp c:\\k\\backend",
                "waitAfterCompletion": "3"
              },
              "1-install-bgp1" : {
                "command" : "powershell.exe -Command \"Install-WindowsFeature RSAT-RemoteAccess-PowerShell\"",
                "test" : "findstr calico-bgp c:\\k\\backend",
                "waitAfterCompletion": "3"
              },
              "1-install-bgp2" : {
                "command" : "powershell.exe -Command \"Install-WindowsFeature Routing\"",
                "test" : "findstr calico-bgp c:\\k\\backend",
                "waitAfterCompletion": "3"
              },
              "1-install-bgp3-Restart-Computer" : {
                "command" : "powershell.exe -Command \"Restart-Computer -Force\"",
                "test" : "findstr calico-bgp c:\\k\\backend",
                "waitAfterCompletion": "forever"
              },
              "1-install-bgp4" : {
                "command" : "powershell.exe -Command \"Start-Sleep 60; Install-RemoteAccess -ErrorAction Ignore -VpnType RoutingOnly\"",
                "test" : "findstr calico-bgp c:\\k\\backend",
                "waitAfterCompletion": "0"
              },
              "2-install-docker1-enable-containers" : {
                "command": "powershell.exe -Command \"Install-WindowsFeature -Name Containers\"",
                "waitAfterCompletion": "3"
              },
              "2-install-docker2-Restart-Computer" : {
                "command": "powershell.exe -Command \"Restart-Computer -Force\"",
                "waitAfterCompletion": "forever"
              },
              "2-install-docker3" : {
                "command": "powershell.exe -Command \"Invoke-WebRequest -UseBasicParsing 'https://raw.githubusercontent.com/microsoft/Windows-Containers/Main/helpful_tools/Install-DockerCE/install-docker-ce.ps1' -o install-docker-ce.ps1; ./install-docker-ce.ps1\"",
                "waitAfterCompletion": "3"
              },
              "3-run-fv" : {
                "command": "powershell.exe -Command \"start-process powershell -argument 'C:\\k\\run-fv.ps1' -WindowStyle hidden -RedirectStandardOutput c:\\k\\cf-fv-log.txt\" ",
                "waitAfterCompletion": "0"
              }
            }
          }
        }
      },
      "Properties": {
        "InstanceType" : "t2.large",
        "ImageId" : { "Fn::FindInMap" : [ "AWSRegion2AMI", { "Ref" : "AWS::Region" }, { "Ref" : "WindowsOS" } ]},
        "SecurityGroupIds" : [ {"Ref" : "CurrentNodesSg"}, {"Ref" : "HybridClusterSecurityGroup"} ],
        "KeyName" : { "Ref" : "KeyName" },
        "SubnetId": { "Ref": "CurrentSubnet" },
        "SourceDestCheck": false,
        "Tags" : [ {"Key" : "Name", "Value" : { "Fn::Join" : [ "-", [ { "Ref": "AWS::StackName" }, "windows" ]]}} ],
        "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
          "<powershell>\n",

          "Set-ExecutionPolicy Unrestricted -Force\n",
          "Invoke-WebRequest -Uri https://curl.se/ca/cacert.pem -OutFile \"C:\\Program Files\\Amazon\\cfn-bootstrap\\cacert.pem\"\n",
          "cfn-init.exe -v -s ", { "Ref" : "AWS::StackId" }, 
          " -r HybridCluster1", " --configset calico",
          " --region ", { "Ref" : "AWS::Region" }, "\n",

          "</powershell>"

         ]]}}
        },
      "DependsOn" : "HybridCluster0"
    }

  },

  "Outputs" : {
    "InstanceId0" : {
      "Value" : { "Ref" : "HybridCluster0" },
      "Description" : "linux InstanceId"
    },
    
    "InstanceId1" : {
      "Value" : { "Ref" : "HybridCluster1" },
      "Description" : "Windows InstanceId"
    },

    "InstanceEIP0" : {
      "Value" : { "Ref" : "HybridCluster0EIP" },
      "Description" : "Linux Instance PublicIP"
    },

    "InstancePIP0" : {
      "Value" : { "Fn::GetAtt" : [ "HybridCluster0", "PrivateIp" ] },
      "Description" : "Linux Instance PrivateIP"
    },

    "InstanceEIP1" : {
      "Value" : { "Ref" : "HybridCluster1EIP" },
      "Description" : "Windows Instance PublicIP"
    },

    "InstancePIP1" : {
      "Value" : { "Fn::GetAtt" : [ "HybridCluster1", "PrivateIp" ] },
      "Description" : "Windows Instance PrivateIP"
    }

  }
}
