{
  "typeName" : "AWS::FMS::Policy",
  "description" : "Creates an AWS Firewall Manager policy.",
  "sourceUrl" : "https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-fms.git",
  "definitions" : {
    "AccountId" : {
      "description" : "An AWS account ID.",
      "type" : "string",
      "pattern" : "^([0-9]*)$",
      "minLength" : 12,
      "maxLength" : 12
    },
    "Base62Id" : {
      "description" : "A Base62 ID",
      "type" : "string",
      "pattern" : "^[a-z0-9A-Z]{22}$",
      "minLength" : 22,
      "maxLength" : 22
    },
    "OrganizationalUnitId" : {
      "description" : "An Organizational Unit ID.",
      "type" : "string",
      "pattern" : "^(ou-[0-9a-z]{4,32}-[a-z0-9]{8,32})$",
      "minLength" : 16,
      "maxLength" : 68
    },
    "IEMap" : {
      "description" : "An FMS includeMap or excludeMap.",
      "type" : "object",
      "properties" : {
        "ACCOUNT" : {
          "type" : "array",
          "items" : {
            "$ref" : "#/definitions/AccountId"
          },
          "insertionOrder" : true
        },
        "ORGUNIT" : {
          "type" : "array",
          "items" : {
            "$ref" : "#/definitions/OrganizationalUnitId"
          },
          "insertionOrder" : true
        }
      },
      "additionalProperties" : false
    },
    "PolicyTag" : {
      "description" : "A policy tag.",
      "type" : "object",
      "properties" : {
        "Key" : {
          "type" : "string",
          "pattern" : "^([^\\s]*)$",
          "minLength" : 1,
          "maxLength" : 128
        },
        "Value" : {
          "type" : "string",
          "pattern" : "^([^\\s]*)$",
          "maxLength" : 256
        }
      },
      "additionalProperties" : false,
      "required" : [ "Key", "Value" ]
    },
    "ResourceTag" : {
      "description" : "A resource tag.",
      "type" : "object",
      "properties" : {
        "Key" : {
          "type" : "string",
          "minLength" : 1,
          "maxLength" : 128
        },
        "Value" : {
          "type" : "string",
          "maxLength" : 256
        }
      },
      "additionalProperties" : false,
      "required" : [ "Key" ]
    },
    "ResourceType" : {
      "description" : "An AWS resource type",
      "type" : "string",
      "pattern" : "^([^\\s]*)$",
      "minLength" : 1,
      "maxLength" : 128
    },
    "ResourceArn" : {
      "description" : "A resource ARN.",
      "type" : "string",
      "pattern" : "^([^\\s]*)$",
      "minLength" : 1,
      "maxLength" : 1024
    },
    "SecurityServicePolicyData" : {
      "description" : "Firewall security service policy data.",
      "type" : "object",
      "properties" : {
        "ManagedServiceData" : {
          "$ref" : "#/definitions/ManagedServiceData"
        },
        "Type" : {
          "$ref" : "#/definitions/PolicyType"
        },
        "PolicyOption" : {
          "$ref" : "#/definitions/PolicyOption"
        }
      },
      "additionalProperties" : false,
      "required" : [ "Type" ]
    },
    "FirewallDeploymentModel" : {
      "description" : "Firewall deployment mode.",
      "type" : "string",
      "enum" : [ "DISTRIBUTED", "CENTRALIZED" ]
    },
    "NetworkAclEntry" : {
      "description" : "Network ACL entry.",
      "type" : "object",
      "properties" : {
        "CidrBlock" : {
          "description" : "CIDR block.",
          "type" : "string",
          "pattern" : "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$"
        },
        "Egress" : {
          "description" : "Whether the entry is an egress entry.",
          "type" : "boolean"
        },
        "IcmpTypeCode" : {
          "description" : "ICMP type and code.",
          "type" : "object",
          "properties" : {
            "Code" : {
              "description" : "Code.",
              "type" : "integer",
              "minimum" : 0,
              "maximum" : 255
            },
            "Type" : {
              "description" : "Type.",
              "type" : "integer",
              "minimum" : 0,
              "maximum" : 255
            }
          },
          "additionalProperties" : false,
          "required" : [ "Code", "Type" ]
        },
        "Ipv6CidrBlock" : {
          "type" : "string",
          "description" : "IPv6 CIDR block.",
          "pattern" : "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(/(1[0-2]|[0-9]))?$"
        },
        "PortRange" : {
          "type" : "object",
          "description" : "Port range.",
          "properties" : {
            "From" : {
              "description" : "From Port.",
              "type" : "integer",
              "minimum" : 0,
              "maximum" : 65535
            },
            "To" : {
              "description" : "To Port.",
              "type" : "integer",
              "minimum" : 0,
              "maximum" : 65535
            }
          },
          "additionalProperties" : false,
          "required" : [ "From", "To" ]
        },
        "Protocol" : {
          "description" : "Protocol.",
          "type" : "string",
          "pattern" : "^(tcp|udp|icmp|-1|([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))$"
        },
        "RuleAction" : {
          "description" : "Rule Action.",
          "type" : "string",
          "enum" : [ "allow", "deny" ]
        }
      },
      "additionalProperties" : false,
      "required" : [ "Egress", "Protocol", "RuleAction" ]
    },
    "NetworkAclEntryList" : {
      "description" : "NetworkAcl entry list.",
      "type" : "array",
      "items" : {
        "$ref" : "#/definitions/NetworkAclEntry"
      },
      "insertionOrder" : true
    },
    "NetworkAclEntrySet" : {
      "description" : "Network ACL entry set.",
      "type" : "object",
      "properties" : {
        "FirstEntries" : {
          "$ref" : "#/definitions/NetworkAclEntryList"
        },
        "ForceRemediateForFirstEntries" : {
          "type" : "boolean"
        },
        "LastEntries" : {
          "$ref" : "#/definitions/NetworkAclEntryList"
        },
        "ForceRemediateForLastEntries" : {
          "type" : "boolean"
        }
      },
      "additionalProperties" : false,
      "required" : [ "ForceRemediateForFirstEntries", "ForceRemediateForLastEntries" ],
      "anyOf" : [ {
        "required" : [ "FirstEntries" ]
      }, {
        "required" : [ "LastEntries" ]
      } ]
    },
    "ManagedServiceData" : {
      "description" : "Firewall managed service data.",
      "type" : "string",
      "minLength" : 1,
      "maxLength" : 30000
    },
    "PolicyType" : {
      "description" : "Firewall policy type.",
      "type" : "string",
      "enum" : [ "WAF", "WAFV2", "SHIELD_ADVANCED", "SECURITY_GROUPS_COMMON", "SECURITY_GROUPS_CONTENT_AUDIT", "SECURITY_GROUPS_USAGE_AUDIT", "NETWORK_FIREWALL", "THIRD_PARTY_FIREWALL", "DNS_FIREWALL", "IMPORT_NETWORK_FIREWALL", "NETWORK_ACL_COMMON" ]
    },
    "NetworkFirewallPolicy" : {
      "description" : "Network firewall policy.",
      "type" : "object",
      "properties" : {
        "FirewallDeploymentModel" : {
          "$ref" : "#/definitions/FirewallDeploymentModel"
        }
      },
      "additionalProperties" : false,
      "required" : [ "FirewallDeploymentModel" ]
    },
    "ThirdPartyFirewallPolicy" : {
      "description" : "Third party firewall policy.",
      "type" : "object",
      "properties" : {
        "FirewallDeploymentModel" : {
          "$ref" : "#/definitions/FirewallDeploymentModel"
        }
      },
      "additionalProperties" : false,
      "required" : [ "FirewallDeploymentModel" ]
    },
    "NetworkAclCommonPolicy" : {
      "description" : "Network ACL common policy.",
      "type" : "object",
      "properties" : {
        "NetworkAclEntrySet" : {
          "$ref" : "#/definitions/NetworkAclEntrySet"
        }
      },
      "additionalProperties" : false,
      "required" : [ "NetworkAclEntrySet" ]
    },
    "PolicyOption" : {
      "description" : "Firewall policy option.",
      "type" : "object",
      "properties" : {
        "NetworkFirewallPolicy" : {
          "$ref" : "#/definitions/NetworkFirewallPolicy"
        },
        "ThirdPartyFirewallPolicy" : {
          "$ref" : "#/definitions/ThirdPartyFirewallPolicy"
        },
        "NetworkAclCommonPolicy" : {
          "$ref" : "#/definitions/NetworkAclCommonPolicy"
        }
      },
      "additionalProperties" : false,
      "oneOf" : [ {
        "required" : [ "NetworkFirewallPolicy" ]
      }, {
        "required" : [ "ThirdPartyFirewallPolicy" ]
      }, {
        "required" : [ "NetworkAclCommonPolicy" ]
      } ]
    }
  },
  "properties" : {
    "ExcludeMap" : {
      "$ref" : "#/definitions/IEMap"
    },
    "ExcludeResourceTags" : {
      "type" : "boolean"
    },
    "IncludeMap" : {
      "$ref" : "#/definitions/IEMap"
    },
    "Id" : {
      "type" : "string",
      "pattern" : "^[a-z0-9A-Z-]{36}$",
      "minLength" : 36,
      "maxLength" : 36
    },
    "PolicyName" : {
      "type" : "string",
      "pattern" : "^([a-zA-Z0-9_.:/=+\\-@\\s]+)$",
      "minLength" : 1,
      "maxLength" : 1024
    },
    "PolicyDescription" : {
      "type" : "string",
      "pattern" : "^([a-zA-Z0-9_.:/=+\\-@\\s]+)$",
      "maxLength" : 256
    },
    "RemediationEnabled" : {
      "type" : "boolean"
    },
    "ResourceTags" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/definitions/ResourceTag"
      },
      "maxItems" : 50,
      "insertionOrder" : true
    },
    "ResourceTagLogicalOperator" : {
      "type" : "string",
      "enum" : [ "AND", "OR" ]
    },
    "ResourceType" : {
      "$ref" : "#/definitions/ResourceType"
    },
    "ResourceTypeList" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/definitions/ResourceType"
      },
      "insertionOrder" : true
    },
    "ResourceSetIds" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/definitions/Base62Id"
      },
      "insertionOrder" : true,
      "uniqueItems" : true
    },
    "SecurityServicePolicyData" : {
      "$ref" : "#/definitions/SecurityServicePolicyData"
    },
    "Arn" : {
      "$ref" : "#/definitions/ResourceArn"
    },
    "DeleteAllPolicyResources" : {
      "type" : "boolean"
    },
    "ResourcesCleanUp" : {
      "type" : "boolean"
    },
    "Tags" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/definitions/PolicyTag"
      },
      "insertionOrder" : true
    }
  },
  "tagging" : {
    "taggable" : true,
    "tagOnCreate" : true,
    "tagUpdatable" : true,
    "cloudFormationSystemTags" : true,
    "tagProperty" : "/properties/Tags",
    "permissions" : [ "fms:TagResource", "fms:UntagResource" ]
  },
  "additionalProperties" : false,
  "required" : [ "ExcludeResourceTags", "PolicyName", "RemediationEnabled", "SecurityServicePolicyData" ],
  "readOnlyProperties" : [ "/properties/Arn", "/properties/Id" ],
  "writeOnlyProperties" : [ "/properties/DeleteAllPolicyResources" ],
  "primaryIdentifier" : [ "/properties/Id" ],
  "handlers" : {
    "create" : {
      "permissions" : [ "fms:PutPolicy", "fms:TagResource", "waf-regional:ListRuleGroups", "wafv2:CheckCapacity", "wafv2:ListRuleGroups", "wafv2:ListAvailableManagedRuleGroups", "wafv2:ListAvailableManagedRuleGroupVersions", "network-firewall:DescribeRuleGroup", "network-firewall:DescribeRuleGroupMetadata", "route53resolver:ListFirewallRuleGroups", "ec2:DescribeAvailabilityZones", "s3:PutBucketPolicy", "s3:GetBucketPolicy" ]
    },
    "update" : {
      "permissions" : [ "fms:PutPolicy", "fms:GetPolicy", "fms:TagResource", "fms:UntagResource", "fms:ListTagsForResource", "waf-regional:ListRuleGroups", "wafv2:CheckCapacity", "wafv2:ListRuleGroups", "wafv2:ListAvailableManagedRuleGroups", "wafv2:ListAvailableManagedRuleGroupVersions", "network-firewall:DescribeRuleGroup", "network-firewall:DescribeRuleGroupMetadata", "route53resolver:ListFirewallRuleGroups", "ec2:DescribeAvailabilityZones", "s3:PutBucketPolicy", "s3:GetBucketPolicy" ]
    },
    "read" : {
      "permissions" : [ "fms:GetPolicy", "fms:ListTagsForResource" ]
    },
    "delete" : {
      "permissions" : [ "fms:DeletePolicy" ]
    },
    "list" : {
      "permissions" : [ "fms:ListPolicies", "fms:ListTagsForResource" ]
    }
  }
}