{
  "AWSTemplateFormatVersion":"2010-09-09",
  "Description":"Aviatrix integration with Control Tower to create and attach VPC on new account creation",
  "Parameters":{
    "VpcCIDR":{
      "Description":"Please enter the IP range (CIDR notation) for this VPC",
      "Type":"String",
      "Default":"10.254.0.0/27"
    },
    "PrivateSubnet1CIDR":{
      "Description":"Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone",
      "Type":"String",
      "Default":"10.254.0.0/28"
    },
    "PrivateSubnet2CIDR":{
      "Description":"Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone",
      "Type":"String",
      "Default":"10.254.0.16/28"
    },
    "ctrlaccount":{
      "Type":"String",
      "Description":"The AWS account# where the Aviatrix Controller resides"
    },
    "transitgateway":{
      "Type":"String",
      "Description":"Name of the AWS or Aviatrix Transit GW for VPC attachment"
    },
    "avtxtransit":{
      "Type":"String",
      "AllowedValues":[
        "true",
        "false"
      ],
      "Default":"false",
      "Description":"Set to true if using Aviatrix Transit GW, false if using AWS Transit GW"
    },
    "vpcaddressrange":{
      "Type":"String",
      "Default":"10.0.0.0/8",
      "Description":"Address space in which VPC CIDRs will be generated"
    },
    "vpcmasklength":{
      "Type":"String",
      "Default":"24",
      "Description":"Mask length to dictate size of created VPC"
    }
  },
  "Resources":{
    "VPC":{
      "Type":"AWS::EC2::VPC",
      "Properties":{
        "CidrBlock":{
          "Ref":"VpcCIDR"
        },
        "EnableDnsSupport":true,
        "EnableDnsHostnames":true,
        "Tags":[
          {
            "Key":"Name",
            "Value":"AviatrixControlTowerLambdaVPC"
          }
        ]
      }
    },
    "PrivateSubnet1":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"VPC"
        },
        "AvailabilityZone":{
          "Fn::Select":[
            0,
            {
              "Fn::GetAZs":{
                "Ref":"AWS::Region"
              }
            }
          ]
        },
        "CidrBlock":{
          "Ref":"PrivateSubnet1CIDR"
        },
        "MapPublicIpOnLaunch":false,
        "Tags":[
          {
            "Key":"Name",
            "Value":"AviatrixControlTowerLambdaPvtSubnet1"
          }
        ]
      }
    },
    "PrivateSubnet2":{
      "Type":"AWS::EC2::Subnet",
      "Properties":{
        "VpcId":{
          "Ref":"VPC"
        },
        "AvailabilityZone":{
          "Fn::Select":[
            1,
            {
              "Fn::GetAZs":{
                "Ref":"AWS::Region"
              }
            }
          ]
        },
        "CidrBlock":{
          "Ref":"PrivateSubnet2CIDR"
        },
        "MapPublicIpOnLaunch":false,
        "Tags":[
          {
            "Key":"Name",
            "Value":"AviatrixControlTowerLambdaPvtSubnet2"
          }
        ]
      }
    },
    "PrivateRouteTable":{
      "Type":"AWS::EC2::RouteTable",
      "Properties":{
        "VpcId":{
          "Ref":"VPC"
        },
        "Tags":[
          {
            "Key":"Name",
            "Value":"AviatrixControlTowerLambdaPvtRouteTable"
          }
        ]
      }
    },
    "PrivateSubnet1RouteTableAssociation":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        },
        "SubnetId":{
          "Ref":"PrivateSubnet1"
        }
      }
    },
    "PrivateSubnet2RouteTableAssociation":{
      "Type":"AWS::EC2::SubnetRouteTableAssociation",
      "Properties":{
        "RouteTableId":{
          "Ref":"PrivateRouteTable"
        },
        "SubnetId":{
          "Ref":"PrivateSubnet2"
        }
      }
    },
    "Ec2VpcEndpoint":{
      "Type":"AWS::EC2::VPCEndpoint",
      "Properties":{
        "PrivateDnsEnabled":"true",
        "SecurityGroupIds":[
          "Fn::GetAtt":          [
            "VPC",
            "DefaultSecurityGroup"
          ]
        ],
        "ServiceName":{
          "Fn::Join":[
            ".",
            [
              "com.amazonaws",
              {
                "Ref":"AWS::Region"
              },
              "ec2"
            ]
          ]
        },
        "SubnetIds":[
          {
            "Ref":"PrivateSubnet1"
          },
          {
            "Ref":"PrivateSubnet2"
          }
        ],
        "VpcEndpointType":"Interface",
        "VpcId":{
          "Ref":"VPC"
        }
      }
    },
    "StsVpcEndpoint":{
      "Type":"AWS::EC2::VPCEndpoint",
      "Properties":{
        "PrivateDnsEnabled":"true",
        "SecurityGroupIds":[
          "Fn::GetAtt":          [
            "VPC",
            "DefaultSecurityGroup"
          ]
        ],
        "ServiceName":{
          "Fn::Join":[
            ".",
            [
              "com.amazonaws",
              {
                "Ref":"AWS::Region"
              },
              "sts"
            ]
          ]
        },
        "SubnetIds":[
          {
            "Ref":"PrivateSubnet1"
          },
          {
            "Ref":"PrivateSubnet2"
          }
        ],
        "VpcEndpointType":"Interface",
        "VpcId":{
          "Ref":"VPC"
        }
      }
    },
    "CfVpcEndpoint":{
      "Type":"AWS::EC2::VPCEndpoint",
      "Properties":{
        "PrivateDnsEnabled":"true",
        "SecurityGroupIds":[
          "Fn::GetAtt":          [
            "VPC",
            "DefaultSecurityGroup"
          ]
        ],
        "ServiceName":{
          "Fn::Join":[
            ".",
            [
              "com.amazonaws",
              {
                "Ref":"AWS::Region"
              },
              "cloudformation"
            ]
          ]
        },
        "SubnetIds":[
          {
            "Ref":"PrivateSubnet1"
          },
          {
            "Ref":"PrivateSubnet2"
          }
        ],
        "VpcEndpointType":"Interface",
        "VpcId":{
          "Ref":"VPC"
        }
      }
    },
    "SsmVpcEndpoint":{
      "Type":"AWS::EC2::VPCEndpoint",
      "Properties":{
        "PrivateDnsEnabled":"true",
        "SecurityGroupIds":[
          "Fn::GetAtt":          [
            "VPC",
            "DefaultSecurityGroup"
          ]
        ],
        "ServiceName":{
          "Fn::Join":[
            ".",
            [
              "com.amazonaws",
              {
                "Ref":"AWS::Region"
              },
              "ssm"
            ]
          ]
        },
        "SubnetIds":[
          {
            "Ref":"PrivateSubnet1"
          },
          {
            "Ref":"PrivateSubnet2"
          }
        ],
        "VpcEndpointType":"Interface",
        "VpcId":{
          "Ref":"VPC"
        }
      }
    },
    "EventRule":{
      "Type":"AWS::Events::Rule",
      "Properties":{
        "Description":"EventRule",
        "EventPattern":{
          "source":[
            "aws.controltower"
          ],
          "detail-type":[
            "AWS Service Event via CloudTrail"
          ],
          "detail":{
            "eventName":[
              "CreateManagedAccount"
            ],
            "serviceEventDetails":{
              "createManagedAccountStatus":{
                "state":[
                  "SUCCEEDED"
                ]
              }
            }
          }
        },
        "Targets":[
          {
            "Arn":{
              "Fn::GetAtt":[
                "LambdaFunction",
                "Arn"
              ]
            },
            "Id":"CreateManagedAccount"
          }
        ]
      }
    },
    "PermissionForEventsToInvokeLambda":{
      "Type":"AWS::Lambda::Permission",
      "Properties":{
        "FunctionName":{
          "Ref":"LambdaFunction"
        },
        "Action":"lambda:InvokeFunction",
        "Principal":"events.amazonaws.com",
        "SourceArn":{
          "Fn::GetAtt":[
            "EventRule",
            "Arn"
          ]
        }
      }
    },
    "LambdaFunction":{
      "Type":"AWS::Lambda::Function",
      "Properties":{
        "Handler":"vpc_attach.lambda_handler",
        "Role":{
          "Fn::GetAtt":[
            "LambdaExecutionRole",
            "Arn"
          ]
        },
        "Code":{
          "S3Bucket":{
            "Fn::Join":[
              "-",
              [
                "aviatrix-lambda",
                {
                  "Ref":"AWS::Region"
                }
              ]
            ]
          },
          "S3Key":"vpc_attach.zip"
        },
        "VpcConfig":{
          "SubnetIds":[
            {
              "Ref":"PrivateSubnet1"
            },
            {
              "Ref":"PrivateSubnet2"
            }
          ],
          "SecurityGroupIds":[
            "Fn::GetAtt":            [
              "VPC",
              "DefaultSecurityGroup"
            ]
          ]
        },
        "Environment":{
          "Variables":{
            "CTRL_ACC":{
              "Ref":"ctrlaccount"
            },
            "TRANSIT_GW":{
              "Ref":"transitgateway"
            },
            "AVTX_TRANSIT":{
              "Ref":"avtxtransit"
            },
            "VPC_ADDR_RANGE":{
              "Ref":"vpcaddressrange"
            },
            "VPC_MASK_LENGTH":{
              "Ref":"vpcmasklength"
            }
          }
        },
        "Runtime":"python3.7",
        "Timeout":900
      }
    },
    "LambdaExecutionRole":{
      "Type":"AWS::IAM::Role",
      "Description":"Aviatrix integration with Control Tower Lambda Role",
      "Properties":{
        "AssumeRolePolicyDocument":{
          "Version":"2012-10-17",
          "Statement":[
            {
              "Effect":"Allow",
              "Principal":{
                "Service":[
                  "lambda.amazonaws.com"
                ]
              },
              "Action":[
                "sts:AssumeRole"
              ]
            }
          ]
        },
        "ManagedPolicyArns":[
          "Ref" : "LambdaExecutionPolicy"
        ]
      }
    },
    "LambdaExecutionPolicy":{
      "Type":"AWS::IAM::ManagedPolicy",
      "Properties":{
        "ManagedPolicyName":"AviatrixControlTowerLambda",
        "Description":"Policy for creating a test database",
        "PolicyDocument":{
          "Version":"2012-10-17",
          "Statement":[
            {
              "Effect":"Allow",
              "Action":[
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
              ],
              "Resource":"arn:aws:logs:::*"
            },
            {
              "Effect": "Allow",
              "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DeleteNetworkInterface",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeVpcs"
              ],
              "Resource": "*"
            },
            {
              "Effect": "Allow",
              "Action": "sts:AssumeRole",
              "Resource": "arn:aws:iam::*:role/AWSControlTowerExecution"
            },
            {
              "Effect": "Allow",
              "Action": [
                "ssm:GetParametersByPath",
                "ssm:GetParameters",
                "ssm:GetParameter"
              ],
              "Resource": "arn:aws:ssm:*:*:parameter/aviatrix/*"
            }
          ]
        }
      }
    }
  }
}
