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

  "Parameters": {
    "ArnPartition": {
      "Description": "ARN partition used in current AWS environment.",
      "Type": "String"
    },
    "AwsEndpoint": {
      "Description": "AWS endpoint used in current environment.",
      "Type": "String"
    },
    "GatewayAccountId": {
      "Description": "ID of AWS account where GW is deployed.",
      "Type": "String"
    },
    "GatewayRoleName": {
      "Description": "Role for Gateway to be able to assume role and get access to resources.",
      "Type": "String"
    },
    "GatewayExternalId": {
      "Description": "External Id for Gateway to utilize when assuming role.",
      "Type": "String"
    },
    "ClusterNodeRoleName": {
      "Description": "Role for Cluster Nodes.",
      "Type": "String"
    }
  },

  "Resources": {

    "MCMGatewayRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": { "Ref" : "GatewayRoleName" },
        "Path": "/",
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": "sts:AssumeRole",
              "Principal": {
                "AWS": {
                  "Fn::Join": [
                    "",
                    [
                      "arn:",
                      { "Ref":  "ArnPartition" },
                      ":iam::",
                      { "Ref":  "GatewayAccountId" },
                      ":root"]
                  ]
                }
              },
              "Condition": {
                "StringEquals": {
                  "sts:ExternalId": { "Ref" : "GatewayExternalId" }
                }
              }
            }
          ]
        }
      }
    },

    "MCMGatewayPolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "GatewayRoleName" },
              "-Policy"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "ec2:*Image",
                "ec2:*Images",
                "ec2:*Instances",
                "ec2:*PlacementGroup",
                "ec2:*SecurityGroup*",
                "ec2:AcceptVpcPeeringConnection",
                "ec2:AllocateAddress",
                "ec2:AllocateHosts",
                "ec2:AssociateAddress",
                "ec2:AssociateDhcpOptions",
                "ec2:AssociateRouteTable",
                "ec2:AttachInternetGateway",
                "ec2:CreateDefaultSubnet",
                "ec2:CreateDhcpOptions",
                "ec2:CreateInternetGateway",
                "ec2:CreateKeyPair",
                "ec2:CreateNatGateway",
                "ec2:CreateNetworkAcl",
                "ec2:CreateNetworkInterface",
                "ec2:CreateRoute",
                "ec2:CreateRouteTable",
                "ec2:CreateSubnet",
                "ec2:CreateTags",
                "ec2:CreateVpc",
                "ec2:CreateVpcEndpoint",
                "ec2:CreateVpcPeeringConnection",
                "ec2:DeleteDhcpOptions",
                "ec2:DeleteEgressOnlyInternetGateway",
                "ec2:DeleteInternetGateway",
                "ec2:DeleteKeyPair",
                "ec2:DeleteNatGateway",
                "ec2:DeleteNetworkAcl",
                "ec2:DeleteNetworkAclEntry",
                "ec2:DeleteNetworkInterface",
                "ec2:DeleteNetworkInterfacePermission",
                "ec2:DeleteRoute",
                "ec2:DeleteRouteTable",
                "ec2:DeleteSnapshot",
                "ec2:DeleteSubnet",
                "ec2:DeleteTags",
                "ec2:DeleteVpc",
                "ec2:DeleteVpcEndpoints",
                "ec2:DeleteVpcPeeringConnection",
                "ec2:DescribeAccountAttributes",
                "ec2:DescribeAddresses",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeDhcpOptions",
                "ec2:DescribeHosts",
                "ec2:DescribeInstanceAttribute",
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceTypes",
                "ec2:DescribeInstanceStatus",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeKeyPairs",
                "ec2:DescribeNatGateways",
                "ec2:DescribeNetworkAcls",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribePlacementGroups",
                "ec2:DescribeRouteTables",
                "ec2:DescribeSpotPriceHistory",
                "ec2:DescribeSubnets",
                "ec2:DescribeVolumesModifications",
                "ec2:DescribeVolumeStatus",
                "ec2:DescribeVpcAttribute",
                "ec2:DescribeVpcEndpoints",
                "ec2:DescribeVpcPeeringConnections",
                "ec2:DescribeVpcs",
                "ec2:DetachInternetGateway",
                "ec2:DetachNetworkInterface",
                "ec2:DisassociateAddress",
                "ec2:DisassociateIamInstanceProfile",
                "ec2:DisassociateRouteTable",
                "ec2:DisassociateSubnetCidrBlock",
                "ec2:DisassociateVpcCidrBlock",
                "ec2:ModifyImageAttribute",
                "ec2:ModifyInstanceAttribute",
                "ec2:ModifySubnetAttribute",
                "ec2:ModifyVpcAttribute",
                "ec2:ModifyVpcEndpoint",
                "ec2:ReleaseAddress",
                "ec2:ReleaseHosts",
                "ec2:ModifyNetworkInterfaceAttribute",
                "ec2:*Volume",
                "ec2:*Volumes",
                "elasticloadbalancing:DescribeLoadBalancerAttributes",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeTargetGroupAttributes",
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticloadbalancing:DescribeRules",
                "elasticloadbalancing:CreateLoadBalancer",
                "elasticloadbalancing:CreateTargetGroup",
                "elasticloadbalancing:CreateListener",
                "elasticloadbalancing:CreateRule",
                "elasticloadbalancing:RegisterTargets",
                "elasticloadbalancing:DeregisterTargets",
                "elasticloadbalancing:SetSubnets",
                "elasticloadbalancing:DeleteTargetGroup",
                "elasticloadbalancing:DeleteLoadBalancer",
                "elasticloadbalancing:AddTags",
                "elasticloadbalancing:RemoveTags",
                "elasticloadbalancing:DeleteRule",
                "elasticloadbalancing:ModifyTargetGroup",
                "elasticloadbalancing:DeleteListener",
                "iam:CreateServiceLinkedRole",
                "iam:GetRole",
                "iam:ListInstanceProfilesForRole",
                "iam:PassRole",
                "s3:CreateBucket",
                "s3:GetObject",
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "s3:PutBucketPolicy",
                "s3:PutBucketTagging",
                "s3:GetBucketTagging",
                "s3:PutObject",
                "s3:PutLifecycleConfiguration",
                "s3:PutEncryptionConfiguration",
                "s3:PutBucketPublicAccessBlock",
                "servicequotas:GetServiceQuota",
                "servicequotas:ListServiceQuotas",
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey",
                "kms:CreateGrant"
              ],
              "Resource": [ "*" ]
            }
          ]
        },
        "Roles": [
          { "Ref":  "GatewayRoleName" }
        ]
      },
      "DependsOn": "MCMGatewayRole"
    },

    "ClusterNodeRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": { "Ref" : "ClusterNodeRoleName" },
        "Path": "/",
        "AssumeRolePolicyDocument": {
           "Version" : "2012-10-17",
           "Statement": [
             {
                "Effect": "Allow",
                "Principal": {
                   "Service": {
                      "Fn::Join": [
                        "",
                        [
                          "ec2.",
                          { "Ref":  "AwsEndpoint" }
                        ]
                      ]
                    }
                },
                "Action": [
                  "sts:AssumeRole"
                ]
             }
           ]
        }
      }
    },

    "ClusterNodeEC2InstancesDescriptionReadAccessForAgentsPolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-EC2InstancesDescriptionReadAccessForAgents"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
             "Effect": "Allow",
             "Action": [
               "ec2:DescribeInstances",
               "ec2:DescribeNetworkInterfaces",
               "ec2:DescribeTags"
             ],
             "Resource": [
               "*"
             ]
            }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeEC2InstancesDescriptionReadAccessForNetworkingPolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-EC2InstancesDescriptionReadAccessForNetworking"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
             "Effect": "Allow",
             "Action": [
               "ec2:DescribeInstances",
               "ec2:DescribeInstanceTypes"
             ],
             "Resource": [
               "*"
             ]
            }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeEC2NetworksDescriptionReadAccessForNetworkingPolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-EC2NetworksDescriptionReadAccessForNetworking"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
             "Effect": "Allow",
             "Action": [
               "ec2:DescribeSubnets",
               "ec2:DescribeVpcs",
               "ec2:CreateSubnet",
               "ec2:DeleteSubnet"
             ],
             "Resource": [
               "*"
             ]
            }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeEC2SubnetsTagsFullAccessForNetworkingPolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-EC2SubnetsTagsFullAccessForNetworking"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
             "Effect": "Allow",
             "Action": [
               "ec2:DescribeTags"
             ],
             "Resource": [
               "*"
             ]
            },
            {
             "Effect": "Allow",
             "Action": [
               "ec2:CreateTags",
               "ec2:DeleteTags"
             ],
             "Resource": [
               "arn:*:ec2:*:*:subnet/*"
             ]
            }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeEC2NetworkInterfacessFullAccessForNetworkingPolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-EC2NetworkInterfacessFullAccessForNetworking"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
             "Effect": "Allow",
             "Action": [
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribeNetworkInterfaceAttribute",
                "ec2:ModifyNetworkInterfaceAttribute",
                "ec2:CreateNetworkInterface",
                "ec2:DeleteNetworkInterface",
                "ec2:AttachNetworkInterface",
                "ec2:DetachNetworkInterface",
                "ec2:DescribeTags"
             ],
             "Resource": [
               "*"
             ]
            },
            {
             "Effect": "Allow",
             "Action": [
               "ec2:CreateTags",
               "ec2:DeleteTags"
             ],
             "Resource": [
               "arn:*:ec2:*:*:network-interface/*"
             ]
            }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeEC2SecurityGroupsFullAccessForNetworkingPolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-EC2SecurityGroupsFullAccessForNetworking"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
             "Effect": "Allow",
             "Action": [
               "ec2:CreateSecurityGroup",
               "ec2:DescribeSecurityGroups",
               "ec2:DescribeTags"
             ],
             "Resource": [
               "*"
             ]
            },
            {
             "Effect": "Allow",
             "Action": [
                "ec2:RevokeSecurityGroupEgress",
                "ec2:RevokeSecurityGroupIngress",
                "ec2:AuthorizeSecurityGroupEgress",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:UpdateSecurityGroupRuleDescriptionsEgress",
                "ec2:UpdateSecurityGroupRuleDescriptionsIngress",
                "ec2:DeleteSecurityGroup",
                "ec2:CreateTags",
                "ec2:DeleteTags"
             ],
             "Resource": [
               "arn:*:ec2:*:*:security-group/*"
             ]
            }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeEC2PrivateIpAddressesFullAccessForNetworkingPolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-EC2PrivateIpAddressesFullAccessForNetworking"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
             {
               "Effect": "Allow",
               "Action": [
                 "ec2:AssignPrivateIpAddresses",
                 "ec2:UnassignPrivateIpAddresses"
               ],
               "Resource": [
                 "*"
               ]
             }
          ]
        },
        "Roles": [
          { "Ref": "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },
    "ClusterNodeEC2RouteTablesFullAccessForNetworkingPolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref": "ClusterNodeRoleName" },
              "-Policy-EC2RouteTablesFullAccessForNetworking"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "ec2:CreateRoute",
                "ec2:ReplaceRoute",
                "ec2:DeleteRoute",
                "ec2:DescribeRouteTables"
              ],
              "Resource": [
                "*"
              ]
            }
          ]
        },
        "Roles": [
          { "Ref": "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },
    "ClusterNodeS3BucketsListAccessForHibernatePolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref": "ClusterNodeRoleName" },
              "-Policy-S3BucketsListAccessForHibernate"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
             {
               "Effect": "Allow",
               "Action": [
                 "s3:ListBucket",
                 "s3:ListBucketMultipartUploads"
               ],
               "Resource": [
                 "arn:*:s3:::nutanix-clusters-hb-*",
                 "arn:*:s3:::*-nutanix-cluster-hibernate"
               ]
             }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeS3ObjectsFullAccessForHibernatePolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-S3ObjectsFullAccessForHibernate"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
             {
               "Effect": "Allow",
               "Action": [
                  "s3:GetObject",
                  "s3:PutObject",
                  "s3:DeleteObject",
                  "s3:ListMultipartUploadParts",
                  "s3:AbortMultipartUpload"
               ],
               "Resource": [
                 "arn:*:s3:::nutanix-clusters-hb-*/*",
                 "arn:*:s3:::*-nutanix-cluster-hibernate/*"
               ]
             }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },
    "ClusterNodeS3BucketsListAccessForSnap2S3Policy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              {
                "Ref": "ClusterNodeRoleName"
              },
              "-Policy-S3BucketsListAccessForSnap2S3"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads"
              ],
              "Resource": [
                "arn:*:s3:::nutanix-clusters*"
              ]
            }
          ]
        },
        "Roles": [
          {
            "Ref": "ClusterNodeRoleName"
          }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },
    "ClusterNodeS3ObjectsFullAccessForSnap2S3Policy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-S3ObjectsFullAccessForSnap2S3"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
             {
               "Effect": "Allow",
               "Action": [
                  "s3:GetObject",
                  "s3:PutObject",
                  "s3:DeleteObject",
                  "s3:ListMultipartUploadParts",
                  "s3:AbortMultipartUpload"
               ],
               "Resource": [
                 "arn:*:s3:::nutanix-clusters*/*"
               ]
             }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeEC2NetworkInterfacesDeleteAccessForHibernatePolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-EC2NetworkInterfacesDeleteAccessForHibernate"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
             {
               "Effect": "Allow",
               "Action": [
                  "ec2:DescribeNetworkInterfaces",
                  "ec2:DetachNetworkInterface",
                  "ec2:DeleteNetworkInterface"
               ],
               "Resource": [
                 "*"
               ]
             }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeInstanceProfile": {
       "Type": "AWS::IAM::InstanceProfile",
       "Properties": {
          "Path": "/",
          "Roles": [
            { "Ref":  "ClusterNodeRoleName" }
          ],
          "InstanceProfileName": { "Ref":  "ClusterNodeRoleName" }
       },
       "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeEC2PrivateIpAddressesAssignAccessForAgents": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-EC2PrivateIpAddressesAssignAccessForAgents"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
             {
               "Effect": "Allow",
               "Action": [
                  "ec2:AssignPrivateIpAddresses"
               ],
               "Resource": [
                 "*"
               ]
             }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeEC2ReadAccessForTroubleshooting": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-EC2ReadAccessForTroubleshooting"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
             {
               "Effect": "Allow",
               "Action": [
                 "ec2:DescribeDhcpOptions",
                 "ec2:DescribeInstanceAttribute",
                 "ec2:DescribeInstanceStatus",
                 "ec2:DescribeInstanceTypes",
                 "ec2:DescribeInstances",
                 "ec2:DescribeNetworkInterfaceAttribute",
                 "ec2:DescribeNetworkInterfacePermissions",
                 "ec2:DescribeNetworkInterfaces",
                 "ec2:DescribePlacementGroups",
                 "ec2:DescribeSubnets",
                 "ec2:DescribeVpcAttribute",
                 "ec2:DescribeVpcs",
                 "ec2:GetConsoleOutput"
               ],
               "Resource": [
                 "*"
               ]
             }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    },

    "ClusterNodeEC2ReadAccessForServiceQuotas": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyName": {
          "Fn::Join": [
            "",
            [
              { "Ref":  "ClusterNodeRoleName" },
              "-Policy-EC2ReadAccessForServiceQuotas"
            ]
          ]
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
             {
               "Effect": "Allow",
               "Action": [
                 "servicequotas:GetServiceQuota",
                 "servicequotas:ListServiceQuotas"
               ],
               "Resource": [
                 "*"
               ]
             }
          ]
        },
        "Roles": [
          { "Ref":  "ClusterNodeRoleName" }
        ]
      },
      "DependsOn": "ClusterNodeRole"
    }
  }
}
