{
  "tagging" : {
    "permissions" : [ "ec2:CreateTags", "ec2:DeleteTags" ],
    "taggable" : true,
    "tagOnCreate" : true,
    "tagUpdatable" : true,
    "tagProperty" : "/properties/Tags",
    "cloudFormationSystemTags" : true
  },
  "$schema" : "https://raw.githubusercontent.com/aws-cloudformation/cloudformation-resource-schema/master/src/main/resources/schema/provider.definition.schema.v1.json",
  "deprecatedProperties" : [ "/properties/SecurityGroupEgress/*/SourceSecurityGroupId" ],
  "typeName" : "AWS::EC2::SecurityGroup",
  "readOnlyProperties" : [ "/properties/Id", "/properties/GroupId" ],
  "description" : "Resource Type definition for AWS::EC2::SecurityGroup",
  "createOnlyProperties" : [ "/properties/GroupDescription", "/properties/GroupName", "/properties/VpcId" ],
  "primaryIdentifier" : [ "/properties/Id" ],
  "required" : [ "GroupDescription" ],
  "propertyTransform" : {
    "/properties/SecurityGroupEgress/*/FromPort" : "($mapVal := $lookup({'1': 'icmp','6': 'tcp','17': 'udp','58': 'icmpv6'}, IpProtocol);$ipProtocol := $mapVal ? $mapVal : $lowercase(IpProtocol);$ipProtocol in ['imcp', 'tcp', 'udp', 'imcp'] ? FromPort : -1)",
    "/properties/SecurityGroupIngress/*/ToPort" : "($mapVal := $lookup({'1': 'icmp','6': 'tcp','17': 'udp','58': 'icmpv6'}, IpProtocol);$ipProtocol := $mapVal ? $mapVal : $lowercase(IpProtocol);$ipProtocol in ['imcp', 'tcp', 'udp', 'imcp'] ? ToPort : -1)",
    "/properties/SecurityGroupIngress/*/IpProtocol" : "($mapVal := $lookup({'1': 'icmp','6': 'tcp','17': 'udp','58': 'icmpv6'}, IpProtocol);$mapVal ? $mapVal : $lowercase(IpProtocol))",
    "/properties/SecurityGroupEgress/*/IpProtocol" : "($mapVal := $lookup({'1': 'icmp','6': 'tcp','17': 'udp','58': 'icmpv6'}, IpProtocol);$mapVal ? $mapVal : $lowercase(IpProtocol))",
    "/properties/SecurityGroupIngress/*/FromPort" : "($mapVal := $lookup({'1': 'icmp','6': 'tcp','17': 'udp','58': 'icmpv6'}, IpProtocol);$ipProtocol := $mapVal ? $mapVal : $lowercase(IpProtocol);$ipProtocol in ['imcp', 'tcp', 'udp', 'imcp'] ? FromPort : -1)",
    "/properties/SecurityGroupEgress/*/ToPort" : "($mapVal := $lookup({'1': 'icmp','6': 'tcp','17': 'udp','58': 'icmpv6'}, IpProtocol);$ipProtocol := $mapVal ? $mapVal : $lowercase(IpProtocol);$ipProtocol in ['imcp', 'tcp', 'udp', 'imcp'] ? ToPort : -1)"
  },
  "handlers" : {
    "read" : {
      "permissions" : [ "ec2:DescribeSecurityGroups" ]
    },
    "create" : {
      "permissions" : [ "ec2:CreateSecurityGroup", "ec2:DescribeSecurityGroups", "ec2:RevokeSecurityGroupEgress", "ec2:AuthorizeSecurityGroupEgress", "ec2:AuthorizeSecurityGroupIngress", "ec2:CreateTags" ]
    },
    "update" : {
      "permissions" : [ "ec2:RevokeSecurityGroupEgress", "ec2:RevokeSecurityGroupIngress", "ec2:DescribeSecurityGroups", "ec2:AuthorizeSecurityGroupEgress", "ec2:AuthorizeSecurityGroupIngress", "ec2:UpdateSecurityGroupRuleDescriptionsIngress", "ec2:UpdateSecurityGroupRuleDescriptionsEgress", "ec2:CreateTags", "ec2:DeleteTags" ]
    },
    "list" : {
      "permissions" : [ "ec2:DescribeSecurityGroups" ]
    },
    "delete" : {
      "permissions" : [ "ec2:DescribeSecurityGroups", "ec2:DeleteSecurityGroup", "ec2:DescribeInstances" ]
    }
  },
  "writeOnlyProperties" : [ "/properties/SecurityGroupIngress/*/SourceSecurityGroupName" ],
  "additionalProperties" : false,
  "definitions" : {
    "Ingress" : {
      "additionalProperties" : false,
      "type" : "object",
      "properties" : {
        "CidrIp" : {
          "type" : "string"
        },
        "CidrIpv6" : {
          "type" : "string"
        },
        "Description" : {
          "type" : "string"
        },
        "FromPort" : {
          "type" : "integer"
        },
        "SourceSecurityGroupName" : {
          "type" : "string"
        },
        "ToPort" : {
          "type" : "integer"
        },
        "SourceSecurityGroupOwnerId" : {
          "type" : "string"
        },
        "IpProtocol" : {
          "type" : "string"
        },
        "SourceSecurityGroupId" : {
          "type" : "string"
        },
        "SourcePrefixListId" : {
          "type" : "string"
        }
      },
      "required" : [ "IpProtocol" ]
    },
    "Egress" : {
      "additionalProperties" : false,
      "type" : "object",
      "properties" : {
        "CidrIp" : {
          "type" : "string"
        },
        "CidrIpv6" : {
          "type" : "string"
        },
        "Description" : {
          "type" : "string"
        },
        "FromPort" : {
          "type" : "integer"
        },
        "ToPort" : {
          "type" : "integer"
        },
        "IpProtocol" : {
          "type" : "string"
        },
        "DestinationSecurityGroupId" : {
          "type" : "string"
        },
        "DestinationPrefixListId" : {
          "type" : "string"
        }
      },
      "required" : [ "IpProtocol" ]
    },
    "Tag" : {
      "additionalProperties" : false,
      "type" : "object",
      "properties" : {
        "Value" : {
          "type" : "string"
        },
        "Key" : {
          "type" : "string"
        }
      },
      "required" : [ "Value", "Key" ]
    }
  },
  "properties" : {
    "GroupDescription" : {
      "description" : "A description for the security group.",
      "type" : "string"
    },
    "GroupName" : {
      "description" : "The name of the security group.",
      "type" : "string"
    },
    "VpcId" : {
      "description" : "The ID of the VPC for the security group.",
      "type" : "string"
    },
    "Id" : {
      "description" : "The group name or group ID depending on whether the SG is created in default or specific VPC",
      "type" : "string"
    },
    "SecurityGroupIngress" : {
      "uniqueItems" : false,
      "description" : "The inbound rules associated with the security group. There is a short interruption during which you cannot connect to the security group.",
      "insertionOrder" : false,
      "type" : "array",
      "items" : {
        "$ref" : "#/definitions/Ingress"
      }
    },
    "SecurityGroupEgress" : {
      "uniqueItems" : false,
      "description" : "[VPC only] The outbound rules associated with the security group. There is a short interruption during which you cannot connect to the security group.",
      "insertionOrder" : false,
      "type" : "array",
      "items" : {
        "$ref" : "#/definitions/Egress"
      }
    },
    "Tags" : {
      "uniqueItems" : false,
      "description" : "Any tags assigned to the security group.",
      "insertionOrder" : false,
      "type" : "array",
      "items" : {
        "$ref" : "#/definitions/Tag"
      }
    },
    "GroupId" : {
      "description" : "The group ID of the specified security group.",
      "type" : "string"
    }
  }
}