'''
# Amazon EC2 Construct Library

<!--BEGIN STABILITY BANNER-->---


![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)

![cdk-constructs: Stable](https://img.shields.io/badge/cdk--constructs-stable-success.svg?style=for-the-badge)

---
<!--END STABILITY BANNER-->

The `@aws-cdk/aws-ec2` package contains primitives for setting up networking and
instances.

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
import aws_cdk.aws_ec2 as ec2
```

## VPC

Most projects need a Virtual Private Cloud to provide security by means of
network partitioning. This is achieved by creating an instance of
`Vpc`:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
vpc = ec2.Vpc(self, "VPC")
```

All default constructs require EC2 instances to be launched inside a VPC, so
you should generally start by defining a VPC whenever you need to launch
instances for your project.

### Subnet Types

A VPC consists of one or more subnets that instances can be placed into. CDK
distinguishes three different subnet types:

* **Public** - public subnets connect directly to the Internet using an
  Internet Gateway. If you want your instances to have a public IP address
  and be directly reachable from the Internet, you must place them in a
  public subnet.
* **Private** - instances in private subnets are not directly routable from the
  Internet, and connect out to the Internet via a NAT gateway. By default, a
  NAT gateway is created in every public subnet for maximum availability. Be
  aware that you will be charged for NAT gateways.
* **Isolated** - isolated subnets do not route from or to the Internet, and
  as such do not require NAT gateways. They can only connect to or be
  connected to from other instances in the same VPC. A default VPC configuration
  will not include isolated subnets,

A default VPC configuration will create public and **private** subnets. However, if
`natGateways:0` **and** `subnetConfiguration` is undefined, default VPC configuration
will create public and **isolated** subnets. See [*Advanced Subnet Configuration*](#advanced-subnet-configuration)
below for information on how to change the default subnet configuration.

Constructs using the VPC will "launch instances" (or more accurately, create
Elastic Network Interfaces) into one or more of the subnets. They all accept
a property called `subnetSelection` (sometimes called `vpcSubnets`) to allow
you to select in what subnet to place the ENIs, usually defaulting to
*private* subnets if the property is omitted.

If you would like to save on the cost of NAT gateways, you can use
*isolated* subnets instead of *private* subnets (as described in Advanced
*Subnet Configuration*). If you need private instances to have
internet connectivity, another option is to reduce the number of NAT gateways
created by setting the `natGateways` property to a lower value (the default
is one NAT gateway per availability zone). Be aware that this may have
availability implications for your application.

[Read more about
subnets](https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Subnets.html).

### Control over availability zones

By default, a VPC will spread over at most 3 Availability Zones available to
it. To change the number of Availability Zones that the VPC will spread over,
specify the `maxAzs` property when defining it.

The number of Availability Zones that are available depends on the *region*
and *account* of the Stack containing the VPC. If the [region and account are
specified](https://docs.aws.amazon.com/cdk/latest/guide/environments.html) on
the Stack, the CLI will [look up the existing Availability
Zones](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#using-regions-availability-zones-describe)
and get an accurate count. If region and account are not specified, the stack
could be deployed anywhere and it will have to make a safe choice, limiting
itself to 2 Availability Zones.

Therefore, to get the VPC to spread over 3 or more availability zones, you
must specify the environment where the stack will be deployed.

You can gain full control over the availability zones selection strategy by overriding the Stack's [`get availabilityZones()`](https://github.com/aws/aws-cdk/blob/master/packages/@aws-cdk/core/lib/stack.ts) method:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
class MyStack(Stack): get availabilityZones(): string[] {
        return ['us-west-2a', 'us-west-2b'];
      }

    def __init__(self, scope, id, props=None):
        super().__init__(scope, id, props)
```

Note that overriding the `get availabilityZones()` method will override the default behavior for all constructs defined within the Stack.

### Choosing subnets for resources

When creating resources that create Elastic Network Interfaces (such as
databases or instances), there is an option to choose which subnets to place
them in. For example, a VPC endpoint by default is placed into a subnet in
every availability zone, but you can override which subnets to use. The property
is typically called one of `subnets`, `vpcSubnets` or `subnetSelection`.

The example below will place the endpoint into two AZs (`us-east-1a` and `us-east-1c`),
in Isolated subnets:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
InterfaceVpcEndpoint(stack, "VPC Endpoint",
    vpc=vpc,
    service=InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    subnets={
        "subnet_type": SubnetType.ISOLATED,
        "availability_zones": ["us-east-1a", "us-east-1c"]
    }
)
```

You can also specify specific subnet objects for granular control:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
InterfaceVpcEndpoint(stack, "VPC Endpoint",
    vpc=vpc,
    service=InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    subnets={
        "subnets": [subnet1, subnet2]
    }
)
```

Which subnets are selected is evaluated as follows:

* `subnets`: if specific subnet objects are supplied, these are selected, and no other
  logic is used.
* `subnetType`/`subnetGroupName`: otherwise, a set of subnets is selected by
  supplying either type or name:

  * `subnetType` will select all subnets of the given type.
  * `subnetGroupName` should be used to distinguish between multiple groups of subnets of
    the same type (for example, you may want to separate your application instances and your
    RDS instances into two distinct groups of Isolated subnets).
  * If neither are given, the first available subnet group of a given type that
    exists in the VPC will be used, in this order: Private, then Isolated, then Public.
    In short: by default ENIs will preferentially be placed in subnets not connected to
    the Internet.
* `availabilityZones`/`onePerAz`: finally, some availability-zone based filtering may be done.
  This filtering by availability zones will only be possible if the VPC has been created or
  looked up in a non-environment agnostic stack (so account and region have been set and
  availability zones have been looked up).

  * `availabilityZones`: only the specific subnets from the selected subnet groups that are
    in the given availability zones will be returned.
  * `onePerAz`: per availability zone, a maximum of one subnet will be returned (Useful for resource
    types that do not allow creating two ENIs in the same availability zone).
* `subnetFilters`: additional filtering on subnets using any number of user-provided filters which
  extend the SubnetFilter class.

### Using NAT instances

By default, the `Vpc` construct will create NAT *gateways* for you, which
are managed by AWS. If you would prefer to use your own managed NAT
*instances* instead, specify a different value for the `natGatewayProvider`
property, as follows:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
# Configure the `natGatewayProvider` when defining a Vpc
nat_gateway_provider = ec2.NatProvider.instance(
    instance_type=ec2.InstanceType("t3.small")
)

vpc = ec2.Vpc(self, "MyVpc",
    nat_gateway_provider=nat_gateway_provider,

    # The 'natGateways' parameter now controls the number of NAT instances
    nat_gateways=2
)
```

The construct will automatically search for the most recent NAT gateway AMI.
If you prefer to use a custom AMI, use `machineImage: MachineImage.genericLinux({ ... })` and configure the right AMI ID for the
regions you want to deploy to.

By default, the NAT instances will route all traffic. To control what traffic
gets routed, pass `allowAllTraffic: false` and access the
`NatInstanceProvider.connections` member after having passed it to the VPC:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
provider = NatProvider.instance(
    instance_type=,
    allow_all_traffic=False
)
Vpc(stack, "TheVPC",
    nat_gateway_provider=provider
)
provider.connections.allow_from(Peer.ipv4("1.2.3.4/8"), Port.tcp(80))
```

### Advanced Subnet Configuration

If the default VPC configuration (public and private subnets spanning the
size of the VPC) don't suffice for you, you can configure what subnets to
create by specifying the `subnetConfiguration` property. It allows you
to configure the number and size of all subnets. Specifying an advanced
subnet configuration could look like this:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
vpc = ec2.Vpc(self, "TheVPC",
    # 'cidr' configures the IP range and size of the entire VPC.
    # The IP space will be divided over the configured subnets.
    cidr="10.0.0.0/21",

    # 'maxAzs' configures the maximum number of availability zones to use
    max_azs=3,

    # 'subnetConfiguration' specifies the "subnet groups" to create.
    # Every subnet group will have a subnet for each AZ, so this
    # configuration will create `3 groups × 3 AZs = 9` subnets.
    subnet_configuration=[SubnetConfiguration(
        # 'subnetType' controls Internet access, as described above.
        subnet_type=ec2.SubnetType.PUBLIC,

        # 'name' is used to name this particular subnet group. You will have to
        # use the name for subnet selection if you have more than one subnet
        # group of the same type.
        name="Ingress",

        # 'cidrMask' specifies the IP addresses in the range of of individual
        # subnets in the group. Each of the subnets in this group will contain
        # `2^(32 address bits - 24 subnet bits) - 2 reserved addresses = 254`
        # usable IP addresses.
        #
        # If 'cidrMask' is left out the available address space is evenly
        # divided across the remaining subnet groups.
        cidr_mask=24
    ), SubnetConfiguration(
        cidr_mask=24,
        name="Application",
        subnet_type=ec2.SubnetType.PRIVATE
    ), SubnetConfiguration(
        cidr_mask=28,
        name="Database",
        subnet_type=ec2.SubnetType.ISOLATED,

        # 'reserved' can be used to reserve IP address space. No resources will
        # be created for this subnet, but the IP range will be kept available for
        # future creation of this subnet, or even for future subdivision.
        reserved=True
    )
    ]
)
```

The example above is one possible configuration, but the user can use the
constructs above to implement many other network configurations.

The `Vpc` from the above configuration in a Region with three
availability zones will be the following:

Subnet Name       |Type      |IP Block      |AZ|Features
------------------|----------|--------------|--|--------
IngressSubnet1    |`PUBLIC`  |`10.0.0.0/24` |#1|NAT Gateway
IngressSubnet2    |`PUBLIC`  |`10.0.1.0/24` |#2|NAT Gateway
IngressSubnet3    |`PUBLIC`  |`10.0.2.0/24` |#3|NAT Gateway
ApplicationSubnet1|`PRIVATE` |`10.0.3.0/24` |#1|Route to NAT in IngressSubnet1
ApplicationSubnet2|`PRIVATE` |`10.0.4.0/24` |#2|Route to NAT in IngressSubnet2
ApplicationSubnet3|`PRIVATE` |`10.0.5.0/24` |#3|Route to NAT in IngressSubnet3
DatabaseSubnet1   |`ISOLATED`|`10.0.6.0/28` |#1|Only routes within the VPC
DatabaseSubnet2   |`ISOLATED`|`10.0.6.16/28`|#2|Only routes within the VPC
DatabaseSubnet3   |`ISOLATED`|`10.0.6.32/28`|#3|Only routes within the VPC

### Accessing the Internet Gateway

If you need access to the internet gateway, you can get it's ID like so:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
igw_id = vpc.internet_gateway_id
```

For a VPC with only `ISOLATED` subnets, this value will be undefined.

This is only supported for VPCs created in the stack - currently you're
unable to get the ID for imported VPCs. To do that you'd have to specifically
look up the Internet Gateway by name, which would require knowing the name
beforehand.

This can be useful for configuring routing using a combination of gateways:
for more information see [Routing](#routing) below.

#### Routing

It's possible to add routes to any subnets using the `addRoute()` method. If for
example you want an isolated subnet to have a static route via the default
Internet Gateway created for the public subnet - perhaps for routing a VPN
connection - you can do so like this:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
vpc = ec2.Vpc(self, "VPC",
    subnet_configuration=[{
        "subnet_type": SubnetType.PUBLIC,
        "name": "Public"
    }, {
        "subnet_type": SubnetType.ISOLATED,
        "name": "Isolated"
    }]
)(vpc.isolatedSubnets[0]).add_route("StaticRoute",
    router_id=vpc.internet_gateway_id,
    router_type=RouterType.GATEWAY,
    destination_cidr_block="8.8.8.8/32"
)
```

*Note that we cast to `Subnet` here because the list of subnets only returns an
`ISubnet`.*

### Reserving subnet IP space

There are situations where the IP space for a subnet or number of subnets
will need to be reserved. This is useful in situations where subnets would
need to be added after the vpc is originally deployed, without causing IP
renumbering for existing subnets. The IP space for a subnet may be reserved
by setting the `reserved` subnetConfiguration property to true, as shown
below:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
vpc = ec2.Vpc(self, "TheVPC",
    nat_gateways=1,
    subnet_configuration=[SubnetConfiguration(
        cidr_mask=26,
        name="Public",
        subnet_type=ec2.SubnetType.PUBLIC
    ), SubnetConfiguration(
        cidr_mask=26,
        name="Application1",
        subnet_type=ec2.SubnetType.PRIVATE
    ), SubnetConfiguration(
        cidr_mask=26,
        name="Application2",
        subnet_type=ec2.SubnetType.PRIVATE,
        reserved=True
    ), SubnetConfiguration(
        cidr_mask=27,
        name="Database",
        subnet_type=ec2.SubnetType.ISOLATED
    )
    ]
)
```

In the example above, the subnet for Application2 is not actually provisioned
but its IP space is still reserved. If in the future this subnet needs to be
provisioned, then the `reserved: true` property should be removed. Reserving
parts of the IP space prevents the other subnets from getting renumbered.

### Sharing VPCs between stacks

If you are creating multiple `Stack`s inside the same CDK application, you
can reuse a VPC defined in one Stack in another by simply passing the VPC
instance around:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
#
# Stack1 creates the VPC
#
class Stack1(cdk.Stack):

    def __init__(self, scope, id, *, description=None, env=None, stackName=None, tags=None, synthesizer=None, terminationProtection=None, analyticsReporting=None):
        super().__init__(scope, id, description=description, env=env, stackName=stackName, tags=tags, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting)

        self.vpc = ec2.Vpc(self, "VPC")

#
# Stack2 consumes the VPC
#
class Stack2(cdk.Stack):
    def __init__(self, scope, id, *, vpc, description=None, env=None, stackName=None, tags=None, synthesizer=None, terminationProtection=None, analyticsReporting=None):
        super().__init__(scope, id, vpc=vpc, description=description, env=env, stackName=stackName, tags=tags, synthesizer=synthesizer, terminationProtection=terminationProtection, analyticsReporting=analyticsReporting)

        # Pass the VPC to a construct that needs it
        ConstructThatTakesAVpc(self, "Construct",
            vpc=vpc
        )

stack1 = Stack1(app, "Stack1")
stack2 = Stack2(app, "Stack2",
    vpc=stack1.vpc
)
```

### Importing an existing VPC

If your VPC is created outside your CDK app, you can use `Vpc.fromLookup()`.
The CDK CLI will search for the specified VPC in the the stack's region and
account, and import the subnet configuration. Looking up can be done by VPC
ID, but more flexibly by searching for a specific tag on the VPC.

Subnet types will be determined from the `aws-cdk:subnet-type` tag on the
subnet if it exists, or the presence of a route to an Internet Gateway
otherwise. Subnet names will be determined from the `aws-cdk:subnet-name` tag
on the subnet if it exists, or will mirror the subnet type otherwise (i.e.
a public subnet will have the name `"Public"`).

The result of the `Vpc.fromLookup()` operation will be written to a file
called `cdk.context.json`. You must commit this file to source control so
that the lookup values are available in non-privileged environments such
as CI build steps, and to ensure your template builds are repeatable.

Here's how `Vpc.fromLookup()` can be used:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
vpc = ec2.Vpc.from_lookup(stack, "VPC",
    # This imports the default VPC but you can also
    # specify a 'vpcName' or 'tags'.
    is_default=True
)
```

`Vpc.fromLookup` is the recommended way to import VPCs. If for whatever
reason you do not want to use the context mechanism to look up a VPC at
synthesis time, you can also use `Vpc.fromVpcAttributes`. This has the
following limitations:

* Every subnet group in the VPC must have a subnet in each availability zone
  (for example, each AZ must have both a public and private subnet). Asymmetric
  VPCs are not supported.
* All VpcId, SubnetId, RouteTableId, ... parameters must either be known at
  synthesis time, or they must come from deploy-time list parameters whose
  deploy-time lengths are known at synthesis time.

Using `Vpc.fromVpcAttributes()` looks like this:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
vpc = ec2.Vpc.from_vpc_attributes(stack, "VPC",
    vpc_id="vpc-1234",
    availability_zones=["us-east-1a", "us-east-1b"],

    # Either pass literals for all IDs
    public_subnet_ids=["s-12345", "s-67890"],

    # OR: import a list of known length
    private_subnet_ids=Fn.import_list_value("PrivateSubnetIds", 2),

    # OR: split an imported string to a list of known length
    isolated_subnet_ids=Fn.split(",", ssm.StringParameter.value_for_string_parameter(stack, "MyParameter"), 2)
)
```

## Allowing Connections

In AWS, all network traffic in and out of **Elastic Network Interfaces** (ENIs)
is controlled by **Security Groups**. You can think of Security Groups as a
firewall with a set of rules. By default, Security Groups allow no incoming
(ingress) traffic and all outgoing (egress) traffic. You can add ingress rules
to them to allow incoming traffic streams. To exert fine-grained control over
egress traffic, set `allowAllOutbound: false` on the `SecurityGroup`, after
which you can add egress traffic rules.

You can manipulate Security Groups directly:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
my_security_group = ec2.SecurityGroup(self, "SecurityGroup",
    vpc=vpc,
    description="Allow ssh access to ec2 instances",
    allow_all_outbound=True
)
my_security_group.add_ingress_rule(ec2.Peer.any_ipv4(), ec2.Port.tcp(22), "allow ssh access from the world")
```

All constructs that create ENIs on your behalf (typically constructs that create
EC2 instances or other VPC-connected resources) will all have security groups
automatically assigned. Those constructs have an attribute called
**connections**, which is an object that makes it convenient to update the
security groups. If you want to allow connections between two constructs that
have security groups, you have to add an **Egress** rule to one Security Group,
and an **Ingress** rule to the other. The connections object will automatically
take care of this for you:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
# Allow connections from anywhere
load_balancer.connections.allow_from_any_ipv4(ec2.Port.tcp(443), "Allow inbound HTTPS")

# The same, but an explicit IP address
load_balancer.connections.allow_from(ec2.Peer.ipv4("1.2.3.4/32"), ec2.Port.tcp(443), "Allow inbound HTTPS")

# Allow connection between AutoScalingGroups
app_fleet.connections.allow_to(db_fleet, ec2.Port.tcp(443), "App can call database")
```

### Connection Peers

There are various classes that implement the connection peer part:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
# Simple connection peers
peer = ec2.Peer.ipv4("10.0.0.0/16")
peer = ec2.Peer.any_ipv4()
peer = ec2.Peer.ipv6("::0/0")
peer = ec2.Peer.any_ipv6()
peer = ec2.Peer.prefix_list("pl-12345")
app_fleet.connections.allow_to(peer, ec2.Port.tcp(443), "Allow outbound HTTPS")
```

Any object that has a security group can itself be used as a connection peer:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
# These automatically create appropriate ingress and egress rules in both security groups
fleet1.connections.allow_to(fleet2, ec2.Port.tcp(80), "Allow between fleets")

app_fleet.connections.allow_from_any_ipv4(ec2.Port.tcp(80), "Allow from load balancer")
```

### Port Ranges

The connections that are allowed are specified by port ranges. A number of classes provide
the connection specifier:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
ec2.Port.tcp(80)
ec2.Port.tcp_range(60000, 65535)
ec2.Port.all_tcp()
ec2.Port.all_traffic()
```

> NOTE: This set is not complete yet; for example, there is no library support for ICMP at the moment.
> However, you can write your own classes to implement those.

### Default Ports

Some Constructs have default ports associated with them. For example, the
listener of a load balancer does (it's the public port), or instances of an
RDS database (it's the port the database is accepting connections on).

If the object you're calling the peering method on has a default port associated with it, you can call
`allowDefaultPortFrom()` and omit the port specifier. If the argument has an associated default port, call
`allowDefaultPortTo()`.

For example:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
# Port implicit in listener
listener.connections.allow_default_port_from_any_ipv4("Allow public")

# Port implicit in peer
app_fleet.connections.allow_default_port_to(rds_database, "Fleet can access database")
```

## Machine Images (AMIs)

AMIs control the OS that gets launched when you start your EC2 instance. The EC2
library contains constructs to select the AMI you want to use.

Depending on the type of AMI, you select it a different way. Here are some
examples of things you might want to use:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
# Pick the right Amazon Linux edition. All arguments shown are optional
# and will default to these values when omitted.
amzn_linux = ec2.MachineImage.latest_amazon_linux(
    generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX,
    edition=ec2.AmazonLinuxEdition.STANDARD,
    virtualization=ec2.AmazonLinuxVirt.HVM,
    storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE,
    cpu_type=ec2.AmazonLinuxCpuType.X86_64
)

# Pick a Windows edition to use
windows = ec2.MachineImage.latest_windows(ec2.WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_FULL_BASE)

# Read AMI id from SSM parameter store
ssm = ec2.MachineImage.from_sSMParameter("/my/ami", ec2.OperatingSystemType.LINUX)

# Look up the most recent image matching a set of AMI filters.
# In this case, look up the NAT instance AMI, by using a wildcard
# in the 'name' field:
nat_ami = ec2.MachineImage.lookup(
    name="amzn-ami-vpc-nat-*",
    owners=["amazon"]
)

# For other custom (Linux) images, instantiate a `GenericLinuxImage` with
# a map giving the AMI to in for each region:
linux = ec2.MachineImage.generic_linux({
    "us-east-1": "ami-97785bed",
    "eu-west-1": "ami-12345678"
})

# For other custom (Windows) images, instantiate a `GenericWindowsImage` with
# a map giving the AMI to in for each region:
generic_windows = ec2.MachineImage.generic_windows({
    "us-east-1": "ami-97785bed",
    "eu-west-1": "ami-12345678"
})
```

> NOTE: The AMIs selected by `MachineImage.lookup()` will be cached in
> `cdk.context.json`, so that your AutoScalingGroup instances aren't replaced while
> you are making unrelated changes to your CDK app.
>
> To query for the latest AMI again, remove the relevant cache entry from
> `cdk.context.json`, or use the `cdk context` command. For more information, see
> [Runtime Context](https://docs.aws.amazon.com/cdk/latest/guide/context.html) in the CDK
> developer guide.
>
> `MachineImage.genericLinux()`, `MachineImage.genericWindows()` will use `CfnMapping` in
> an agnostic stack.

## Special VPC configurations

### VPN connections to a VPC

Create your VPC with VPN connections by specifying the `vpnConnections` props (keys are construct `id`s):

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
vpc = ec2.Vpc(self, "MyVpc",
    vpn_connections={
        "dynamic": VpnConnectionOptions(# Dynamic routing (BGP)
            ip="1.2.3.4"),
        "static": VpnConnectionOptions(# Static routing
            ip="4.5.6.7",
            static_routes=["192.168.10.0/24", "192.168.20.0/24"
            ])
    }
)
```

To create a VPC that can accept VPN connections, set `vpnGateway` to `true`:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
vpc = ec2.Vpc(self, "MyVpc",
    vpn_gateway=True
)
```

VPN connections can then be added:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
vpc.add_vpn_connection("Dynamic",
    ip="1.2.3.4"
)
```

By default, routes will be propagated on the route tables associated with the private subnets. If no
private subnets exists, isolated subnets are used. If no isolated subnets exists, public subnets are
used. Use the `Vpc` property `vpnRoutePropagation` to customize this behavior.

VPN connections expose [metrics (cloudwatch.Metric)](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-cloudwatch/README.md) across all tunnels in the account/region and per connection:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
# Across all tunnels in the account/region
all_data_out = ec2.VpnConnection.metric_all_tunnel_data_out()

# For a specific vpn connection
vpn_connection = vpc.add_vpn_connection("Dynamic",
    ip="1.2.3.4"
)
state = vpn_connection.metric_tunnel_state()
```

### VPC endpoints

A VPC endpoint enables you to privately connect your VPC to supported AWS services and VPC endpoint services powered by PrivateLink without requiring an internet gateway, NAT device, VPN connection, or AWS Direct Connect connection. Instances in your VPC do not require public IP addresses to communicate with resources in the service. Traffic between your VPC and the other service does not leave the Amazon network.

Endpoints are virtual devices. They are horizontally scaled, redundant, and highly available VPC components that allow communication between instances in your VPC and services without imposing availability risks or bandwidth constraints on your network traffic.

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
# Add gateway endpoints when creating the VPC
vpc = ec2.Vpc(self, "MyVpc",
    gateway_endpoints={
        "S3": GatewayVpcEndpointOptions(
            service=ec2.GatewayVpcEndpointAwsService.S3
        )
    }
)

# Alternatively gateway endpoints can be added on the VPC
dynamo_db_endpoint = vpc.add_gateway_endpoint("DynamoDbEndpoint",
    service=ec2.GatewayVpcEndpointAwsService.DYNAMODB
)

# This allows to customize the endpoint policy
dynamo_db_endpoint.add_to_policy(
    iam.PolicyStatement(# Restrict to listing and describing tables
        principals=[iam.AnyPrincipal()],
        actions=["dynamodb:DescribeTable", "dynamodb:ListTables"],
        resources=["*"]))

# Add an interface endpoint
vpc.add_interface_endpoint("EcrDockerEndpoint", {
    "service": ec2.InterfaceVpcEndpointAwsService.ECR_DOCKER
})
```

By default, CDK will place a VPC endpoint in one subnet per AZ. If you wish to override the AZs CDK places the VPC endpoint in,
use the `subnets` parameter as follows:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
InterfaceVpcEndpoint(stack, "VPC Endpoint",
    vpc=vpc,
    service=InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    # Choose which availability zones to place the VPC endpoint in, based on
    # available AZs
    subnets={
        "availability_zones": ["us-east-1a", "us-east-1c"]
    }
)
```

Per the [AWS documentation](https://aws.amazon.com/premiumsupport/knowledge-center/interface-endpoint-availability-zone/), not all
VPC endpoint services are available in all AZs. If you specify the parameter `lookupSupportedAzs`, CDK attempts to discover which
AZs an endpoint service is available in, and will ensure the VPC endpoint is not placed in a subnet that doesn't match those AZs.
These AZs will be stored in cdk.context.json.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
InterfaceVpcEndpoint(stack, "VPC Endpoint",
    vpc=vpc,
    service=InterfaceVpcEndpointService("com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc", 443),
    # Choose which availability zones to place the VPC endpoint in, based on
    # available AZs
    lookup_supported_azs=True
)
```

#### Security groups for interface VPC endpoints

By default, interface VPC endpoints create a new security group and traffic is **not**
automatically allowed from the VPC CIDR.

Use the `connections` object to allow traffic to flow to the endpoint:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
my_endpoint.connections.allow_default_port_from_any_ipv4()
```

Alternatively, existing security groups can be used by specifying the `securityGroups` prop.

### VPC endpoint services

A VPC endpoint service enables you to expose a Network Load Balancer(s) as a provider service to consumers, who connect to your service over a VPC endpoint. You can restrict access to your service via whitelisted principals (anything that extends ArnPrincipal), and require that new connections be manually accepted.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
VpcEndpointService(self, "EndpointService",
    vpc_endpoint_service_load_balancers=[network_load_balancer1, network_load_balancer2],
    acceptance_required=True,
    whitelisted_principals=[ArnPrincipal("arn:aws:iam::123456789012:root")]
)
```

Endpoint services support private DNS, which makes it easier for clients to connect to your service by automatically setting up DNS in their VPC.
You can enable private DNS on an endpoint service like so:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
from aws_cdk.aws_route53 import VpcEndpointServiceDomainName


VpcEndpointServiceDomainName(stack, "EndpointDomain",
    endpoint_service=vpces,
    domain_name="my-stuff.aws-cdk.dev",
    public_hosted_zone=zone
)
```

Note: The domain name must be owned (registered through Route53) by the account the endpoint service is in, or delegated to the account.
The VpcEndpointServiceDomainName will handle the AWS side of domain verification, the process for which can be found
[here](https://docs.aws.amazon.com/vpc/latest/userguide/endpoint-services-dns-validation.html)

## Instances

You can use the `Instance` class to start up a single EC2 instance. For production setups, we recommend
you use an `AutoScalingGroup` from the `aws-autoscaling` module instead, as AutoScalingGroups will take
care of restarting your instance if it ever fails.

### Configuring Instances using CloudFormation Init (cfn-init)

CloudFormation Init allows you to configure your instances by writing files to them, installing software
packages, starting services and running arbitrary commands. By default, if any of the instance setup
commands throw an error, the deployment will fail and roll back to the previously known good state.
The following documentation also applies to `AutoScalingGroup`s.

For the full set of capabilities of this system, see the documentation for
[`AWS::CloudFormation::Init`](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html).
Here is an example of applying some configuration to an instance:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
ec2.Instance(self, "Instance", {
    # Showing the most complex setup, if you have simpler requirements
    # you can use `CloudFormationInit.fromElements()`.
    "init": ec2.CloudFormationInit.from_config_sets(
        config_sets={
            # Applies the configs below in this order
            "default": ["yumPreinstall", "config"]
        },
        configs={
            "yum_preinstall": ec2.InitConfig([
                # Install an Amazon Linux package using yum
                ec2.InitPackage.yum("git")
            ]),
            "config": ec2.InitConfig([
                # Create a JSON file from tokens (can also create other files)
                ec2.InitFile.from_object("/etc/stack.json", {
                    "stack_id": stack.stack_id,
                    "stack_name": stack.stack_name,
                    "region": stack.region
                }),

                # Create a group and user
                ec2.InitGroup.from_name("my-group"),
                ec2.InitUser.from_name("my-user"),

                # Install an RPM from the internet
                ec2.InitPackage.rpm("http://mirrors.ukfast.co.uk/sites/dl.fedoraproject.org/pub/epel/8/Everything/x86_64/Packages/r/rubygem-git-1.5.0-2.el8.noarch.rpm")
            ])
        }
    ),
    "init_options": ApplyCloudFormationInitOptions(
        # Optional, which configsets to activate (['default'] by default)
        config_sets=["default"],

        # Optional, how long the installation is expected to take (5 minutes by default)
        timeout=Duration.minutes(30)
    )
})
```

You can have services restarted after the init process has made changes to the system.
To do that, instantiate an `InitServiceRestartHandle` and pass it to the config elements
that need to trigger the restart and the service itself. For example, the following
config writes a config file for nginx, extracts an archive to the root directory, and then
restarts nginx so that it picks up the new config and files:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
handle = ec2.InitServiceRestartHandle()

ec2.CloudFormationInit.from_elements(
    ec2.InitFile.from_string("/etc/nginx/nginx.conf", "...", {"service_restart_handles": [handle]}),
    ec2.InitSource.from_bucket("/var/www/html", my_bucket, "html.zip", service_restart_handles=[handle]),
    ec2.InitService.enable("nginx", {
        "service_restart_handle": handle
    }))
```

### Bastion Hosts

A bastion host functions as an instance used to access servers and resources in a VPC without open up the complete VPC on a network level.
You can use bastion hosts using a standard SSH connection targeting port 22 on the host. As an alternative, you can connect the SSH connection
feature of AWS Systems Manager Session Manager, which does not need an opened security group. (https://aws.amazon.com/about-aws/whats-new/2019/07/session-manager-launches-tunneling-support-for-ssh-and-scp/)

A default bastion host for use via SSM can be configured like:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
host = ec2.BastionHostLinux(self, "BastionHost", vpc=vpc)
```

If you want to connect from the internet using SSH, you need to place the host into a public subnet. You can then configure allowed source hosts.

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
host = ec2.BastionHostLinux(self, "BastionHost",
    vpc=vpc,
    subnet_selection=SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC)
)
host.allow_ssh_access_from(ec2.Peer.ipv4("1.2.3.4/32"))
```

As there are no SSH public keys deployed on this machine, you need to use [EC2 Instance Connect](https://aws.amazon.com/de/blogs/compute/new-using-amazon-ec2-instance-connect-for-ssh-access-to-your-ec2-instances/)
with the command `aws ec2-instance-connect send-ssh-public-key` to provide your SSH public key.

EBS volume for the bastion host can be encrypted like:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
host = ec2.BastionHostLinux(stack, "BastionHost",
    vpc=vpc,
    block_devices=[BlockDevice(
        device_name="EBSBastionHost",
        volume=BlockDeviceVolume.ebs(10,
            encrypted=True
        )
    )]
)
```

### Block Devices

To add EBS block device mappings, specify the `blockDevices` property. The following example sets the EBS-backed
root device (`/dev/sda1`) size to 50 GiB, and adds another EBS-backed device mapped to `/dev/sdm` that is 100 GiB in
size:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
ec2.Instance(self, "Instance", {
    # ...
    "block_devices": [BlockDevice(
        device_name="/dev/sda1",
        volume=ec2.BlockDeviceVolume.ebs(50)
    ), BlockDevice(
        device_name="/dev/sdm",
        volume=ec2.BlockDeviceVolume.ebs(100)
    )
    ]
})
```

### Volumes

Whereas a `BlockDeviceVolume` is an EBS volume that is created and destroyed as part of the creation and destruction of a specific instance. A `Volume` is for when you want an EBS volume separate from any particular instance. A `Volume` is an EBS block device that can be attached to, or detached from, any instance at any time. Some types of `Volume`s can also be attached to multiple instances at the same time to allow you to have shared storage between those instances.

A notable restriction is that a Volume can only be attached to instances in the same availability zone as the Volume itself.

The following demonstrates how to create a 500 GiB encrypted Volume in the `us-west-2a` availability zone, and give a role the ability to attach that Volume to a specific instance:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
instance = ec2.Instance(self, "Instance", {})
role = iam.Role(stack, "SomeRole",
    assumed_by=iam.AccountRootPrincipal()
)
volume = ec2.Volume(self, "Volume",
    availability_zone="us-west-2a",
    size=cdk.Size.gibibytes(500),
    encrypted=True
)

volume.grant_attach_volume(role, [instance])
```

#### Instances Attaching Volumes to Themselves

If you need to grant an instance the ability to attach/detach an EBS volume to/from itself, then using `grantAttachVolume` and `grantDetachVolume` as outlined above
will lead to an unresolvable circular reference between the instance role and the instance. In this case, use `grantAttachVolumeByResourceTag` and `grantDetachVolumeByResourceTag` as follows:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
instance = ec2.Instance(self, "Instance", {})
volume = ec2.Volume(self, "Volume")

attach_grant = volume.grant_attach_volume_by_resource_tag(instance.grant_principal, [instance])
detach_grant = volume.grant_detach_volume_by_resource_tag(instance.grant_principal, [instance])
```

#### Attaching Volumes

The Amazon EC2 documentation for
[Linux Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonEBS.html) and
[Windows Instances](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ebs-volumes.html) contains information on how
to attach and detach your Volumes to/from instances, and how to format them for use.

The following is a sample skeleton of EC2 UserData that can be used to attach a Volume to the Linux instance that it is running on:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
volume = ec2.Volume(self, "Volume")
instance = ec2.Instance(self, "Instance", {})
volume.grant_attach_volume_by_resource_tag(instance.grant_principal, [instance])
target_device = "/dev/xvdz"
instance.user_data.add_commands(f"aws --region {Stack.of(this).region} ec2 attach-volume --volume-id {volume.volumeId} --instance-id {instance.instanceId} --device {targetDevice}", f"while ! test -e {targetDevice}; do sleep 1; done")
```

## VPC Flow Logs

VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. Flow log data can be published to Amazon CloudWatch Logs and Amazon S3. After you've created a flow log, you can retrieve and view its data in the chosen destination. ([https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html)).

By default a flow log will be created with CloudWatch Logs as the destination.

You can create a flow log like this:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
ec2.FlowLog(self, "FlowLog",
    resource_type=ec2.FlowLogResourceType.from_vpc(vpc)
)
```

Or you can add a Flow Log to a VPC by using the addFlowLog method like this:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
vpc = ec2.Vpc(self, "Vpc")

vpc.add_flow_log("FlowLog")
```

You can also add multiple flow logs with different destinations.

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
vpc = ec2.Vpc(self, "Vpc")

vpc.add_flow_log("FlowLogS3",
    destination=ec2.FlowLogDestination.to_s3()
)

vpc.add_flow_log("FlowLogCloudWatch",
    traffic_type=ec2.FlowLogTrafficType.REJECT
)
```

By default the CDK will create the necessary resources for the destination. For the CloudWatch Logs destination
it will create a CloudWatch Logs Log Group as well as the IAM role with the necessary permissions to publish to
the log group. In the case of an S3 destination, it will create the S3 bucket.

If you want to customize any of the destination resources you can provide your own as part of the `destination`.

*CloudWatch Logs*

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
log_group = logs.LogGroup(self, "MyCustomLogGroup")

role = iam.Role(self, "MyCustomRole",
    assumed_by=iam.ServicePrincipal("vpc-flow-logs.amazonaws.com")
)

ec2.FlowLog(self, "FlowLog",
    resource_type=ec2.FlowLogResourceType.from_vpc(vpc),
    destination=ec2.FlowLogDestination.to_cloud_watch_logs(log_group, role)
)
```

*S3*

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
bucket = s3.Bucket(self, "MyCustomBucket")

ec2.FlowLog(self, "FlowLog",
    resource_type=ec2.FlowLogResourceType.from_vpc(vpc),
    destination=ec2.FlowLogDestination.to_s3(bucket)
)

ec2.FlowLog(self, "FlowLogWithKeyPrefix",
    resource_type=ec2.FlowLogResourceType.from_vpc(vpc),
    destination=ec2.FlowLogDestination.to_s3(bucket, "prefix/")
)
```

## User Data

User data enables you to run a script when your instances start up.  In order to configure these scripts you can add commands directly to the script
or you can use the UserData's convenience functions to aid in the creation of your script.

A user data could be configured to run a script found in an asset through the following:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
asset = Asset(self, "Asset", path=path.join(__dirname, "configure.sh"))
instance = ec2.Instance(self, "Instance", {})
local_path = instance.user_data.add_s3_download_command(
    bucket=asset.bucket,
    bucket_key=asset.s3_object_key
)
instance.user_data.add_execute_file_command(
    file_path=local_path,
    arguments="--verbose -y"
)
asset.grant_read(instance.role)
```

## Importing existing subnet

To import an existing Subnet, call `Subnet.fromSubnetAttributes()` or
`Subnet.fromSubnetId()`. Only if you supply the subnet's Availability Zone
and Route Table Ids when calling `Subnet.fromSubnetAttributes()` will you be
able to use the CDK features that use these values (such as selecting one
subnet per AZ).

Importing an existing subnet looks like this:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
# Supply all properties
subnet = Subnet.from_subnet_attributes(self, "SubnetFromAttributes",
    subnet_id="s-1234",
    availability_zone="pub-az-4465",
    route_table_id="rt-145"
)

# Supply only subnet id
subnet = Subnet.from_subnet_id(self, "SubnetFromId", "s-1234")
```

## Launch Templates

A Launch Template is a standardized template that contains the configuration information to launch an instance.
They can be used when launching instances on their own, through Amazon EC2 Auto Scaling, EC2 Fleet, and Spot Fleet.
Launch templates enable you to store launch parameters so that you do not have to specify them every time you launch
an instance. For information on Launch Templates please see the
[official documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html).

The following demonstrates how to create a launch template with an Amazon Machine Image, and security group.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
vpc = ec2.Vpc(...)
# ...
template = ec2.LaunchTemplate(self, "LaunchTemplate",
    machine_image=ec2.AmazonMachineImage(),
    security_group=ec2.SecurityGroup(self, "LaunchTemplateSG",
        vpc=vpc
    )
)
```
'''
import abc
import builtins
import datetime
import enum
import typing

import jsii
import publication
import typing_extensions

from ._jsii import *

import aws_cdk.assets
import aws_cdk.aws_cloudwatch
import aws_cdk.aws_iam
import aws_cdk.aws_kms
import aws_cdk.aws_logs
import aws_cdk.aws_s3
import aws_cdk.aws_s3_assets
import aws_cdk.core
import constructs


class AclCidr(metaclass=jsii.JSIIAbstractClass, jsii_type="@aws-cdk/aws-ec2.AclCidr"):
    '''(experimental) Either an IPv4 or an IPv6 CIDR.

    :stability: experimental
    '''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_AclCidrProxy"]:
        return _AclCidrProxy

    def __init__(self) -> None:
        jsii.create(AclCidr, self, [])

    @jsii.member(jsii_name="anyIpv4") # type: ignore[misc]
    @builtins.classmethod
    def any_ipv4(cls) -> "AclCidr":
        '''(experimental) The CIDR containing all IPv4 addresses (i.e., 0.0.0.0/0).

        :stability: experimental
        '''
        return typing.cast("AclCidr", jsii.sinvoke(cls, "anyIpv4", []))

    @jsii.member(jsii_name="anyIpv6") # type: ignore[misc]
    @builtins.classmethod
    def any_ipv6(cls) -> "AclCidr":
        '''(experimental) The CIDR containing all IPv6 addresses (i.e., ::/0).

        :stability: experimental
        '''
        return typing.cast("AclCidr", jsii.sinvoke(cls, "anyIpv6", []))

    @jsii.member(jsii_name="ipv4") # type: ignore[misc]
    @builtins.classmethod
    def ipv4(cls, ipv4_cidr: builtins.str) -> "AclCidr":
        '''(experimental) An IP network range in CIDR notation (for example, 172.16.0.0/24).

        :param ipv4_cidr: -

        :stability: experimental
        '''
        return typing.cast("AclCidr", jsii.sinvoke(cls, "ipv4", [ipv4_cidr]))

    @jsii.member(jsii_name="ipv6") # type: ignore[misc]
    @builtins.classmethod
    def ipv6(cls, ipv6_cidr: builtins.str) -> "AclCidr":
        '''(experimental) An IPv6 network range in CIDR notation (for example, 2001:db8::/48).

        :param ipv6_cidr: -

        :stability: experimental
        '''
        return typing.cast("AclCidr", jsii.sinvoke(cls, "ipv6", [ipv6_cidr]))

    @jsii.member(jsii_name="toCidrConfig") # type: ignore[misc]
    @abc.abstractmethod
    def to_cidr_config(self) -> "AclCidrConfig":
        '''
        :stability: experimental
        '''
        ...


class _AclCidrProxy(AclCidr):
    @jsii.member(jsii_name="toCidrConfig")
    def to_cidr_config(self) -> "AclCidrConfig":
        '''
        :stability: experimental
        '''
        return typing.cast("AclCidrConfig", jsii.invoke(self, "toCidrConfig", []))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.AclCidrConfig",
    jsii_struct_bases=[],
    name_mapping={"cidr_block": "cidrBlock", "ipv6_cidr_block": "ipv6CidrBlock"},
)
class AclCidrConfig:
    def __init__(
        self,
        *,
        cidr_block: typing.Optional[builtins.str] = None,
        ipv6_cidr_block: typing.Optional[builtins.str] = None,
    ) -> None:
        '''(experimental) Acl Configuration for CIDR.

        :param cidr_block: (experimental) Ipv4 CIDR.
        :param ipv6_cidr_block: (experimental) Ipv6 CIDR.

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if cidr_block is not None:
            self._values["cidr_block"] = cidr_block
        if ipv6_cidr_block is not None:
            self._values["ipv6_cidr_block"] = ipv6_cidr_block

    @builtins.property
    def cidr_block(self) -> typing.Optional[builtins.str]:
        '''(experimental) Ipv4 CIDR.

        :stability: experimental
        '''
        result = self._values.get("cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ipv6_cidr_block(self) -> typing.Optional[builtins.str]:
        '''(experimental) Ipv6 CIDR.

        :stability: experimental
        '''
        result = self._values.get("ipv6_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AclCidrConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.AclIcmp",
    jsii_struct_bases=[],
    name_mapping={"code": "code", "type": "type"},
)
class AclIcmp:
    def __init__(
        self,
        *,
        code: typing.Optional[jsii.Number] = None,
        type: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''(experimental) Properties to create Icmp.

        :param code: (experimental) The Internet Control Message Protocol (ICMP) code. You can use -1 to specify all ICMP codes for the given ICMP type. Requirement is conditional: Required if you specify 1 (ICMP) for the protocol parameter.
        :param type: (experimental) The Internet Control Message Protocol (ICMP) type. You can use -1 to specify all ICMP types. Conditional requirement: Required if you specify 1 (ICMP) for the CreateNetworkAclEntry protocol parameter.

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if code is not None:
            self._values["code"] = code
        if type is not None:
            self._values["type"] = type

    @builtins.property
    def code(self) -> typing.Optional[jsii.Number]:
        '''(experimental) The Internet Control Message Protocol (ICMP) code.

        You can use -1 to specify all ICMP
        codes for the given ICMP type. Requirement is conditional: Required if you
        specify 1 (ICMP) for the protocol parameter.

        :stability: experimental
        '''
        result = self._values.get("code")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def type(self) -> typing.Optional[jsii.Number]:
        '''(experimental) The Internet Control Message Protocol (ICMP) type.

        You can use -1 to specify all ICMP types.
        Conditional requirement: Required if you specify 1 (ICMP) for the CreateNetworkAclEntry protocol parameter.

        :stability: experimental
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AclIcmp(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.AclPortRange",
    jsii_struct_bases=[],
    name_mapping={"from_": "from", "to": "to"},
)
class AclPortRange:
    def __init__(
        self,
        *,
        from_: typing.Optional[jsii.Number] = None,
        to: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''(experimental) Properties to create PortRange.

        :param from_: (experimental) The first port in the range. Required if you specify 6 (TCP) or 17 (UDP) for the protocol parameter.
        :param to: (experimental) The last port in the range. Required if you specify 6 (TCP) or 17 (UDP) for the protocol parameter.

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if from_ is not None:
            self._values["from_"] = from_
        if to is not None:
            self._values["to"] = to

    @builtins.property
    def from_(self) -> typing.Optional[jsii.Number]:
        '''(experimental) The first port in the range.

        Required if you specify 6 (TCP) or 17 (UDP) for the protocol parameter.

        :stability: experimental
        '''
        result = self._values.get("from_")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def to(self) -> typing.Optional[jsii.Number]:
        '''(experimental) The last port in the range.

        Required if you specify 6 (TCP) or 17 (UDP) for the protocol parameter.

        :stability: experimental
        '''
        result = self._values.get("to")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AclPortRange(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class AclTraffic(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-ec2.AclTraffic",
):
    '''(experimental) The traffic that is configured using a Network ACL entry.

    :stability: experimental
    '''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_AclTrafficProxy"]:
        return _AclTrafficProxy

    def __init__(self) -> None:
        jsii.create(AclTraffic, self, [])

    @jsii.member(jsii_name="allTraffic") # type: ignore[misc]
    @builtins.classmethod
    def all_traffic(cls) -> "AclTraffic":
        '''(experimental) Apply the ACL entry to all traffic.

        :stability: experimental
        '''
        return typing.cast("AclTraffic", jsii.sinvoke(cls, "allTraffic", []))

    @jsii.member(jsii_name="icmp") # type: ignore[misc]
    @builtins.classmethod
    def icmp(
        cls,
        *,
        code: typing.Optional[jsii.Number] = None,
        type: typing.Optional[jsii.Number] = None,
    ) -> "AclTraffic":
        '''(experimental) Apply the ACL entry to ICMP traffic of given type and code.

        :param code: (experimental) The Internet Control Message Protocol (ICMP) code. You can use -1 to specify all ICMP codes for the given ICMP type. Requirement is conditional: Required if you specify 1 (ICMP) for the protocol parameter.
        :param type: (experimental) The Internet Control Message Protocol (ICMP) type. You can use -1 to specify all ICMP types. Conditional requirement: Required if you specify 1 (ICMP) for the CreateNetworkAclEntry protocol parameter.

        :stability: experimental
        '''
        props = AclIcmp(code=code, type=type)

        return typing.cast("AclTraffic", jsii.sinvoke(cls, "icmp", [props]))

    @jsii.member(jsii_name="icmpv6") # type: ignore[misc]
    @builtins.classmethod
    def icmpv6(
        cls,
        *,
        code: typing.Optional[jsii.Number] = None,
        type: typing.Optional[jsii.Number] = None,
    ) -> "AclTraffic":
        '''(experimental) Apply the ACL entry to ICMPv6 traffic of given type and code.

        Requires an IPv6 CIDR block.

        :param code: (experimental) The Internet Control Message Protocol (ICMP) code. You can use -1 to specify all ICMP codes for the given ICMP type. Requirement is conditional: Required if you specify 1 (ICMP) for the protocol parameter.
        :param type: (experimental) The Internet Control Message Protocol (ICMP) type. You can use -1 to specify all ICMP types. Conditional requirement: Required if you specify 1 (ICMP) for the CreateNetworkAclEntry protocol parameter.

        :stability: experimental
        '''
        props = AclIcmp(code=code, type=type)

        return typing.cast("AclTraffic", jsii.sinvoke(cls, "icmpv6", [props]))

    @jsii.member(jsii_name="tcpPort") # type: ignore[misc]
    @builtins.classmethod
    def tcp_port(cls, port: jsii.Number) -> "AclTraffic":
        '''(experimental) Apply the ACL entry to TCP traffic on a given port.

        :param port: -

        :stability: experimental
        '''
        return typing.cast("AclTraffic", jsii.sinvoke(cls, "tcpPort", [port]))

    @jsii.member(jsii_name="tcpPortRange") # type: ignore[misc]
    @builtins.classmethod
    def tcp_port_range(
        cls,
        start_port: jsii.Number,
        end_port: jsii.Number,
    ) -> "AclTraffic":
        '''(experimental) Apply the ACL entry to TCP traffic on a given port range.

        :param start_port: -
        :param end_port: -

        :stability: experimental
        '''
        return typing.cast("AclTraffic", jsii.sinvoke(cls, "tcpPortRange", [start_port, end_port]))

    @jsii.member(jsii_name="udpPort") # type: ignore[misc]
    @builtins.classmethod
    def udp_port(cls, port: jsii.Number) -> "AclTraffic":
        '''(experimental) Apply the ACL entry to UDP traffic on a given port.

        :param port: -

        :stability: experimental
        '''
        return typing.cast("AclTraffic", jsii.sinvoke(cls, "udpPort", [port]))

    @jsii.member(jsii_name="udpPortRange") # type: ignore[misc]
    @builtins.classmethod
    def udp_port_range(
        cls,
        start_port: jsii.Number,
        end_port: jsii.Number,
    ) -> "AclTraffic":
        '''(experimental) Apply the ACL entry to UDP traffic on a given port range.

        :param start_port: -
        :param end_port: -

        :stability: experimental
        '''
        return typing.cast("AclTraffic", jsii.sinvoke(cls, "udpPortRange", [start_port, end_port]))

    @jsii.member(jsii_name="toTrafficConfig") # type: ignore[misc]
    @abc.abstractmethod
    def to_traffic_config(self) -> "AclTrafficConfig":
        '''
        :stability: experimental
        '''
        ...


class _AclTrafficProxy(AclTraffic):
    @jsii.member(jsii_name="toTrafficConfig")
    def to_traffic_config(self) -> "AclTrafficConfig":
        '''
        :stability: experimental
        '''
        return typing.cast("AclTrafficConfig", jsii.invoke(self, "toTrafficConfig", []))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.AclTrafficConfig",
    jsii_struct_bases=[],
    name_mapping={"protocol": "protocol", "icmp": "icmp", "port_range": "portRange"},
)
class AclTrafficConfig:
    def __init__(
        self,
        *,
        protocol: jsii.Number,
        icmp: typing.Optional[AclIcmp] = None,
        port_range: typing.Optional[AclPortRange] = None,
    ) -> None:
        '''(experimental) Acl Configuration for traffic.

        :param protocol: (experimental) The protocol number. A value of "-1" means all protocols. If you specify "-1" or a protocol number other than "6" (TCP), "17" (UDP), or "1" (ICMP), traffic on all ports is allowed, regardless of any ports or ICMP types or codes that you specify. If you specify protocol "58" (ICMPv6) and specify an IPv4 CIDR block, traffic for all ICMP types and codes allowed, regardless of any that you specify. If you specify protocol "58" (ICMPv6) and specify an IPv6 CIDR block, you must specify an ICMP type and code. Default: 17
        :param icmp: (experimental) The Internet Control Message Protocol (ICMP) code and type. Default: - Required if specifying 1 (ICMP) for the protocol parameter.
        :param port_range: (experimental) The range of port numbers for the UDP/TCP protocol. Default: - Required if specifying 6 (TCP) or 17 (UDP) for the protocol parameter

        :stability: experimental
        '''
        if isinstance(icmp, dict):
            icmp = AclIcmp(**icmp)
        if isinstance(port_range, dict):
            port_range = AclPortRange(**port_range)
        self._values: typing.Dict[str, typing.Any] = {
            "protocol": protocol,
        }
        if icmp is not None:
            self._values["icmp"] = icmp
        if port_range is not None:
            self._values["port_range"] = port_range

    @builtins.property
    def protocol(self) -> jsii.Number:
        '''(experimental) The protocol number.

        A value of "-1" means all protocols.

        If you specify "-1" or a protocol number other than "6" (TCP), "17" (UDP),
        or "1" (ICMP), traffic on all ports is allowed, regardless of any ports or
        ICMP types or codes that you specify.

        If you specify protocol "58" (ICMPv6) and specify an IPv4 CIDR
        block, traffic for all ICMP types and codes allowed, regardless of any that
        you specify. If you specify protocol "58" (ICMPv6) and specify an IPv6 CIDR
        block, you must specify an ICMP type and code.

        :default: 17

        :stability: experimental
        '''
        result = self._values.get("protocol")
        assert result is not None, "Required property 'protocol' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def icmp(self) -> typing.Optional[AclIcmp]:
        '''(experimental) The Internet Control Message Protocol (ICMP) code and type.

        :default: - Required if specifying 1 (ICMP) for the protocol parameter.

        :stability: experimental
        '''
        result = self._values.get("icmp")
        return typing.cast(typing.Optional[AclIcmp], result)

    @builtins.property
    def port_range(self) -> typing.Optional[AclPortRange]:
        '''(experimental) The range of port numbers for the UDP/TCP protocol.

        :default: - Required if specifying 6 (TCP) or 17 (UDP) for the protocol parameter

        :stability: experimental
        '''
        result = self._values.get("port_range")
        return typing.cast(typing.Optional[AclPortRange], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AclTrafficConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.Action")
class Action(enum.Enum):
    '''(experimental) What action to apply to traffic matching the ACL.

    :stability: experimental
    '''

    ALLOW = "ALLOW"
    '''(experimental) Allow the traffic.

    :stability: experimental
    '''
    DENY = "DENY"
    '''(experimental) Deny the traffic.

    :stability: experimental
    '''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.AddRouteOptions",
    jsii_struct_bases=[],
    name_mapping={
        "router_id": "routerId",
        "router_type": "routerType",
        "destination_cidr_block": "destinationCidrBlock",
        "destination_ipv6_cidr_block": "destinationIpv6CidrBlock",
        "enables_internet_connectivity": "enablesInternetConnectivity",
    },
)
class AddRouteOptions:
    def __init__(
        self,
        *,
        router_id: builtins.str,
        router_type: "RouterType",
        destination_cidr_block: typing.Optional[builtins.str] = None,
        destination_ipv6_cidr_block: typing.Optional[builtins.str] = None,
        enables_internet_connectivity: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Options for adding a new route to a subnet.

        :param router_id: The ID of the router. Can be an instance ID, gateway ID, etc, depending on the router type.
        :param router_type: What type of router to route this traffic to.
        :param destination_cidr_block: IPv4 range this route applies to. Default: '0.0.0.0/0'
        :param destination_ipv6_cidr_block: IPv6 range this route applies to. Default: - Uses IPv6
        :param enables_internet_connectivity: Whether this route will enable internet connectivity. If true, this route will be added before any AWS resources that depend on internet connectivity in the VPC will be created. Default: false
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "router_id": router_id,
            "router_type": router_type,
        }
        if destination_cidr_block is not None:
            self._values["destination_cidr_block"] = destination_cidr_block
        if destination_ipv6_cidr_block is not None:
            self._values["destination_ipv6_cidr_block"] = destination_ipv6_cidr_block
        if enables_internet_connectivity is not None:
            self._values["enables_internet_connectivity"] = enables_internet_connectivity

    @builtins.property
    def router_id(self) -> builtins.str:
        '''The ID of the router.

        Can be an instance ID, gateway ID, etc, depending on the router type.
        '''
        result = self._values.get("router_id")
        assert result is not None, "Required property 'router_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def router_type(self) -> "RouterType":
        '''What type of router to route this traffic to.'''
        result = self._values.get("router_type")
        assert result is not None, "Required property 'router_type' is missing"
        return typing.cast("RouterType", result)

    @builtins.property
    def destination_cidr_block(self) -> typing.Optional[builtins.str]:
        '''IPv4 range this route applies to.

        :default: '0.0.0.0/0'
        '''
        result = self._values.get("destination_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def destination_ipv6_cidr_block(self) -> typing.Optional[builtins.str]:
        '''IPv6 range this route applies to.

        :default: - Uses IPv6
        '''
        result = self._values.get("destination_ipv6_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def enables_internet_connectivity(self) -> typing.Optional[builtins.bool]:
        '''Whether this route will enable internet connectivity.

        If true, this route will be added before any AWS resources that depend
        on internet connectivity in the VPC will be created.

        :default: false
        '''
        result = self._values.get("enables_internet_connectivity")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AddRouteOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.AmazonLinuxCpuType")
class AmazonLinuxCpuType(enum.Enum):
    '''CPU type.'''

    ARM_64 = "ARM_64"
    '''arm64 CPU type.'''
    X86_64 = "X86_64"
    '''x86_64 CPU type.'''


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.AmazonLinuxEdition")
class AmazonLinuxEdition(enum.Enum):
    '''Amazon Linux edition.'''

    STANDARD = "STANDARD"
    '''Standard edition.'''
    MINIMAL = "MINIMAL"
    '''Minimal edition.'''


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.AmazonLinuxGeneration")
class AmazonLinuxGeneration(enum.Enum):
    '''What generation of Amazon Linux to use.'''

    AMAZON_LINUX = "AMAZON_LINUX"
    '''Amazon Linux.'''
    AMAZON_LINUX_2 = "AMAZON_LINUX_2"
    '''Amazon Linux 2.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.AmazonLinuxImageProps",
    jsii_struct_bases=[],
    name_mapping={
        "cpu_type": "cpuType",
        "edition": "edition",
        "generation": "generation",
        "storage": "storage",
        "user_data": "userData",
        "virtualization": "virtualization",
    },
)
class AmazonLinuxImageProps:
    def __init__(
        self,
        *,
        cpu_type: typing.Optional[AmazonLinuxCpuType] = None,
        edition: typing.Optional[AmazonLinuxEdition] = None,
        generation: typing.Optional[AmazonLinuxGeneration] = None,
        storage: typing.Optional["AmazonLinuxStorage"] = None,
        user_data: typing.Optional["UserData"] = None,
        virtualization: typing.Optional["AmazonLinuxVirt"] = None,
    ) -> None:
        '''Amazon Linux image properties.

        :param cpu_type: CPU Type. Default: X86_64
        :param edition: What edition of Amazon Linux to use. Default: Standard
        :param generation: What generation of Amazon Linux to use. Default: AmazonLinux
        :param storage: What storage backed image to use. Default: GeneralPurpose
        :param user_data: Initial user data. Default: - Empty UserData for Linux machines
        :param virtualization: Virtualization type. Default: HVM
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if cpu_type is not None:
            self._values["cpu_type"] = cpu_type
        if edition is not None:
            self._values["edition"] = edition
        if generation is not None:
            self._values["generation"] = generation
        if storage is not None:
            self._values["storage"] = storage
        if user_data is not None:
            self._values["user_data"] = user_data
        if virtualization is not None:
            self._values["virtualization"] = virtualization

    @builtins.property
    def cpu_type(self) -> typing.Optional[AmazonLinuxCpuType]:
        '''CPU Type.

        :default: X86_64
        '''
        result = self._values.get("cpu_type")
        return typing.cast(typing.Optional[AmazonLinuxCpuType], result)

    @builtins.property
    def edition(self) -> typing.Optional[AmazonLinuxEdition]:
        '''What edition of Amazon Linux to use.

        :default: Standard
        '''
        result = self._values.get("edition")
        return typing.cast(typing.Optional[AmazonLinuxEdition], result)

    @builtins.property
    def generation(self) -> typing.Optional[AmazonLinuxGeneration]:
        '''What generation of Amazon Linux to use.

        :default: AmazonLinux
        '''
        result = self._values.get("generation")
        return typing.cast(typing.Optional[AmazonLinuxGeneration], result)

    @builtins.property
    def storage(self) -> typing.Optional["AmazonLinuxStorage"]:
        '''What storage backed image to use.

        :default: GeneralPurpose
        '''
        result = self._values.get("storage")
        return typing.cast(typing.Optional["AmazonLinuxStorage"], result)

    @builtins.property
    def user_data(self) -> typing.Optional["UserData"]:
        '''Initial user data.

        :default: - Empty UserData for Linux machines
        '''
        result = self._values.get("user_data")
        return typing.cast(typing.Optional["UserData"], result)

    @builtins.property
    def virtualization(self) -> typing.Optional["AmazonLinuxVirt"]:
        '''Virtualization type.

        :default: HVM
        '''
        result = self._values.get("virtualization")
        return typing.cast(typing.Optional["AmazonLinuxVirt"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AmazonLinuxImageProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.AmazonLinuxStorage")
class AmazonLinuxStorage(enum.Enum):
    EBS = "EBS"
    '''EBS-backed storage.'''
    GENERAL_PURPOSE = "GENERAL_PURPOSE"
    '''General Purpose-based storage (recommended).'''


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.AmazonLinuxVirt")
class AmazonLinuxVirt(enum.Enum):
    '''Virtualization type for Amazon Linux.'''

    HVM = "HVM"
    '''HVM virtualization (recommended).'''
    PV = "PV"
    '''PV virtualization.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.ApplyCloudFormationInitOptions",
    jsii_struct_bases=[],
    name_mapping={
        "config_sets": "configSets",
        "embed_fingerprint": "embedFingerprint",
        "ignore_failures": "ignoreFailures",
        "print_log": "printLog",
        "timeout": "timeout",
    },
)
class ApplyCloudFormationInitOptions:
    def __init__(
        self,
        *,
        config_sets: typing.Optional[typing.List[builtins.str]] = None,
        embed_fingerprint: typing.Optional[builtins.bool] = None,
        ignore_failures: typing.Optional[builtins.bool] = None,
        print_log: typing.Optional[builtins.bool] = None,
        timeout: typing.Optional[aws_cdk.core.Duration] = None,
    ) -> None:
        '''Options for applying CloudFormation init to an instance or instance group.

        :param config_sets: ConfigSet to activate. Default: ['default']
        :param embed_fingerprint: Force instance replacement by embedding a config fingerprint. If ``true`` (the default), a hash of the config will be embedded into the UserData, so that if the config changes, the UserData changes. - If the EC2 instance is instance-store backed or ``userDataCausesReplacement`` is set, this will cause the instance to be replaced and the new configuration to be applied. - If the instance is EBS-backed and ``userDataCausesReplacement`` is not set, the change of UserData will make the instance restart but not be replaced, and the configuration will not be applied automatically. If ``false``, no hash will be embedded, and if the CloudFormation Init config changes nothing will happen to the running instance. If a config update introduces errors, you will not notice until after the CloudFormation deployment successfully finishes and the next instance fails to launch. Default: true
        :param ignore_failures: Don't fail the instance creation when cfn-init fails. You can use this to prevent CloudFormation from rolling back when instances fail to start up, to help in debugging. Default: false
        :param print_log: Print the results of running cfn-init to the Instance System Log. By default, the output of running cfn-init is written to a log file on the instance. Set this to ``true`` to print it to the System Log (visible from the EC2 Console), ``false`` to not print it. (Be aware that the system log is refreshed at certain points in time of the instance life cycle, and successful execution may not always show up). Default: true
        :param timeout: Timeout waiting for the configuration to be applied. Default: Duration.minutes(5)
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if config_sets is not None:
            self._values["config_sets"] = config_sets
        if embed_fingerprint is not None:
            self._values["embed_fingerprint"] = embed_fingerprint
        if ignore_failures is not None:
            self._values["ignore_failures"] = ignore_failures
        if print_log is not None:
            self._values["print_log"] = print_log
        if timeout is not None:
            self._values["timeout"] = timeout

    @builtins.property
    def config_sets(self) -> typing.Optional[typing.List[builtins.str]]:
        '''ConfigSet to activate.

        :default: ['default']
        '''
        result = self._values.get("config_sets")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def embed_fingerprint(self) -> typing.Optional[builtins.bool]:
        '''Force instance replacement by embedding a config fingerprint.

        If ``true`` (the default), a hash of the config will be embedded into the
        UserData, so that if the config changes, the UserData changes.

        - If the EC2 instance is instance-store backed or
          ``userDataCausesReplacement`` is set, this will cause the instance to be
          replaced and the new configuration to be applied.
        - If the instance is EBS-backed and ``userDataCausesReplacement`` is not
          set, the change of UserData will make the instance restart but not be
          replaced, and the configuration will not be applied automatically.

        If ``false``, no hash will be embedded, and if the CloudFormation Init
        config changes nothing will happen to the running instance. If a
        config update introduces errors, you will not notice until after the
        CloudFormation deployment successfully finishes and the next instance
        fails to launch.

        :default: true
        '''
        result = self._values.get("embed_fingerprint")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def ignore_failures(self) -> typing.Optional[builtins.bool]:
        '''Don't fail the instance creation when cfn-init fails.

        You can use this to prevent CloudFormation from rolling back when
        instances fail to start up, to help in debugging.

        :default: false
        '''
        result = self._values.get("ignore_failures")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def print_log(self) -> typing.Optional[builtins.bool]:
        '''Print the results of running cfn-init to the Instance System Log.

        By default, the output of running cfn-init is written to a log file
        on the instance. Set this to ``true`` to print it to the System Log
        (visible from the EC2 Console), ``false`` to not print it.

        (Be aware that the system log is refreshed at certain points in
        time of the instance life cycle, and successful execution may
        not always show up).

        :default: true
        '''
        result = self._values.get("print_log")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def timeout(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''Timeout waiting for the configuration to be applied.

        :default: Duration.minutes(5)
        '''
        result = self._values.get("timeout")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ApplyCloudFormationInitOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.AttachInitOptions",
    jsii_struct_bases=[],
    name_mapping={
        "instance_role": "instanceRole",
        "platform": "platform",
        "user_data": "userData",
        "config_sets": "configSets",
        "embed_fingerprint": "embedFingerprint",
        "ignore_failures": "ignoreFailures",
        "print_log": "printLog",
    },
)
class AttachInitOptions:
    def __init__(
        self,
        *,
        instance_role: aws_cdk.aws_iam.IRole,
        platform: "OperatingSystemType",
        user_data: "UserData",
        config_sets: typing.Optional[typing.List[builtins.str]] = None,
        embed_fingerprint: typing.Optional[builtins.bool] = None,
        ignore_failures: typing.Optional[builtins.bool] = None,
        print_log: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Options for attaching a CloudFormationInit to a resource.

        :param instance_role: Instance role of the consuming instance or fleet.
        :param platform: OS Platform the init config will be used for.
        :param user_data: UserData to add commands to.
        :param config_sets: ConfigSet to activate. Default: ['default']
        :param embed_fingerprint: Whether to embed a hash into the userData. If ``true`` (the default), a hash of the config will be embedded into the UserData, so that if the config changes, the UserData changes and the instance will be replaced. If ``false``, no such hash will be embedded, and if the CloudFormation Init config changes nothing will happen to the running instance. Default: true
        :param ignore_failures: Don't fail the instance creation when cfn-init fails. You can use this to prevent CloudFormation from rolling back when instances fail to start up, to help in debugging. Default: false
        :param print_log: Print the results of running cfn-init to the Instance System Log. By default, the output of running cfn-init is written to a log file on the instance. Set this to ``true`` to print it to the System Log (visible from the EC2 Console), ``false`` to not print it. (Be aware that the system log is refreshed at certain points in time of the instance life cycle, and successful execution may not always show up). Default: true
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "instance_role": instance_role,
            "platform": platform,
            "user_data": user_data,
        }
        if config_sets is not None:
            self._values["config_sets"] = config_sets
        if embed_fingerprint is not None:
            self._values["embed_fingerprint"] = embed_fingerprint
        if ignore_failures is not None:
            self._values["ignore_failures"] = ignore_failures
        if print_log is not None:
            self._values["print_log"] = print_log

    @builtins.property
    def instance_role(self) -> aws_cdk.aws_iam.IRole:
        '''Instance role of the consuming instance or fleet.'''
        result = self._values.get("instance_role")
        assert result is not None, "Required property 'instance_role' is missing"
        return typing.cast(aws_cdk.aws_iam.IRole, result)

    @builtins.property
    def platform(self) -> "OperatingSystemType":
        '''OS Platform the init config will be used for.'''
        result = self._values.get("platform")
        assert result is not None, "Required property 'platform' is missing"
        return typing.cast("OperatingSystemType", result)

    @builtins.property
    def user_data(self) -> "UserData":
        '''UserData to add commands to.'''
        result = self._values.get("user_data")
        assert result is not None, "Required property 'user_data' is missing"
        return typing.cast("UserData", result)

    @builtins.property
    def config_sets(self) -> typing.Optional[typing.List[builtins.str]]:
        '''ConfigSet to activate.

        :default: ['default']
        '''
        result = self._values.get("config_sets")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def embed_fingerprint(self) -> typing.Optional[builtins.bool]:
        '''Whether to embed a hash into the userData.

        If ``true`` (the default), a hash of the config will be embedded into the
        UserData, so that if the config changes, the UserData changes and
        the instance will be replaced.

        If ``false``, no such hash will be embedded, and if the CloudFormation Init
        config changes nothing will happen to the running instance.

        :default: true
        '''
        result = self._values.get("embed_fingerprint")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def ignore_failures(self) -> typing.Optional[builtins.bool]:
        '''Don't fail the instance creation when cfn-init fails.

        You can use this to prevent CloudFormation from rolling back when
        instances fail to start up, to help in debugging.

        :default: false
        '''
        result = self._values.get("ignore_failures")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def print_log(self) -> typing.Optional[builtins.bool]:
        '''Print the results of running cfn-init to the Instance System Log.

        By default, the output of running cfn-init is written to a log file
        on the instance. Set this to ``true`` to print it to the System Log
        (visible from the EC2 Console), ``false`` to not print it.

        (Be aware that the system log is refreshed at certain points in
        time of the instance life cycle, and successful execution may
        not always show up).

        :default: true
        '''
        result = self._values.get("print_log")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AttachInitOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.BastionHostLinuxProps",
    jsii_struct_bases=[],
    name_mapping={
        "vpc": "vpc",
        "availability_zone": "availabilityZone",
        "block_devices": "blockDevices",
        "instance_name": "instanceName",
        "instance_type": "instanceType",
        "machine_image": "machineImage",
        "security_group": "securityGroup",
        "subnet_selection": "subnetSelection",
    },
)
class BastionHostLinuxProps:
    def __init__(
        self,
        *,
        vpc: "IVpc",
        availability_zone: typing.Optional[builtins.str] = None,
        block_devices: typing.Optional[typing.List["BlockDevice"]] = None,
        instance_name: typing.Optional[builtins.str] = None,
        instance_type: typing.Optional["InstanceType"] = None,
        machine_image: typing.Optional["IMachineImage"] = None,
        security_group: typing.Optional["ISecurityGroup"] = None,
        subnet_selection: typing.Optional["SubnetSelection"] = None,
    ) -> None:
        '''(experimental) Properties of the bastion host.

        :param vpc: (experimental) VPC to launch the instance in.
        :param availability_zone: (experimental) In which AZ to place the instance within the VPC. Default: - Random zone.
        :param block_devices: (experimental) Specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes. Each instance that is launched has an associated root device volume, either an Amazon EBS volume or an instance store volume. You can use block device mappings to specify additional EBS volumes or instance store volumes to attach to an instance when it is launched. Default: - Uses the block device mapping of the AMI
        :param instance_name: (experimental) The name of the instance. Default: 'BastionHost'
        :param instance_type: (experimental) Type of instance to launch. Default: 't3.nano'
        :param machine_image: (experimental) The machine image to use, assumed to have SSM Agent preinstalled. Default: - An Amazon Linux 2 image which is kept up-to-date automatically (the instance may be replaced on every deployment) and already has SSM Agent installed.
        :param security_group: (experimental) Security Group to assign to this instance. Default: - create new security group with no inbound and all outbound traffic allowed
        :param subnet_selection: (experimental) Select the subnets to run the bastion host in. Set this to PUBLIC if you need to connect to this instance via the internet and cannot use SSM. You have to allow port 22 manually by using the connections field Default: - private subnets of the supplied VPC

        :stability: experimental
        '''
        if isinstance(subnet_selection, dict):
            subnet_selection = SubnetSelection(**subnet_selection)
        self._values: typing.Dict[str, typing.Any] = {
            "vpc": vpc,
        }
        if availability_zone is not None:
            self._values["availability_zone"] = availability_zone
        if block_devices is not None:
            self._values["block_devices"] = block_devices
        if instance_name is not None:
            self._values["instance_name"] = instance_name
        if instance_type is not None:
            self._values["instance_type"] = instance_type
        if machine_image is not None:
            self._values["machine_image"] = machine_image
        if security_group is not None:
            self._values["security_group"] = security_group
        if subnet_selection is not None:
            self._values["subnet_selection"] = subnet_selection

    @builtins.property
    def vpc(self) -> "IVpc":
        '''(experimental) VPC to launch the instance in.

        :stability: experimental
        '''
        result = self._values.get("vpc")
        assert result is not None, "Required property 'vpc' is missing"
        return typing.cast("IVpc", result)

    @builtins.property
    def availability_zone(self) -> typing.Optional[builtins.str]:
        '''(experimental) In which AZ to place the instance within the VPC.

        :default: - Random zone.

        :stability: experimental
        '''
        result = self._values.get("availability_zone")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def block_devices(self) -> typing.Optional[typing.List["BlockDevice"]]:
        '''(experimental) Specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes.

        Each instance that is launched has an associated root device volume,
        either an Amazon EBS volume or an instance store volume.
        You can use block device mappings to specify additional EBS volumes or
        instance store volumes to attach to an instance when it is launched.

        :default: - Uses the block device mapping of the AMI

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html
        :stability: experimental
        '''
        result = self._values.get("block_devices")
        return typing.cast(typing.Optional[typing.List["BlockDevice"]], result)

    @builtins.property
    def instance_name(self) -> typing.Optional[builtins.str]:
        '''(experimental) The name of the instance.

        :default: 'BastionHost'

        :stability: experimental
        '''
        result = self._values.get("instance_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def instance_type(self) -> typing.Optional["InstanceType"]:
        '''(experimental) Type of instance to launch.

        :default: 't3.nano'

        :stability: experimental
        '''
        result = self._values.get("instance_type")
        return typing.cast(typing.Optional["InstanceType"], result)

    @builtins.property
    def machine_image(self) -> typing.Optional["IMachineImage"]:
        '''(experimental) The machine image to use, assumed to have SSM Agent preinstalled.

        :default:

        - An Amazon Linux 2 image which is kept up-to-date automatically (the instance
        may be replaced on every deployment) and already has SSM Agent installed.

        :stability: experimental
        '''
        result = self._values.get("machine_image")
        return typing.cast(typing.Optional["IMachineImage"], result)

    @builtins.property
    def security_group(self) -> typing.Optional["ISecurityGroup"]:
        '''(experimental) Security Group to assign to this instance.

        :default: - create new security group with no inbound and all outbound traffic allowed

        :stability: experimental
        '''
        result = self._values.get("security_group")
        return typing.cast(typing.Optional["ISecurityGroup"], result)

    @builtins.property
    def subnet_selection(self) -> typing.Optional["SubnetSelection"]:
        '''(experimental) Select the subnets to run the bastion host in.

        Set this to PUBLIC if you need to connect to this instance via the internet and cannot use SSM.
        You have to allow port 22 manually by using the connections field

        :default: - private subnets of the supplied VPC

        :stability: experimental
        '''
        result = self._values.get("subnet_selection")
        return typing.cast(typing.Optional["SubnetSelection"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "BastionHostLinuxProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.BlockDevice",
    jsii_struct_bases=[],
    name_mapping={
        "device_name": "deviceName",
        "volume": "volume",
        "mapping_enabled": "mappingEnabled",
    },
)
class BlockDevice:
    def __init__(
        self,
        *,
        device_name: builtins.str,
        volume: "BlockDeviceVolume",
        mapping_enabled: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Block device.

        :param device_name: The device name exposed to the EC2 instance.
        :param volume: Defines the block device volume, to be either an Amazon EBS volume or an ephemeral instance store volume.
        :param mapping_enabled: If false, the device mapping will be suppressed. If set to false for the root device, the instance might fail the Amazon EC2 health check. Amazon EC2 Auto Scaling launches a replacement instance if the instance fails the health check. Default: true - device mapping is left untouched
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "device_name": device_name,
            "volume": volume,
        }
        if mapping_enabled is not None:
            self._values["mapping_enabled"] = mapping_enabled

    @builtins.property
    def device_name(self) -> builtins.str:
        '''The device name exposed to the EC2 instance.

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html

        Example::

            # Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
            "/dev/sdh" , "xvdh"
        '''
        result = self._values.get("device_name")
        assert result is not None, "Required property 'device_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def volume(self) -> "BlockDeviceVolume":
        '''Defines the block device volume, to be either an Amazon EBS volume or an ephemeral instance store volume.

        Example::

            # Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
            BlockDeviceVolume.ebs(15) , BlockDeviceVolume.ephemeral(0)
        '''
        result = self._values.get("volume")
        assert result is not None, "Required property 'volume' is missing"
        return typing.cast("BlockDeviceVolume", result)

    @builtins.property
    def mapping_enabled(self) -> typing.Optional[builtins.bool]:
        '''If false, the device mapping will be suppressed.

        If set to false for the root device, the instance might fail the Amazon EC2 health check.
        Amazon EC2 Auto Scaling launches a replacement instance if the instance fails the health check.

        :default: true - device mapping is left untouched
        '''
        result = self._values.get("mapping_enabled")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "BlockDevice(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class BlockDeviceVolume(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.BlockDeviceVolume",
):
    '''Describes a block device mapping for an EC2 instance or Auto Scaling group.'''

    def __init__(
        self,
        ebs_device: typing.Optional["EbsDeviceProps"] = None,
        virtual_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param ebs_device: EBS device info.
        :param virtual_name: Virtual device name.
        '''
        jsii.create(BlockDeviceVolume, self, [ebs_device, virtual_name])

    @jsii.member(jsii_name="ebs") # type: ignore[misc]
    @builtins.classmethod
    def ebs(
        cls,
        volume_size: jsii.Number,
        *,
        encrypted: typing.Optional[builtins.bool] = None,
        delete_on_termination: typing.Optional[builtins.bool] = None,
        iops: typing.Optional[jsii.Number] = None,
        volume_type: typing.Optional["EbsDeviceVolumeType"] = None,
    ) -> "BlockDeviceVolume":
        '''Creates a new Elastic Block Storage device.

        :param volume_size: The volume size, in Gibibytes (GiB).
        :param encrypted: Specifies whether the EBS volume is encrypted. Encrypted EBS volumes can only be attached to instances that support Amazon EBS encryption Default: false
        :param delete_on_termination: Indicates whether to delete the volume when the instance is terminated. Default: - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS)
        :param iops: The number of I/O operations per second (IOPS) to provision for the volume. Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1} The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS, you need at least 100 GiB storage on the volume. Default: - none, required for {@link EbsDeviceVolumeType.IO1}
        :param volume_type: The EBS volume type. Default: {@link EbsDeviceVolumeType.GP2}
        '''
        options = EbsDeviceOptions(
            encrypted=encrypted,
            delete_on_termination=delete_on_termination,
            iops=iops,
            volume_type=volume_type,
        )

        return typing.cast("BlockDeviceVolume", jsii.sinvoke(cls, "ebs", [volume_size, options]))

    @jsii.member(jsii_name="ebsFromSnapshot") # type: ignore[misc]
    @builtins.classmethod
    def ebs_from_snapshot(
        cls,
        snapshot_id: builtins.str,
        *,
        volume_size: typing.Optional[jsii.Number] = None,
        delete_on_termination: typing.Optional[builtins.bool] = None,
        iops: typing.Optional[jsii.Number] = None,
        volume_type: typing.Optional["EbsDeviceVolumeType"] = None,
    ) -> "BlockDeviceVolume":
        '''Creates a new Elastic Block Storage device from an existing snapshot.

        :param snapshot_id: The snapshot ID of the volume to use.
        :param volume_size: The volume size, in Gibibytes (GiB). If you specify volumeSize, it must be equal or greater than the size of the snapshot. Default: - The snapshot size
        :param delete_on_termination: Indicates whether to delete the volume when the instance is terminated. Default: - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS)
        :param iops: The number of I/O operations per second (IOPS) to provision for the volume. Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1} The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS, you need at least 100 GiB storage on the volume. Default: - none, required for {@link EbsDeviceVolumeType.IO1}
        :param volume_type: The EBS volume type. Default: {@link EbsDeviceVolumeType.GP2}
        '''
        options = EbsDeviceSnapshotOptions(
            volume_size=volume_size,
            delete_on_termination=delete_on_termination,
            iops=iops,
            volume_type=volume_type,
        )

        return typing.cast("BlockDeviceVolume", jsii.sinvoke(cls, "ebsFromSnapshot", [snapshot_id, options]))

    @jsii.member(jsii_name="ephemeral") # type: ignore[misc]
    @builtins.classmethod
    def ephemeral(cls, volume_index: jsii.Number) -> "BlockDeviceVolume":
        '''Creates a virtual, ephemeral device.

        The name will be in the form ephemeral{volumeIndex}.

        :param volume_index: the volume index. Must be equal or greater than 0
        '''
        return typing.cast("BlockDeviceVolume", jsii.sinvoke(cls, "ephemeral", [volume_index]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ebsDevice")
    def ebs_device(self) -> typing.Optional["EbsDeviceProps"]:
        '''EBS device info.'''
        return typing.cast(typing.Optional["EbsDeviceProps"], jsii.get(self, "ebsDevice"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="virtualName")
    def virtual_name(self) -> typing.Optional[builtins.str]:
        '''Virtual device name.'''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "virtualName"))


@jsii.implements(aws_cdk.core.IInspectable)
class CfnCapacityReservation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnCapacityReservation",
):
    '''A CloudFormation ``AWS::EC2::CapacityReservation``.

    :cloudformationResource: AWS::EC2::CapacityReservation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        availability_zone: builtins.str,
        instance_count: jsii.Number,
        instance_platform: builtins.str,
        instance_type: builtins.str,
        ebs_optimized: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        end_date: typing.Optional[builtins.str] = None,
        end_date_type: typing.Optional[builtins.str] = None,
        ephemeral_storage: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        instance_match_criteria: typing.Optional[builtins.str] = None,
        tag_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnCapacityReservation.TagSpecificationProperty"]]]] = None,
        tenancy: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::CapacityReservation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param availability_zone: ``AWS::EC2::CapacityReservation.AvailabilityZone``.
        :param instance_count: ``AWS::EC2::CapacityReservation.InstanceCount``.
        :param instance_platform: ``AWS::EC2::CapacityReservation.InstancePlatform``.
        :param instance_type: ``AWS::EC2::CapacityReservation.InstanceType``.
        :param ebs_optimized: ``AWS::EC2::CapacityReservation.EbsOptimized``.
        :param end_date: ``AWS::EC2::CapacityReservation.EndDate``.
        :param end_date_type: ``AWS::EC2::CapacityReservation.EndDateType``.
        :param ephemeral_storage: ``AWS::EC2::CapacityReservation.EphemeralStorage``.
        :param instance_match_criteria: ``AWS::EC2::CapacityReservation.InstanceMatchCriteria``.
        :param tag_specifications: ``AWS::EC2::CapacityReservation.TagSpecifications``.
        :param tenancy: ``AWS::EC2::CapacityReservation.Tenancy``.
        '''
        props = CfnCapacityReservationProps(
            availability_zone=availability_zone,
            instance_count=instance_count,
            instance_platform=instance_platform,
            instance_type=instance_type,
            ebs_optimized=ebs_optimized,
            end_date=end_date,
            end_date_type=end_date_type,
            ephemeral_storage=ephemeral_storage,
            instance_match_criteria=instance_match_criteria,
            tag_specifications=tag_specifications,
            tenancy=tenancy,
        )

        jsii.create(CfnCapacityReservation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAvailabilityZone")
    def attr_availability_zone(self) -> builtins.str:
        '''
        :cloudformationAttribute: AvailabilityZone
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrAvailabilityZone"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAvailableInstanceCount")
    def attr_available_instance_count(self) -> jsii.Number:
        '''
        :cloudformationAttribute: AvailableInstanceCount
        '''
        return typing.cast(jsii.Number, jsii.get(self, "attrAvailableInstanceCount"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrInstanceType")
    def attr_instance_type(self) -> builtins.str:
        '''
        :cloudformationAttribute: InstanceType
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrInstanceType"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrTenancy")
    def attr_tenancy(self) -> builtins.str:
        '''
        :cloudformationAttribute: Tenancy
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrTenancy"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrTotalInstanceCount")
    def attr_total_instance_count(self) -> jsii.Number:
        '''
        :cloudformationAttribute: TotalInstanceCount
        '''
        return typing.cast(jsii.Number, jsii.get(self, "attrTotalInstanceCount"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> builtins.str:
        '''``AWS::EC2::CapacityReservation.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-availabilityzone
        '''
        return typing.cast(builtins.str, jsii.get(self, "availabilityZone"))

    @availability_zone.setter
    def availability_zone(self, value: builtins.str) -> None:
        jsii.set(self, "availabilityZone", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceCount")
    def instance_count(self) -> jsii.Number:
        '''``AWS::EC2::CapacityReservation.InstanceCount``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-instancecount
        '''
        return typing.cast(jsii.Number, jsii.get(self, "instanceCount"))

    @instance_count.setter
    def instance_count(self, value: jsii.Number) -> None:
        jsii.set(self, "instanceCount", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePlatform")
    def instance_platform(self) -> builtins.str:
        '''``AWS::EC2::CapacityReservation.InstancePlatform``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-instanceplatform
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePlatform"))

    @instance_platform.setter
    def instance_platform(self, value: builtins.str) -> None:
        jsii.set(self, "instancePlatform", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceType")
    def instance_type(self) -> builtins.str:
        '''``AWS::EC2::CapacityReservation.InstanceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-instancetype
        '''
        return typing.cast(builtins.str, jsii.get(self, "instanceType"))

    @instance_type.setter
    def instance_type(self, value: builtins.str) -> None:
        jsii.set(self, "instanceType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ebsOptimized")
    def ebs_optimized(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::CapacityReservation.EbsOptimized``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-ebsoptimized
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "ebsOptimized"))

    @ebs_optimized.setter
    def ebs_optimized(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "ebsOptimized", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="endDate")
    def end_date(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::CapacityReservation.EndDate``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-enddate
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "endDate"))

    @end_date.setter
    def end_date(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "endDate", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="endDateType")
    def end_date_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::CapacityReservation.EndDateType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-enddatetype
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "endDateType"))

    @end_date_type.setter
    def end_date_type(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "endDateType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ephemeralStorage")
    def ephemeral_storage(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::CapacityReservation.EphemeralStorage``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-ephemeralstorage
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "ephemeralStorage"))

    @ephemeral_storage.setter
    def ephemeral_storage(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "ephemeralStorage", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceMatchCriteria")
    def instance_match_criteria(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::CapacityReservation.InstanceMatchCriteria``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-instancematchcriteria
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "instanceMatchCriteria"))

    @instance_match_criteria.setter
    def instance_match_criteria(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "instanceMatchCriteria", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tagSpecifications")
    def tag_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnCapacityReservation.TagSpecificationProperty"]]]]:
        '''``AWS::EC2::CapacityReservation.TagSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-tagspecifications
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnCapacityReservation.TagSpecificationProperty"]]]], jsii.get(self, "tagSpecifications"))

    @tag_specifications.setter
    def tag_specifications(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnCapacityReservation.TagSpecificationProperty"]]]],
    ) -> None:
        jsii.set(self, "tagSpecifications", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tenancy")
    def tenancy(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::CapacityReservation.Tenancy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-tenancy
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "tenancy"))

    @tenancy.setter
    def tenancy(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "tenancy", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnCapacityReservation.TagSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"resource_type": "resourceType", "tags": "tags"},
    )
    class TagSpecificationProperty:
        def __init__(
            self,
            *,
            resource_type: typing.Optional[builtins.str] = None,
            tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        ) -> None:
            '''
            :param resource_type: ``CfnCapacityReservation.TagSpecificationProperty.ResourceType``.
            :param tags: ``CfnCapacityReservation.TagSpecificationProperty.Tags``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservation-tagspecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if resource_type is not None:
                self._values["resource_type"] = resource_type
            if tags is not None:
                self._values["tags"] = tags

        @builtins.property
        def resource_type(self) -> typing.Optional[builtins.str]:
            '''``CfnCapacityReservation.TagSpecificationProperty.ResourceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservation-tagspecification.html#cfn-ec2-capacityreservation-tagspecification-resourcetype
            '''
            result = self._values.get("resource_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
            '''``CfnCapacityReservation.TagSpecificationProperty.Tags``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservation-tagspecification.html#cfn-ec2-capacityreservation-tagspecification-tags
            '''
            result = self._values.get("tags")
            return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TagSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnCapacityReservationProps",
    jsii_struct_bases=[],
    name_mapping={
        "availability_zone": "availabilityZone",
        "instance_count": "instanceCount",
        "instance_platform": "instancePlatform",
        "instance_type": "instanceType",
        "ebs_optimized": "ebsOptimized",
        "end_date": "endDate",
        "end_date_type": "endDateType",
        "ephemeral_storage": "ephemeralStorage",
        "instance_match_criteria": "instanceMatchCriteria",
        "tag_specifications": "tagSpecifications",
        "tenancy": "tenancy",
    },
)
class CfnCapacityReservationProps:
    def __init__(
        self,
        *,
        availability_zone: builtins.str,
        instance_count: jsii.Number,
        instance_platform: builtins.str,
        instance_type: builtins.str,
        ebs_optimized: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        end_date: typing.Optional[builtins.str] = None,
        end_date_type: typing.Optional[builtins.str] = None,
        ephemeral_storage: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        instance_match_criteria: typing.Optional[builtins.str] = None,
        tag_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnCapacityReservation.TagSpecificationProperty]]]] = None,
        tenancy: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::CapacityReservation``.

        :param availability_zone: ``AWS::EC2::CapacityReservation.AvailabilityZone``.
        :param instance_count: ``AWS::EC2::CapacityReservation.InstanceCount``.
        :param instance_platform: ``AWS::EC2::CapacityReservation.InstancePlatform``.
        :param instance_type: ``AWS::EC2::CapacityReservation.InstanceType``.
        :param ebs_optimized: ``AWS::EC2::CapacityReservation.EbsOptimized``.
        :param end_date: ``AWS::EC2::CapacityReservation.EndDate``.
        :param end_date_type: ``AWS::EC2::CapacityReservation.EndDateType``.
        :param ephemeral_storage: ``AWS::EC2::CapacityReservation.EphemeralStorage``.
        :param instance_match_criteria: ``AWS::EC2::CapacityReservation.InstanceMatchCriteria``.
        :param tag_specifications: ``AWS::EC2::CapacityReservation.TagSpecifications``.
        :param tenancy: ``AWS::EC2::CapacityReservation.Tenancy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "availability_zone": availability_zone,
            "instance_count": instance_count,
            "instance_platform": instance_platform,
            "instance_type": instance_type,
        }
        if ebs_optimized is not None:
            self._values["ebs_optimized"] = ebs_optimized
        if end_date is not None:
            self._values["end_date"] = end_date
        if end_date_type is not None:
            self._values["end_date_type"] = end_date_type
        if ephemeral_storage is not None:
            self._values["ephemeral_storage"] = ephemeral_storage
        if instance_match_criteria is not None:
            self._values["instance_match_criteria"] = instance_match_criteria
        if tag_specifications is not None:
            self._values["tag_specifications"] = tag_specifications
        if tenancy is not None:
            self._values["tenancy"] = tenancy

    @builtins.property
    def availability_zone(self) -> builtins.str:
        '''``AWS::EC2::CapacityReservation.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-availabilityzone
        '''
        result = self._values.get("availability_zone")
        assert result is not None, "Required property 'availability_zone' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def instance_count(self) -> jsii.Number:
        '''``AWS::EC2::CapacityReservation.InstanceCount``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-instancecount
        '''
        result = self._values.get("instance_count")
        assert result is not None, "Required property 'instance_count' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def instance_platform(self) -> builtins.str:
        '''``AWS::EC2::CapacityReservation.InstancePlatform``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-instanceplatform
        '''
        result = self._values.get("instance_platform")
        assert result is not None, "Required property 'instance_platform' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def instance_type(self) -> builtins.str:
        '''``AWS::EC2::CapacityReservation.InstanceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-instancetype
        '''
        result = self._values.get("instance_type")
        assert result is not None, "Required property 'instance_type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def ebs_optimized(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::CapacityReservation.EbsOptimized``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-ebsoptimized
        '''
        result = self._values.get("ebs_optimized")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def end_date(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::CapacityReservation.EndDate``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-enddate
        '''
        result = self._values.get("end_date")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def end_date_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::CapacityReservation.EndDateType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-enddatetype
        '''
        result = self._values.get("end_date_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ephemeral_storage(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::CapacityReservation.EphemeralStorage``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-ephemeralstorage
        '''
        result = self._values.get("ephemeral_storage")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def instance_match_criteria(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::CapacityReservation.InstanceMatchCriteria``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-instancematchcriteria
        '''
        result = self._values.get("instance_match_criteria")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tag_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnCapacityReservation.TagSpecificationProperty]]]]:
        '''``AWS::EC2::CapacityReservation.TagSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-tagspecifications
        '''
        result = self._values.get("tag_specifications")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnCapacityReservation.TagSpecificationProperty]]]], result)

    @builtins.property
    def tenancy(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::CapacityReservation.Tenancy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservation.html#cfn-ec2-capacityreservation-tenancy
        '''
        result = self._values.get("tenancy")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnCapacityReservationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnCarrierGateway(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnCarrierGateway",
):
    '''A CloudFormation ``AWS::EC2::CarrierGateway``.

    :cloudformationResource: AWS::EC2::CarrierGateway
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-carriergateway.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        vpc_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::CarrierGateway``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param vpc_id: ``AWS::EC2::CarrierGateway.VpcId``.
        :param tags: ``AWS::EC2::CarrierGateway.Tags``.
        '''
        props = CfnCarrierGatewayProps(vpc_id=vpc_id, tags=tags)

        jsii.create(CfnCarrierGateway, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrCarrierGatewayId")
    def attr_carrier_gateway_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: CarrierGatewayId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrCarrierGatewayId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrOwnerId")
    def attr_owner_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: OwnerId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrOwnerId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrState")
    def attr_state(self) -> builtins.str:
        '''
        :cloudformationAttribute: State
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrState"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::CarrierGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-carriergateway.html#cfn-ec2-carriergateway-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::CarrierGateway.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-carriergateway.html#cfn-ec2-carriergateway-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnCarrierGatewayProps",
    jsii_struct_bases=[],
    name_mapping={"vpc_id": "vpcId", "tags": "tags"},
)
class CfnCarrierGatewayProps:
    def __init__(
        self,
        *,
        vpc_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::CarrierGateway``.

        :param vpc_id: ``AWS::EC2::CarrierGateway.VpcId``.
        :param tags: ``AWS::EC2::CarrierGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-carriergateway.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "vpc_id": vpc_id,
        }
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::CarrierGateway.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-carriergateway.html#cfn-ec2-carriergateway-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::CarrierGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-carriergateway.html#cfn-ec2-carriergateway-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnCarrierGatewayProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnClientVpnAuthorizationRule(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnClientVpnAuthorizationRule",
):
    '''A CloudFormation ``AWS::EC2::ClientVpnAuthorizationRule``.

    :cloudformationResource: AWS::EC2::ClientVpnAuthorizationRule
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        client_vpn_endpoint_id: builtins.str,
        target_network_cidr: builtins.str,
        access_group_id: typing.Optional[builtins.str] = None,
        authorize_all_groups: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::ClientVpnAuthorizationRule``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param client_vpn_endpoint_id: ``AWS::EC2::ClientVpnAuthorizationRule.ClientVpnEndpointId``.
        :param target_network_cidr: ``AWS::EC2::ClientVpnAuthorizationRule.TargetNetworkCidr``.
        :param access_group_id: ``AWS::EC2::ClientVpnAuthorizationRule.AccessGroupId``.
        :param authorize_all_groups: ``AWS::EC2::ClientVpnAuthorizationRule.AuthorizeAllGroups``.
        :param description: ``AWS::EC2::ClientVpnAuthorizationRule.Description``.
        '''
        props = CfnClientVpnAuthorizationRuleProps(
            client_vpn_endpoint_id=client_vpn_endpoint_id,
            target_network_cidr=target_network_cidr,
            access_group_id=access_group_id,
            authorize_all_groups=authorize_all_groups,
            description=description,
        )

        jsii.create(CfnClientVpnAuthorizationRule, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clientVpnEndpointId")
    def client_vpn_endpoint_id(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnAuthorizationRule.ClientVpnEndpointId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html#cfn-ec2-clientvpnauthorizationrule-clientvpnendpointid
        '''
        return typing.cast(builtins.str, jsii.get(self, "clientVpnEndpointId"))

    @client_vpn_endpoint_id.setter
    def client_vpn_endpoint_id(self, value: builtins.str) -> None:
        jsii.set(self, "clientVpnEndpointId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="targetNetworkCidr")
    def target_network_cidr(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnAuthorizationRule.TargetNetworkCidr``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html#cfn-ec2-clientvpnauthorizationrule-targetnetworkcidr
        '''
        return typing.cast(builtins.str, jsii.get(self, "targetNetworkCidr"))

    @target_network_cidr.setter
    def target_network_cidr(self, value: builtins.str) -> None:
        jsii.set(self, "targetNetworkCidr", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="accessGroupId")
    def access_group_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnAuthorizationRule.AccessGroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html#cfn-ec2-clientvpnauthorizationrule-accessgroupid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "accessGroupId"))

    @access_group_id.setter
    def access_group_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "accessGroupId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="authorizeAllGroups")
    def authorize_all_groups(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::ClientVpnAuthorizationRule.AuthorizeAllGroups``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html#cfn-ec2-clientvpnauthorizationrule-authorizeallgroups
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "authorizeAllGroups"))

    @authorize_all_groups.setter
    def authorize_all_groups(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "authorizeAllGroups", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnAuthorizationRule.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html#cfn-ec2-clientvpnauthorizationrule-description
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "description"))

    @description.setter
    def description(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "description", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnClientVpnAuthorizationRuleProps",
    jsii_struct_bases=[],
    name_mapping={
        "client_vpn_endpoint_id": "clientVpnEndpointId",
        "target_network_cidr": "targetNetworkCidr",
        "access_group_id": "accessGroupId",
        "authorize_all_groups": "authorizeAllGroups",
        "description": "description",
    },
)
class CfnClientVpnAuthorizationRuleProps:
    def __init__(
        self,
        *,
        client_vpn_endpoint_id: builtins.str,
        target_network_cidr: builtins.str,
        access_group_id: typing.Optional[builtins.str] = None,
        authorize_all_groups: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::ClientVpnAuthorizationRule``.

        :param client_vpn_endpoint_id: ``AWS::EC2::ClientVpnAuthorizationRule.ClientVpnEndpointId``.
        :param target_network_cidr: ``AWS::EC2::ClientVpnAuthorizationRule.TargetNetworkCidr``.
        :param access_group_id: ``AWS::EC2::ClientVpnAuthorizationRule.AccessGroupId``.
        :param authorize_all_groups: ``AWS::EC2::ClientVpnAuthorizationRule.AuthorizeAllGroups``.
        :param description: ``AWS::EC2::ClientVpnAuthorizationRule.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "client_vpn_endpoint_id": client_vpn_endpoint_id,
            "target_network_cidr": target_network_cidr,
        }
        if access_group_id is not None:
            self._values["access_group_id"] = access_group_id
        if authorize_all_groups is not None:
            self._values["authorize_all_groups"] = authorize_all_groups
        if description is not None:
            self._values["description"] = description

    @builtins.property
    def client_vpn_endpoint_id(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnAuthorizationRule.ClientVpnEndpointId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html#cfn-ec2-clientvpnauthorizationrule-clientvpnendpointid
        '''
        result = self._values.get("client_vpn_endpoint_id")
        assert result is not None, "Required property 'client_vpn_endpoint_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def target_network_cidr(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnAuthorizationRule.TargetNetworkCidr``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html#cfn-ec2-clientvpnauthorizationrule-targetnetworkcidr
        '''
        result = self._values.get("target_network_cidr")
        assert result is not None, "Required property 'target_network_cidr' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def access_group_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnAuthorizationRule.AccessGroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html#cfn-ec2-clientvpnauthorizationrule-accessgroupid
        '''
        result = self._values.get("access_group_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def authorize_all_groups(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::ClientVpnAuthorizationRule.AuthorizeAllGroups``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html#cfn-ec2-clientvpnauthorizationrule-authorizeallgroups
        '''
        result = self._values.get("authorize_all_groups")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnAuthorizationRule.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnauthorizationrule.html#cfn-ec2-clientvpnauthorizationrule-description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnClientVpnAuthorizationRuleProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnClientVpnEndpoint(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnClientVpnEndpoint",
):
    '''A CloudFormation ``AWS::EC2::ClientVpnEndpoint``.

    :cloudformationResource: AWS::EC2::ClientVpnEndpoint
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        authentication_options: typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union["CfnClientVpnEndpoint.ClientAuthenticationRequestProperty", aws_cdk.core.IResolvable]]],
        client_cidr_block: builtins.str,
        connection_log_options: typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.ConnectionLogOptionsProperty"],
        server_certificate_arn: builtins.str,
        client_connect_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.ClientConnectOptionsProperty"]] = None,
        description: typing.Optional[builtins.str] = None,
        dns_servers: typing.Optional[typing.List[builtins.str]] = None,
        security_group_ids: typing.Optional[typing.List[builtins.str]] = None,
        self_service_portal: typing.Optional[builtins.str] = None,
        split_tunnel: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        tag_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.TagSpecificationProperty"]]]] = None,
        transport_protocol: typing.Optional[builtins.str] = None,
        vpc_id: typing.Optional[builtins.str] = None,
        vpn_port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::ClientVpnEndpoint``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param authentication_options: ``AWS::EC2::ClientVpnEndpoint.AuthenticationOptions``.
        :param client_cidr_block: ``AWS::EC2::ClientVpnEndpoint.ClientCidrBlock``.
        :param connection_log_options: ``AWS::EC2::ClientVpnEndpoint.ConnectionLogOptions``.
        :param server_certificate_arn: ``AWS::EC2::ClientVpnEndpoint.ServerCertificateArn``.
        :param client_connect_options: ``AWS::EC2::ClientVpnEndpoint.ClientConnectOptions``.
        :param description: ``AWS::EC2::ClientVpnEndpoint.Description``.
        :param dns_servers: ``AWS::EC2::ClientVpnEndpoint.DnsServers``.
        :param security_group_ids: ``AWS::EC2::ClientVpnEndpoint.SecurityGroupIds``.
        :param self_service_portal: ``AWS::EC2::ClientVpnEndpoint.SelfServicePortal``.
        :param split_tunnel: ``AWS::EC2::ClientVpnEndpoint.SplitTunnel``.
        :param tag_specifications: ``AWS::EC2::ClientVpnEndpoint.TagSpecifications``.
        :param transport_protocol: ``AWS::EC2::ClientVpnEndpoint.TransportProtocol``.
        :param vpc_id: ``AWS::EC2::ClientVpnEndpoint.VpcId``.
        :param vpn_port: ``AWS::EC2::ClientVpnEndpoint.VpnPort``.
        '''
        props = CfnClientVpnEndpointProps(
            authentication_options=authentication_options,
            client_cidr_block=client_cidr_block,
            connection_log_options=connection_log_options,
            server_certificate_arn=server_certificate_arn,
            client_connect_options=client_connect_options,
            description=description,
            dns_servers=dns_servers,
            security_group_ids=security_group_ids,
            self_service_portal=self_service_portal,
            split_tunnel=split_tunnel,
            tag_specifications=tag_specifications,
            transport_protocol=transport_protocol,
            vpc_id=vpc_id,
            vpn_port=vpn_port,
        )

        jsii.create(CfnClientVpnEndpoint, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="authenticationOptions")
    def authentication_options(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union["CfnClientVpnEndpoint.ClientAuthenticationRequestProperty", aws_cdk.core.IResolvable]]]:
        '''``AWS::EC2::ClientVpnEndpoint.AuthenticationOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-authenticationoptions
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union["CfnClientVpnEndpoint.ClientAuthenticationRequestProperty", aws_cdk.core.IResolvable]]], jsii.get(self, "authenticationOptions"))

    @authentication_options.setter
    def authentication_options(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union["CfnClientVpnEndpoint.ClientAuthenticationRequestProperty", aws_cdk.core.IResolvable]]],
    ) -> None:
        jsii.set(self, "authenticationOptions", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clientCidrBlock")
    def client_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnEndpoint.ClientCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-clientcidrblock
        '''
        return typing.cast(builtins.str, jsii.get(self, "clientCidrBlock"))

    @client_cidr_block.setter
    def client_cidr_block(self, value: builtins.str) -> None:
        jsii.set(self, "clientCidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connectionLogOptions")
    def connection_log_options(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.ConnectionLogOptionsProperty"]:
        '''``AWS::EC2::ClientVpnEndpoint.ConnectionLogOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-connectionlogoptions
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.ConnectionLogOptionsProperty"], jsii.get(self, "connectionLogOptions"))

    @connection_log_options.setter
    def connection_log_options(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.ConnectionLogOptionsProperty"],
    ) -> None:
        jsii.set(self, "connectionLogOptions", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="serverCertificateArn")
    def server_certificate_arn(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnEndpoint.ServerCertificateArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-servercertificatearn
        '''
        return typing.cast(builtins.str, jsii.get(self, "serverCertificateArn"))

    @server_certificate_arn.setter
    def server_certificate_arn(self, value: builtins.str) -> None:
        jsii.set(self, "serverCertificateArn", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clientConnectOptions")
    def client_connect_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.ClientConnectOptionsProperty"]]:
        '''``AWS::EC2::ClientVpnEndpoint.ClientConnectOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-clientconnectoptions
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.ClientConnectOptionsProperty"]], jsii.get(self, "clientConnectOptions"))

    @client_connect_options.setter
    def client_connect_options(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.ClientConnectOptionsProperty"]],
    ) -> None:
        jsii.set(self, "clientConnectOptions", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnEndpoint.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-description
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "description"))

    @description.setter
    def description(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="dnsServers")
    def dns_servers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::ClientVpnEndpoint.DnsServers``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-dnsservers
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "dnsServers"))

    @dns_servers.setter
    def dns_servers(self, value: typing.Optional[typing.List[builtins.str]]) -> None:
        jsii.set(self, "dnsServers", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroupIds")
    def security_group_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::ClientVpnEndpoint.SecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-securitygroupids
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "securityGroupIds"))

    @security_group_ids.setter
    def security_group_ids(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "securityGroupIds", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="selfServicePortal")
    def self_service_portal(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnEndpoint.SelfServicePortal``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-selfserviceportal
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "selfServicePortal"))

    @self_service_portal.setter
    def self_service_portal(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "selfServicePortal", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="splitTunnel")
    def split_tunnel(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::ClientVpnEndpoint.SplitTunnel``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-splittunnel
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "splitTunnel"))

    @split_tunnel.setter
    def split_tunnel(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "splitTunnel", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tagSpecifications")
    def tag_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.TagSpecificationProperty"]]]]:
        '''``AWS::EC2::ClientVpnEndpoint.TagSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-tagspecifications
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.TagSpecificationProperty"]]]], jsii.get(self, "tagSpecifications"))

    @tag_specifications.setter
    def tag_specifications(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.TagSpecificationProperty"]]]],
    ) -> None:
        jsii.set(self, "tagSpecifications", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transportProtocol")
    def transport_protocol(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnEndpoint.TransportProtocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-transportprotocol
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "transportProtocol"))

    @transport_protocol.setter
    def transport_protocol(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "transportProtocol", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnEndpoint.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-vpcid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "vpcId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnPort")
    def vpn_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::ClientVpnEndpoint.VpnPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-vpnport
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "vpnPort"))

    @vpn_port.setter
    def vpn_port(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "vpnPort", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnClientVpnEndpoint.CertificateAuthenticationRequestProperty",
        jsii_struct_bases=[],
        name_mapping={
            "client_root_certificate_chain_arn": "clientRootCertificateChainArn",
        },
    )
    class CertificateAuthenticationRequestProperty:
        def __init__(self, *, client_root_certificate_chain_arn: builtins.str) -> None:
            '''
            :param client_root_certificate_chain_arn: ``CfnClientVpnEndpoint.CertificateAuthenticationRequestProperty.ClientRootCertificateChainArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-certificateauthenticationrequest.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "client_root_certificate_chain_arn": client_root_certificate_chain_arn,
            }

        @builtins.property
        def client_root_certificate_chain_arn(self) -> builtins.str:
            '''``CfnClientVpnEndpoint.CertificateAuthenticationRequestProperty.ClientRootCertificateChainArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-certificateauthenticationrequest.html#cfn-ec2-clientvpnendpoint-certificateauthenticationrequest-clientrootcertificatechainarn
            '''
            result = self._values.get("client_root_certificate_chain_arn")
            assert result is not None, "Required property 'client_root_certificate_chain_arn' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CertificateAuthenticationRequestProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnClientVpnEndpoint.ClientAuthenticationRequestProperty",
        jsii_struct_bases=[],
        name_mapping={
            "type": "type",
            "active_directory": "activeDirectory",
            "federated_authentication": "federatedAuthentication",
            "mutual_authentication": "mutualAuthentication",
        },
    )
    class ClientAuthenticationRequestProperty:
        def __init__(
            self,
            *,
            type: builtins.str,
            active_directory: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.DirectoryServiceAuthenticationRequestProperty"]] = None,
            federated_authentication: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.FederatedAuthenticationRequestProperty"]] = None,
            mutual_authentication: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.CertificateAuthenticationRequestProperty"]] = None,
        ) -> None:
            '''
            :param type: ``CfnClientVpnEndpoint.ClientAuthenticationRequestProperty.Type``.
            :param active_directory: ``CfnClientVpnEndpoint.ClientAuthenticationRequestProperty.ActiveDirectory``.
            :param federated_authentication: ``CfnClientVpnEndpoint.ClientAuthenticationRequestProperty.FederatedAuthentication``.
            :param mutual_authentication: ``CfnClientVpnEndpoint.ClientAuthenticationRequestProperty.MutualAuthentication``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-clientauthenticationrequest.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "type": type,
            }
            if active_directory is not None:
                self._values["active_directory"] = active_directory
            if federated_authentication is not None:
                self._values["federated_authentication"] = federated_authentication
            if mutual_authentication is not None:
                self._values["mutual_authentication"] = mutual_authentication

        @builtins.property
        def type(self) -> builtins.str:
            '''``CfnClientVpnEndpoint.ClientAuthenticationRequestProperty.Type``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-clientauthenticationrequest.html#cfn-ec2-clientvpnendpoint-clientauthenticationrequest-type
            '''
            result = self._values.get("type")
            assert result is not None, "Required property 'type' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def active_directory(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.DirectoryServiceAuthenticationRequestProperty"]]:
            '''``CfnClientVpnEndpoint.ClientAuthenticationRequestProperty.ActiveDirectory``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-clientauthenticationrequest.html#cfn-ec2-clientvpnendpoint-clientauthenticationrequest-activedirectory
            '''
            result = self._values.get("active_directory")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.DirectoryServiceAuthenticationRequestProperty"]], result)

        @builtins.property
        def federated_authentication(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.FederatedAuthenticationRequestProperty"]]:
            '''``CfnClientVpnEndpoint.ClientAuthenticationRequestProperty.FederatedAuthentication``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-clientauthenticationrequest.html#cfn-ec2-clientvpnendpoint-clientauthenticationrequest-federatedauthentication
            '''
            result = self._values.get("federated_authentication")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.FederatedAuthenticationRequestProperty"]], result)

        @builtins.property
        def mutual_authentication(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.CertificateAuthenticationRequestProperty"]]:
            '''``CfnClientVpnEndpoint.ClientAuthenticationRequestProperty.MutualAuthentication``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-clientauthenticationrequest.html#cfn-ec2-clientvpnendpoint-clientauthenticationrequest-mutualauthentication
            '''
            result = self._values.get("mutual_authentication")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnClientVpnEndpoint.CertificateAuthenticationRequestProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ClientAuthenticationRequestProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnClientVpnEndpoint.ClientConnectOptionsProperty",
        jsii_struct_bases=[],
        name_mapping={
            "enabled": "enabled",
            "lambda_function_arn": "lambdaFunctionArn",
        },
    )
    class ClientConnectOptionsProperty:
        def __init__(
            self,
            *,
            enabled: typing.Union[builtins.bool, aws_cdk.core.IResolvable],
            lambda_function_arn: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param enabled: ``CfnClientVpnEndpoint.ClientConnectOptionsProperty.Enabled``.
            :param lambda_function_arn: ``CfnClientVpnEndpoint.ClientConnectOptionsProperty.LambdaFunctionArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-clientconnectoptions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "enabled": enabled,
            }
            if lambda_function_arn is not None:
                self._values["lambda_function_arn"] = lambda_function_arn

        @builtins.property
        def enabled(self) -> typing.Union[builtins.bool, aws_cdk.core.IResolvable]:
            '''``CfnClientVpnEndpoint.ClientConnectOptionsProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-clientconnectoptions.html#cfn-ec2-clientvpnendpoint-clientconnectoptions-enabled
            '''
            result = self._values.get("enabled")
            assert result is not None, "Required property 'enabled' is missing"
            return typing.cast(typing.Union[builtins.bool, aws_cdk.core.IResolvable], result)

        @builtins.property
        def lambda_function_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnClientVpnEndpoint.ClientConnectOptionsProperty.LambdaFunctionArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-clientconnectoptions.html#cfn-ec2-clientvpnendpoint-clientconnectoptions-lambdafunctionarn
            '''
            result = self._values.get("lambda_function_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ClientConnectOptionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnClientVpnEndpoint.ConnectionLogOptionsProperty",
        jsii_struct_bases=[],
        name_mapping={
            "enabled": "enabled",
            "cloudwatch_log_group": "cloudwatchLogGroup",
            "cloudwatch_log_stream": "cloudwatchLogStream",
        },
    )
    class ConnectionLogOptionsProperty:
        def __init__(
            self,
            *,
            enabled: typing.Union[builtins.bool, aws_cdk.core.IResolvable],
            cloudwatch_log_group: typing.Optional[builtins.str] = None,
            cloudwatch_log_stream: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param enabled: ``CfnClientVpnEndpoint.ConnectionLogOptionsProperty.Enabled``.
            :param cloudwatch_log_group: ``CfnClientVpnEndpoint.ConnectionLogOptionsProperty.CloudwatchLogGroup``.
            :param cloudwatch_log_stream: ``CfnClientVpnEndpoint.ConnectionLogOptionsProperty.CloudwatchLogStream``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-connectionlogoptions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "enabled": enabled,
            }
            if cloudwatch_log_group is not None:
                self._values["cloudwatch_log_group"] = cloudwatch_log_group
            if cloudwatch_log_stream is not None:
                self._values["cloudwatch_log_stream"] = cloudwatch_log_stream

        @builtins.property
        def enabled(self) -> typing.Union[builtins.bool, aws_cdk.core.IResolvable]:
            '''``CfnClientVpnEndpoint.ConnectionLogOptionsProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-connectionlogoptions.html#cfn-ec2-clientvpnendpoint-connectionlogoptions-enabled
            '''
            result = self._values.get("enabled")
            assert result is not None, "Required property 'enabled' is missing"
            return typing.cast(typing.Union[builtins.bool, aws_cdk.core.IResolvable], result)

        @builtins.property
        def cloudwatch_log_group(self) -> typing.Optional[builtins.str]:
            '''``CfnClientVpnEndpoint.ConnectionLogOptionsProperty.CloudwatchLogGroup``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-connectionlogoptions.html#cfn-ec2-clientvpnendpoint-connectionlogoptions-cloudwatchloggroup
            '''
            result = self._values.get("cloudwatch_log_group")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def cloudwatch_log_stream(self) -> typing.Optional[builtins.str]:
            '''``CfnClientVpnEndpoint.ConnectionLogOptionsProperty.CloudwatchLogStream``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-connectionlogoptions.html#cfn-ec2-clientvpnendpoint-connectionlogoptions-cloudwatchlogstream
            '''
            result = self._values.get("cloudwatch_log_stream")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ConnectionLogOptionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnClientVpnEndpoint.DirectoryServiceAuthenticationRequestProperty",
        jsii_struct_bases=[],
        name_mapping={"directory_id": "directoryId"},
    )
    class DirectoryServiceAuthenticationRequestProperty:
        def __init__(self, *, directory_id: builtins.str) -> None:
            '''
            :param directory_id: ``CfnClientVpnEndpoint.DirectoryServiceAuthenticationRequestProperty.DirectoryId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-directoryserviceauthenticationrequest.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "directory_id": directory_id,
            }

        @builtins.property
        def directory_id(self) -> builtins.str:
            '''``CfnClientVpnEndpoint.DirectoryServiceAuthenticationRequestProperty.DirectoryId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-directoryserviceauthenticationrequest.html#cfn-ec2-clientvpnendpoint-directoryserviceauthenticationrequest-directoryid
            '''
            result = self._values.get("directory_id")
            assert result is not None, "Required property 'directory_id' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "DirectoryServiceAuthenticationRequestProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnClientVpnEndpoint.FederatedAuthenticationRequestProperty",
        jsii_struct_bases=[],
        name_mapping={
            "saml_provider_arn": "samlProviderArn",
            "self_service_saml_provider_arn": "selfServiceSamlProviderArn",
        },
    )
    class FederatedAuthenticationRequestProperty:
        def __init__(
            self,
            *,
            saml_provider_arn: builtins.str,
            self_service_saml_provider_arn: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param saml_provider_arn: ``CfnClientVpnEndpoint.FederatedAuthenticationRequestProperty.SAMLProviderArn``.
            :param self_service_saml_provider_arn: ``CfnClientVpnEndpoint.FederatedAuthenticationRequestProperty.SelfServiceSAMLProviderArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-federatedauthenticationrequest.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "saml_provider_arn": saml_provider_arn,
            }
            if self_service_saml_provider_arn is not None:
                self._values["self_service_saml_provider_arn"] = self_service_saml_provider_arn

        @builtins.property
        def saml_provider_arn(self) -> builtins.str:
            '''``CfnClientVpnEndpoint.FederatedAuthenticationRequestProperty.SAMLProviderArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-federatedauthenticationrequest.html#cfn-ec2-clientvpnendpoint-federatedauthenticationrequest-samlproviderarn
            '''
            result = self._values.get("saml_provider_arn")
            assert result is not None, "Required property 'saml_provider_arn' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def self_service_saml_provider_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnClientVpnEndpoint.FederatedAuthenticationRequestProperty.SelfServiceSAMLProviderArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-federatedauthenticationrequest.html#cfn-ec2-clientvpnendpoint-federatedauthenticationrequest-selfservicesamlproviderarn
            '''
            result = self._values.get("self_service_saml_provider_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "FederatedAuthenticationRequestProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnClientVpnEndpoint.TagSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"resource_type": "resourceType", "tags": "tags"},
    )
    class TagSpecificationProperty:
        def __init__(
            self,
            *,
            resource_type: builtins.str,
            tags: typing.List[aws_cdk.core.CfnTag],
        ) -> None:
            '''
            :param resource_type: ``CfnClientVpnEndpoint.TagSpecificationProperty.ResourceType``.
            :param tags: ``CfnClientVpnEndpoint.TagSpecificationProperty.Tags``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-tagspecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "resource_type": resource_type,
                "tags": tags,
            }

        @builtins.property
        def resource_type(self) -> builtins.str:
            '''``CfnClientVpnEndpoint.TagSpecificationProperty.ResourceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-tagspecification.html#cfn-ec2-clientvpnendpoint-tagspecification-resourcetype
            '''
            result = self._values.get("resource_type")
            assert result is not None, "Required property 'resource_type' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def tags(self) -> typing.List[aws_cdk.core.CfnTag]:
            '''``CfnClientVpnEndpoint.TagSpecificationProperty.Tags``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-tagspecification.html#cfn-ec2-clientvpnendpoint-tagspecification-tags
            '''
            result = self._values.get("tags")
            assert result is not None, "Required property 'tags' is missing"
            return typing.cast(typing.List[aws_cdk.core.CfnTag], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TagSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnClientVpnEndpointProps",
    jsii_struct_bases=[],
    name_mapping={
        "authentication_options": "authenticationOptions",
        "client_cidr_block": "clientCidrBlock",
        "connection_log_options": "connectionLogOptions",
        "server_certificate_arn": "serverCertificateArn",
        "client_connect_options": "clientConnectOptions",
        "description": "description",
        "dns_servers": "dnsServers",
        "security_group_ids": "securityGroupIds",
        "self_service_portal": "selfServicePortal",
        "split_tunnel": "splitTunnel",
        "tag_specifications": "tagSpecifications",
        "transport_protocol": "transportProtocol",
        "vpc_id": "vpcId",
        "vpn_port": "vpnPort",
    },
)
class CfnClientVpnEndpointProps:
    def __init__(
        self,
        *,
        authentication_options: typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[CfnClientVpnEndpoint.ClientAuthenticationRequestProperty, aws_cdk.core.IResolvable]]],
        client_cidr_block: builtins.str,
        connection_log_options: typing.Union[aws_cdk.core.IResolvable, CfnClientVpnEndpoint.ConnectionLogOptionsProperty],
        server_certificate_arn: builtins.str,
        client_connect_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnClientVpnEndpoint.ClientConnectOptionsProperty]] = None,
        description: typing.Optional[builtins.str] = None,
        dns_servers: typing.Optional[typing.List[builtins.str]] = None,
        security_group_ids: typing.Optional[typing.List[builtins.str]] = None,
        self_service_portal: typing.Optional[builtins.str] = None,
        split_tunnel: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        tag_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnClientVpnEndpoint.TagSpecificationProperty]]]] = None,
        transport_protocol: typing.Optional[builtins.str] = None,
        vpc_id: typing.Optional[builtins.str] = None,
        vpn_port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::ClientVpnEndpoint``.

        :param authentication_options: ``AWS::EC2::ClientVpnEndpoint.AuthenticationOptions``.
        :param client_cidr_block: ``AWS::EC2::ClientVpnEndpoint.ClientCidrBlock``.
        :param connection_log_options: ``AWS::EC2::ClientVpnEndpoint.ConnectionLogOptions``.
        :param server_certificate_arn: ``AWS::EC2::ClientVpnEndpoint.ServerCertificateArn``.
        :param client_connect_options: ``AWS::EC2::ClientVpnEndpoint.ClientConnectOptions``.
        :param description: ``AWS::EC2::ClientVpnEndpoint.Description``.
        :param dns_servers: ``AWS::EC2::ClientVpnEndpoint.DnsServers``.
        :param security_group_ids: ``AWS::EC2::ClientVpnEndpoint.SecurityGroupIds``.
        :param self_service_portal: ``AWS::EC2::ClientVpnEndpoint.SelfServicePortal``.
        :param split_tunnel: ``AWS::EC2::ClientVpnEndpoint.SplitTunnel``.
        :param tag_specifications: ``AWS::EC2::ClientVpnEndpoint.TagSpecifications``.
        :param transport_protocol: ``AWS::EC2::ClientVpnEndpoint.TransportProtocol``.
        :param vpc_id: ``AWS::EC2::ClientVpnEndpoint.VpcId``.
        :param vpn_port: ``AWS::EC2::ClientVpnEndpoint.VpnPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "authentication_options": authentication_options,
            "client_cidr_block": client_cidr_block,
            "connection_log_options": connection_log_options,
            "server_certificate_arn": server_certificate_arn,
        }
        if client_connect_options is not None:
            self._values["client_connect_options"] = client_connect_options
        if description is not None:
            self._values["description"] = description
        if dns_servers is not None:
            self._values["dns_servers"] = dns_servers
        if security_group_ids is not None:
            self._values["security_group_ids"] = security_group_ids
        if self_service_portal is not None:
            self._values["self_service_portal"] = self_service_portal
        if split_tunnel is not None:
            self._values["split_tunnel"] = split_tunnel
        if tag_specifications is not None:
            self._values["tag_specifications"] = tag_specifications
        if transport_protocol is not None:
            self._values["transport_protocol"] = transport_protocol
        if vpc_id is not None:
            self._values["vpc_id"] = vpc_id
        if vpn_port is not None:
            self._values["vpn_port"] = vpn_port

    @builtins.property
    def authentication_options(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[CfnClientVpnEndpoint.ClientAuthenticationRequestProperty, aws_cdk.core.IResolvable]]]:
        '''``AWS::EC2::ClientVpnEndpoint.AuthenticationOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-authenticationoptions
        '''
        result = self._values.get("authentication_options")
        assert result is not None, "Required property 'authentication_options' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[CfnClientVpnEndpoint.ClientAuthenticationRequestProperty, aws_cdk.core.IResolvable]]], result)

    @builtins.property
    def client_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnEndpoint.ClientCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-clientcidrblock
        '''
        result = self._values.get("client_cidr_block")
        assert result is not None, "Required property 'client_cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def connection_log_options(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnClientVpnEndpoint.ConnectionLogOptionsProperty]:
        '''``AWS::EC2::ClientVpnEndpoint.ConnectionLogOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-connectionlogoptions
        '''
        result = self._values.get("connection_log_options")
        assert result is not None, "Required property 'connection_log_options' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnClientVpnEndpoint.ConnectionLogOptionsProperty], result)

    @builtins.property
    def server_certificate_arn(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnEndpoint.ServerCertificateArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-servercertificatearn
        '''
        result = self._values.get("server_certificate_arn")
        assert result is not None, "Required property 'server_certificate_arn' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def client_connect_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnClientVpnEndpoint.ClientConnectOptionsProperty]]:
        '''``AWS::EC2::ClientVpnEndpoint.ClientConnectOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-clientconnectoptions
        '''
        result = self._values.get("client_connect_options")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnClientVpnEndpoint.ClientConnectOptionsProperty]], result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnEndpoint.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def dns_servers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::ClientVpnEndpoint.DnsServers``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-dnsservers
        '''
        result = self._values.get("dns_servers")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def security_group_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::ClientVpnEndpoint.SecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-securitygroupids
        '''
        result = self._values.get("security_group_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def self_service_portal(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnEndpoint.SelfServicePortal``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-selfserviceportal
        '''
        result = self._values.get("self_service_portal")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def split_tunnel(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::ClientVpnEndpoint.SplitTunnel``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-splittunnel
        '''
        result = self._values.get("split_tunnel")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def tag_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnClientVpnEndpoint.TagSpecificationProperty]]]]:
        '''``AWS::EC2::ClientVpnEndpoint.TagSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-tagspecifications
        '''
        result = self._values.get("tag_specifications")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnClientVpnEndpoint.TagSpecificationProperty]]]], result)

    @builtins.property
    def transport_protocol(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnEndpoint.TransportProtocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-transportprotocol
        '''
        result = self._values.get("transport_protocol")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vpc_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnEndpoint.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-vpcid
        '''
        result = self._values.get("vpc_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vpn_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::ClientVpnEndpoint.VpnPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnendpoint.html#cfn-ec2-clientvpnendpoint-vpnport
        '''
        result = self._values.get("vpn_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnClientVpnEndpointProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnClientVpnRoute(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnClientVpnRoute",
):
    '''A CloudFormation ``AWS::EC2::ClientVpnRoute``.

    :cloudformationResource: AWS::EC2::ClientVpnRoute
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnroute.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        client_vpn_endpoint_id: builtins.str,
        destination_cidr_block: builtins.str,
        target_vpc_subnet_id: builtins.str,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::ClientVpnRoute``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param client_vpn_endpoint_id: ``AWS::EC2::ClientVpnRoute.ClientVpnEndpointId``.
        :param destination_cidr_block: ``AWS::EC2::ClientVpnRoute.DestinationCidrBlock``.
        :param target_vpc_subnet_id: ``AWS::EC2::ClientVpnRoute.TargetVpcSubnetId``.
        :param description: ``AWS::EC2::ClientVpnRoute.Description``.
        '''
        props = CfnClientVpnRouteProps(
            client_vpn_endpoint_id=client_vpn_endpoint_id,
            destination_cidr_block=destination_cidr_block,
            target_vpc_subnet_id=target_vpc_subnet_id,
            description=description,
        )

        jsii.create(CfnClientVpnRoute, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clientVpnEndpointId")
    def client_vpn_endpoint_id(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnRoute.ClientVpnEndpointId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnroute.html#cfn-ec2-clientvpnroute-clientvpnendpointid
        '''
        return typing.cast(builtins.str, jsii.get(self, "clientVpnEndpointId"))

    @client_vpn_endpoint_id.setter
    def client_vpn_endpoint_id(self, value: builtins.str) -> None:
        jsii.set(self, "clientVpnEndpointId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationCidrBlock")
    def destination_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnRoute.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnroute.html#cfn-ec2-clientvpnroute-destinationcidrblock
        '''
        return typing.cast(builtins.str, jsii.get(self, "destinationCidrBlock"))

    @destination_cidr_block.setter
    def destination_cidr_block(self, value: builtins.str) -> None:
        jsii.set(self, "destinationCidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="targetVpcSubnetId")
    def target_vpc_subnet_id(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnRoute.TargetVpcSubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnroute.html#cfn-ec2-clientvpnroute-targetvpcsubnetid
        '''
        return typing.cast(builtins.str, jsii.get(self, "targetVpcSubnetId"))

    @target_vpc_subnet_id.setter
    def target_vpc_subnet_id(self, value: builtins.str) -> None:
        jsii.set(self, "targetVpcSubnetId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnRoute.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnroute.html#cfn-ec2-clientvpnroute-description
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "description"))

    @description.setter
    def description(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "description", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnClientVpnRouteProps",
    jsii_struct_bases=[],
    name_mapping={
        "client_vpn_endpoint_id": "clientVpnEndpointId",
        "destination_cidr_block": "destinationCidrBlock",
        "target_vpc_subnet_id": "targetVpcSubnetId",
        "description": "description",
    },
)
class CfnClientVpnRouteProps:
    def __init__(
        self,
        *,
        client_vpn_endpoint_id: builtins.str,
        destination_cidr_block: builtins.str,
        target_vpc_subnet_id: builtins.str,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::ClientVpnRoute``.

        :param client_vpn_endpoint_id: ``AWS::EC2::ClientVpnRoute.ClientVpnEndpointId``.
        :param destination_cidr_block: ``AWS::EC2::ClientVpnRoute.DestinationCidrBlock``.
        :param target_vpc_subnet_id: ``AWS::EC2::ClientVpnRoute.TargetVpcSubnetId``.
        :param description: ``AWS::EC2::ClientVpnRoute.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnroute.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "client_vpn_endpoint_id": client_vpn_endpoint_id,
            "destination_cidr_block": destination_cidr_block,
            "target_vpc_subnet_id": target_vpc_subnet_id,
        }
        if description is not None:
            self._values["description"] = description

    @builtins.property
    def client_vpn_endpoint_id(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnRoute.ClientVpnEndpointId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnroute.html#cfn-ec2-clientvpnroute-clientvpnendpointid
        '''
        result = self._values.get("client_vpn_endpoint_id")
        assert result is not None, "Required property 'client_vpn_endpoint_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def destination_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnRoute.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnroute.html#cfn-ec2-clientvpnroute-destinationcidrblock
        '''
        result = self._values.get("destination_cidr_block")
        assert result is not None, "Required property 'destination_cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def target_vpc_subnet_id(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnRoute.TargetVpcSubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnroute.html#cfn-ec2-clientvpnroute-targetvpcsubnetid
        '''
        result = self._values.get("target_vpc_subnet_id")
        assert result is not None, "Required property 'target_vpc_subnet_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::ClientVpnRoute.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpnroute.html#cfn-ec2-clientvpnroute-description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnClientVpnRouteProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnClientVpnTargetNetworkAssociation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnClientVpnTargetNetworkAssociation",
):
    '''A CloudFormation ``AWS::EC2::ClientVpnTargetNetworkAssociation``.

    :cloudformationResource: AWS::EC2::ClientVpnTargetNetworkAssociation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpntargetnetworkassociation.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        client_vpn_endpoint_id: builtins.str,
        subnet_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::ClientVpnTargetNetworkAssociation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param client_vpn_endpoint_id: ``AWS::EC2::ClientVpnTargetNetworkAssociation.ClientVpnEndpointId``.
        :param subnet_id: ``AWS::EC2::ClientVpnTargetNetworkAssociation.SubnetId``.
        '''
        props = CfnClientVpnTargetNetworkAssociationProps(
            client_vpn_endpoint_id=client_vpn_endpoint_id, subnet_id=subnet_id
        )

        jsii.create(CfnClientVpnTargetNetworkAssociation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="clientVpnEndpointId")
    def client_vpn_endpoint_id(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnTargetNetworkAssociation.ClientVpnEndpointId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpntargetnetworkassociation.html#cfn-ec2-clientvpntargetnetworkassociation-clientvpnendpointid
        '''
        return typing.cast(builtins.str, jsii.get(self, "clientVpnEndpointId"))

    @client_vpn_endpoint_id.setter
    def client_vpn_endpoint_id(self, value: builtins.str) -> None:
        jsii.set(self, "clientVpnEndpointId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetId")
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnTargetNetworkAssociation.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpntargetnetworkassociation.html#cfn-ec2-clientvpntargetnetworkassociation-subnetid
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetId"))

    @subnet_id.setter
    def subnet_id(self, value: builtins.str) -> None:
        jsii.set(self, "subnetId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnClientVpnTargetNetworkAssociationProps",
    jsii_struct_bases=[],
    name_mapping={
        "client_vpn_endpoint_id": "clientVpnEndpointId",
        "subnet_id": "subnetId",
    },
)
class CfnClientVpnTargetNetworkAssociationProps:
    def __init__(
        self,
        *,
        client_vpn_endpoint_id: builtins.str,
        subnet_id: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::ClientVpnTargetNetworkAssociation``.

        :param client_vpn_endpoint_id: ``AWS::EC2::ClientVpnTargetNetworkAssociation.ClientVpnEndpointId``.
        :param subnet_id: ``AWS::EC2::ClientVpnTargetNetworkAssociation.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpntargetnetworkassociation.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "client_vpn_endpoint_id": client_vpn_endpoint_id,
            "subnet_id": subnet_id,
        }

    @builtins.property
    def client_vpn_endpoint_id(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnTargetNetworkAssociation.ClientVpnEndpointId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpntargetnetworkassociation.html#cfn-ec2-clientvpntargetnetworkassociation-clientvpnendpointid
        '''
        result = self._values.get("client_vpn_endpoint_id")
        assert result is not None, "Required property 'client_vpn_endpoint_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::ClientVpnTargetNetworkAssociation.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-clientvpntargetnetworkassociation.html#cfn-ec2-clientvpntargetnetworkassociation-subnetid
        '''
        result = self._values.get("subnet_id")
        assert result is not None, "Required property 'subnet_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnClientVpnTargetNetworkAssociationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnCustomerGateway(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnCustomerGateway",
):
    '''A CloudFormation ``AWS::EC2::CustomerGateway``.

    :cloudformationResource: AWS::EC2::CustomerGateway
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-customer-gateway.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        bgp_asn: jsii.Number,
        ip_address: builtins.str,
        type: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::CustomerGateway``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param bgp_asn: ``AWS::EC2::CustomerGateway.BgpAsn``.
        :param ip_address: ``AWS::EC2::CustomerGateway.IpAddress``.
        :param type: ``AWS::EC2::CustomerGateway.Type``.
        :param tags: ``AWS::EC2::CustomerGateway.Tags``.
        '''
        props = CfnCustomerGatewayProps(
            bgp_asn=bgp_asn, ip_address=ip_address, type=type, tags=tags
        )

        jsii.create(CfnCustomerGateway, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::CustomerGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-customer-gateway.html#cfn-ec2-customergateway-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="bgpAsn")
    def bgp_asn(self) -> jsii.Number:
        '''``AWS::EC2::CustomerGateway.BgpAsn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-customer-gateway.html#cfn-ec2-customergateway-bgpasn
        '''
        return typing.cast(jsii.Number, jsii.get(self, "bgpAsn"))

    @bgp_asn.setter
    def bgp_asn(self, value: jsii.Number) -> None:
        jsii.set(self, "bgpAsn", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipAddress")
    def ip_address(self) -> builtins.str:
        '''``AWS::EC2::CustomerGateway.IpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-customer-gateway.html#cfn-ec2-customergateway-ipaddress
        '''
        return typing.cast(builtins.str, jsii.get(self, "ipAddress"))

    @ip_address.setter
    def ip_address(self, value: builtins.str) -> None:
        jsii.set(self, "ipAddress", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="type")
    def type(self) -> builtins.str:
        '''``AWS::EC2::CustomerGateway.Type``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-customer-gateway.html#cfn-ec2-customergateway-type
        '''
        return typing.cast(builtins.str, jsii.get(self, "type"))

    @type.setter
    def type(self, value: builtins.str) -> None:
        jsii.set(self, "type", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnCustomerGatewayProps",
    jsii_struct_bases=[],
    name_mapping={
        "bgp_asn": "bgpAsn",
        "ip_address": "ipAddress",
        "type": "type",
        "tags": "tags",
    },
)
class CfnCustomerGatewayProps:
    def __init__(
        self,
        *,
        bgp_asn: jsii.Number,
        ip_address: builtins.str,
        type: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::CustomerGateway``.

        :param bgp_asn: ``AWS::EC2::CustomerGateway.BgpAsn``.
        :param ip_address: ``AWS::EC2::CustomerGateway.IpAddress``.
        :param type: ``AWS::EC2::CustomerGateway.Type``.
        :param tags: ``AWS::EC2::CustomerGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-customer-gateway.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "bgp_asn": bgp_asn,
            "ip_address": ip_address,
            "type": type,
        }
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def bgp_asn(self) -> jsii.Number:
        '''``AWS::EC2::CustomerGateway.BgpAsn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-customer-gateway.html#cfn-ec2-customergateway-bgpasn
        '''
        result = self._values.get("bgp_asn")
        assert result is not None, "Required property 'bgp_asn' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def ip_address(self) -> builtins.str:
        '''``AWS::EC2::CustomerGateway.IpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-customer-gateway.html#cfn-ec2-customergateway-ipaddress
        '''
        result = self._values.get("ip_address")
        assert result is not None, "Required property 'ip_address' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def type(self) -> builtins.str:
        '''``AWS::EC2::CustomerGateway.Type``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-customer-gateway.html#cfn-ec2-customergateway-type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::CustomerGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-customer-gateway.html#cfn-ec2-customergateway-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnCustomerGatewayProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnDHCPOptions(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnDHCPOptions",
):
    '''A CloudFormation ``AWS::EC2::DHCPOptions``.

    :cloudformationResource: AWS::EC2::DHCPOptions
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        domain_name: typing.Optional[builtins.str] = None,
        domain_name_servers: typing.Optional[typing.List[builtins.str]] = None,
        netbios_name_servers: typing.Optional[typing.List[builtins.str]] = None,
        netbios_node_type: typing.Optional[jsii.Number] = None,
        ntp_servers: typing.Optional[typing.List[builtins.str]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::DHCPOptions``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param domain_name: ``AWS::EC2::DHCPOptions.DomainName``.
        :param domain_name_servers: ``AWS::EC2::DHCPOptions.DomainNameServers``.
        :param netbios_name_servers: ``AWS::EC2::DHCPOptions.NetbiosNameServers``.
        :param netbios_node_type: ``AWS::EC2::DHCPOptions.NetbiosNodeType``.
        :param ntp_servers: ``AWS::EC2::DHCPOptions.NtpServers``.
        :param tags: ``AWS::EC2::DHCPOptions.Tags``.
        '''
        props = CfnDHCPOptionsProps(
            domain_name=domain_name,
            domain_name_servers=domain_name_servers,
            netbios_name_servers=netbios_name_servers,
            netbios_node_type=netbios_node_type,
            ntp_servers=ntp_servers,
            tags=tags,
        )

        jsii.create(CfnDHCPOptions, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::DHCPOptions.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="domainName")
    def domain_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::DHCPOptions.DomainName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-domainname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "domainName"))

    @domain_name.setter
    def domain_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "domainName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="domainNameServers")
    def domain_name_servers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::DHCPOptions.DomainNameServers``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-domainnameservers
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "domainNameServers"))

    @domain_name_servers.setter
    def domain_name_servers(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "domainNameServers", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="netbiosNameServers")
    def netbios_name_servers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::DHCPOptions.NetbiosNameServers``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-netbiosnameservers
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "netbiosNameServers"))

    @netbios_name_servers.setter
    def netbios_name_servers(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "netbiosNameServers", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="netbiosNodeType")
    def netbios_node_type(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::DHCPOptions.NetbiosNodeType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-netbiosnodetype
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "netbiosNodeType"))

    @netbios_node_type.setter
    def netbios_node_type(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "netbiosNodeType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ntpServers")
    def ntp_servers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::DHCPOptions.NtpServers``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-ntpservers
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "ntpServers"))

    @ntp_servers.setter
    def ntp_servers(self, value: typing.Optional[typing.List[builtins.str]]) -> None:
        jsii.set(self, "ntpServers", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnDHCPOptionsProps",
    jsii_struct_bases=[],
    name_mapping={
        "domain_name": "domainName",
        "domain_name_servers": "domainNameServers",
        "netbios_name_servers": "netbiosNameServers",
        "netbios_node_type": "netbiosNodeType",
        "ntp_servers": "ntpServers",
        "tags": "tags",
    },
)
class CfnDHCPOptionsProps:
    def __init__(
        self,
        *,
        domain_name: typing.Optional[builtins.str] = None,
        domain_name_servers: typing.Optional[typing.List[builtins.str]] = None,
        netbios_name_servers: typing.Optional[typing.List[builtins.str]] = None,
        netbios_node_type: typing.Optional[jsii.Number] = None,
        ntp_servers: typing.Optional[typing.List[builtins.str]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::DHCPOptions``.

        :param domain_name: ``AWS::EC2::DHCPOptions.DomainName``.
        :param domain_name_servers: ``AWS::EC2::DHCPOptions.DomainNameServers``.
        :param netbios_name_servers: ``AWS::EC2::DHCPOptions.NetbiosNameServers``.
        :param netbios_node_type: ``AWS::EC2::DHCPOptions.NetbiosNodeType``.
        :param ntp_servers: ``AWS::EC2::DHCPOptions.NtpServers``.
        :param tags: ``AWS::EC2::DHCPOptions.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if domain_name is not None:
            self._values["domain_name"] = domain_name
        if domain_name_servers is not None:
            self._values["domain_name_servers"] = domain_name_servers
        if netbios_name_servers is not None:
            self._values["netbios_name_servers"] = netbios_name_servers
        if netbios_node_type is not None:
            self._values["netbios_node_type"] = netbios_node_type
        if ntp_servers is not None:
            self._values["ntp_servers"] = ntp_servers
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def domain_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::DHCPOptions.DomainName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-domainname
        '''
        result = self._values.get("domain_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def domain_name_servers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::DHCPOptions.DomainNameServers``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-domainnameservers
        '''
        result = self._values.get("domain_name_servers")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def netbios_name_servers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::DHCPOptions.NetbiosNameServers``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-netbiosnameservers
        '''
        result = self._values.get("netbios_name_servers")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def netbios_node_type(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::DHCPOptions.NetbiosNodeType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-netbiosnodetype
        '''
        result = self._values.get("netbios_node_type")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def ntp_servers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::DHCPOptions.NtpServers``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-ntpservers
        '''
        result = self._values.get("ntp_servers")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::DHCPOptions.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html#cfn-ec2-dhcpoptions-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnDHCPOptionsProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnEC2Fleet(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnEC2Fleet",
):
    '''A CloudFormation ``AWS::EC2::EC2Fleet``.

    :cloudformationResource: AWS::EC2::EC2Fleet
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        launch_template_configs: typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty"]]],
        target_capacity_specification: typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.TargetCapacitySpecificationRequestProperty"],
        excess_capacity_termination_policy: typing.Optional[builtins.str] = None,
        on_demand_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.OnDemandOptionsRequestProperty"]] = None,
        replace_unhealthy_instances: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        spot_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.SpotOptionsRequestProperty"]] = None,
        tag_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.TagSpecificationProperty"]]]] = None,
        terminate_instances_with_expiration: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        type: typing.Optional[builtins.str] = None,
        valid_from: typing.Optional[builtins.str] = None,
        valid_until: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::EC2Fleet``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param launch_template_configs: ``AWS::EC2::EC2Fleet.LaunchTemplateConfigs``.
        :param target_capacity_specification: ``AWS::EC2::EC2Fleet.TargetCapacitySpecification``.
        :param excess_capacity_termination_policy: ``AWS::EC2::EC2Fleet.ExcessCapacityTerminationPolicy``.
        :param on_demand_options: ``AWS::EC2::EC2Fleet.OnDemandOptions``.
        :param replace_unhealthy_instances: ``AWS::EC2::EC2Fleet.ReplaceUnhealthyInstances``.
        :param spot_options: ``AWS::EC2::EC2Fleet.SpotOptions``.
        :param tag_specifications: ``AWS::EC2::EC2Fleet.TagSpecifications``.
        :param terminate_instances_with_expiration: ``AWS::EC2::EC2Fleet.TerminateInstancesWithExpiration``.
        :param type: ``AWS::EC2::EC2Fleet.Type``.
        :param valid_from: ``AWS::EC2::EC2Fleet.ValidFrom``.
        :param valid_until: ``AWS::EC2::EC2Fleet.ValidUntil``.
        '''
        props = CfnEC2FleetProps(
            launch_template_configs=launch_template_configs,
            target_capacity_specification=target_capacity_specification,
            excess_capacity_termination_policy=excess_capacity_termination_policy,
            on_demand_options=on_demand_options,
            replace_unhealthy_instances=replace_unhealthy_instances,
            spot_options=spot_options,
            tag_specifications=tag_specifications,
            terminate_instances_with_expiration=terminate_instances_with_expiration,
            type=type,
            valid_from=valid_from,
            valid_until=valid_until,
        )

        jsii.create(CfnEC2Fleet, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="launchTemplateConfigs")
    def launch_template_configs(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty"]]]:
        '''``AWS::EC2::EC2Fleet.LaunchTemplateConfigs``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-launchtemplateconfigs
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty"]]], jsii.get(self, "launchTemplateConfigs"))

    @launch_template_configs.setter
    def launch_template_configs(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty"]]],
    ) -> None:
        jsii.set(self, "launchTemplateConfigs", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="targetCapacitySpecification")
    def target_capacity_specification(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.TargetCapacitySpecificationRequestProperty"]:
        '''``AWS::EC2::EC2Fleet.TargetCapacitySpecification``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-targetcapacityspecification
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.TargetCapacitySpecificationRequestProperty"], jsii.get(self, "targetCapacitySpecification"))

    @target_capacity_specification.setter
    def target_capacity_specification(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.TargetCapacitySpecificationRequestProperty"],
    ) -> None:
        jsii.set(self, "targetCapacitySpecification", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="excessCapacityTerminationPolicy")
    def excess_capacity_termination_policy(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EC2Fleet.ExcessCapacityTerminationPolicy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-excesscapacityterminationpolicy
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "excessCapacityTerminationPolicy"))

    @excess_capacity_termination_policy.setter
    def excess_capacity_termination_policy(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "excessCapacityTerminationPolicy", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="onDemandOptions")
    def on_demand_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.OnDemandOptionsRequestProperty"]]:
        '''``AWS::EC2::EC2Fleet.OnDemandOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-ondemandoptions
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.OnDemandOptionsRequestProperty"]], jsii.get(self, "onDemandOptions"))

    @on_demand_options.setter
    def on_demand_options(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.OnDemandOptionsRequestProperty"]],
    ) -> None:
        jsii.set(self, "onDemandOptions", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="replaceUnhealthyInstances")
    def replace_unhealthy_instances(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::EC2Fleet.ReplaceUnhealthyInstances``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-replaceunhealthyinstances
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "replaceUnhealthyInstances"))

    @replace_unhealthy_instances.setter
    def replace_unhealthy_instances(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "replaceUnhealthyInstances", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="spotOptions")
    def spot_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.SpotOptionsRequestProperty"]]:
        '''``AWS::EC2::EC2Fleet.SpotOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-spotoptions
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.SpotOptionsRequestProperty"]], jsii.get(self, "spotOptions"))

    @spot_options.setter
    def spot_options(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.SpotOptionsRequestProperty"]],
    ) -> None:
        jsii.set(self, "spotOptions", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tagSpecifications")
    def tag_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.TagSpecificationProperty"]]]]:
        '''``AWS::EC2::EC2Fleet.TagSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-tagspecifications
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.TagSpecificationProperty"]]]], jsii.get(self, "tagSpecifications"))

    @tag_specifications.setter
    def tag_specifications(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.TagSpecificationProperty"]]]],
    ) -> None:
        jsii.set(self, "tagSpecifications", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="terminateInstancesWithExpiration")
    def terminate_instances_with_expiration(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::EC2Fleet.TerminateInstancesWithExpiration``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-terminateinstanceswithexpiration
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "terminateInstancesWithExpiration"))

    @terminate_instances_with_expiration.setter
    def terminate_instances_with_expiration(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "terminateInstancesWithExpiration", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="type")
    def type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EC2Fleet.Type``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-type
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "type"))

    @type.setter
    def type(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "type", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="validFrom")
    def valid_from(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EC2Fleet.ValidFrom``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-validfrom
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "validFrom"))

    @valid_from.setter
    def valid_from(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "validFrom", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="validUntil")
    def valid_until(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EC2Fleet.ValidUntil``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-validuntil
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "validUntil"))

    @valid_until.setter
    def valid_until(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "validUntil", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnEC2Fleet.CapacityReservationOptionsRequestProperty",
        jsii_struct_bases=[],
        name_mapping={"usage_strategy": "usageStrategy"},
    )
    class CapacityReservationOptionsRequestProperty:
        def __init__(
            self,
            *,
            usage_strategy: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param usage_strategy: ``CfnEC2Fleet.CapacityReservationOptionsRequestProperty.UsageStrategy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityreservationoptionsrequest.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if usage_strategy is not None:
                self._values["usage_strategy"] = usage_strategy

        @builtins.property
        def usage_strategy(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.CapacityReservationOptionsRequestProperty.UsageStrategy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityreservationoptionsrequest.html#cfn-ec2-ec2fleet-capacityreservationoptionsrequest-usagestrategy
            '''
            result = self._values.get("usage_strategy")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CapacityReservationOptionsRequestProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty",
        jsii_struct_bases=[],
        name_mapping={
            "launch_template_specification": "launchTemplateSpecification",
            "overrides": "overrides",
        },
    )
    class FleetLaunchTemplateConfigRequestProperty:
        def __init__(
            self,
            *,
            launch_template_specification: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.FleetLaunchTemplateSpecificationRequestProperty"]] = None,
            overrides: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty"]]]] = None,
        ) -> None:
            '''
            :param launch_template_specification: ``CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty.LaunchTemplateSpecification``.
            :param overrides: ``CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty.Overrides``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateconfigrequest.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if launch_template_specification is not None:
                self._values["launch_template_specification"] = launch_template_specification
            if overrides is not None:
                self._values["overrides"] = overrides

        @builtins.property
        def launch_template_specification(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.FleetLaunchTemplateSpecificationRequestProperty"]]:
            '''``CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty.LaunchTemplateSpecification``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateconfigrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateconfigrequest-launchtemplatespecification
            '''
            result = self._values.get("launch_template_specification")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.FleetLaunchTemplateSpecificationRequestProperty"]], result)

        @builtins.property
        def overrides(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty"]]]]:
            '''``CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty.Overrides``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateconfigrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateconfigrequest-overrides
            '''
            result = self._values.get("overrides")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty"]]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "FleetLaunchTemplateConfigRequestProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty",
        jsii_struct_bases=[],
        name_mapping={
            "availability_zone": "availabilityZone",
            "instance_type": "instanceType",
            "max_price": "maxPrice",
            "placement": "placement",
            "priority": "priority",
            "subnet_id": "subnetId",
            "weighted_capacity": "weightedCapacity",
        },
    )
    class FleetLaunchTemplateOverridesRequestProperty:
        def __init__(
            self,
            *,
            availability_zone: typing.Optional[builtins.str] = None,
            instance_type: typing.Optional[builtins.str] = None,
            max_price: typing.Optional[builtins.str] = None,
            placement: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.PlacementProperty"]] = None,
            priority: typing.Optional[jsii.Number] = None,
            subnet_id: typing.Optional[builtins.str] = None,
            weighted_capacity: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param availability_zone: ``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.AvailabilityZone``.
            :param instance_type: ``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.InstanceType``.
            :param max_price: ``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.MaxPrice``.
            :param placement: ``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.Placement``.
            :param priority: ``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.Priority``.
            :param subnet_id: ``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.SubnetId``.
            :param weighted_capacity: ``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.WeightedCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if availability_zone is not None:
                self._values["availability_zone"] = availability_zone
            if instance_type is not None:
                self._values["instance_type"] = instance_type
            if max_price is not None:
                self._values["max_price"] = max_price
            if placement is not None:
                self._values["placement"] = placement
            if priority is not None:
                self._values["priority"] = priority
            if subnet_id is not None:
                self._values["subnet_id"] = subnet_id
            if weighted_capacity is not None:
                self._values["weighted_capacity"] = weighted_capacity

        @builtins.property
        def availability_zone(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.AvailabilityZone``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest-availabilityzone
            '''
            result = self._values.get("availability_zone")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def instance_type(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.InstanceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest-instancetype
            '''
            result = self._values.get("instance_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def max_price(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.MaxPrice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest-maxprice
            '''
            result = self._values.get("max_price")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def placement(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.PlacementProperty"]]:
            '''``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.Placement``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest-placement
            '''
            result = self._values.get("placement")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.PlacementProperty"]], result)

        @builtins.property
        def priority(self) -> typing.Optional[jsii.Number]:
            '''``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.Priority``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest-priority
            '''
            result = self._values.get("priority")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def subnet_id(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.SubnetId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest-subnetid
            '''
            result = self._values.get("subnet_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def weighted_capacity(self) -> typing.Optional[jsii.Number]:
            '''``CfnEC2Fleet.FleetLaunchTemplateOverridesRequestProperty.WeightedCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest-weightedcapacity
            '''
            result = self._values.get("weighted_capacity")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "FleetLaunchTemplateOverridesRequestProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnEC2Fleet.FleetLaunchTemplateSpecificationRequestProperty",
        jsii_struct_bases=[],
        name_mapping={
            "launch_template_id": "launchTemplateId",
            "launch_template_name": "launchTemplateName",
            "version": "version",
        },
    )
    class FleetLaunchTemplateSpecificationRequestProperty:
        def __init__(
            self,
            *,
            launch_template_id: typing.Optional[builtins.str] = None,
            launch_template_name: typing.Optional[builtins.str] = None,
            version: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param launch_template_id: ``CfnEC2Fleet.FleetLaunchTemplateSpecificationRequestProperty.LaunchTemplateId``.
            :param launch_template_name: ``CfnEC2Fleet.FleetLaunchTemplateSpecificationRequestProperty.LaunchTemplateName``.
            :param version: ``CfnEC2Fleet.FleetLaunchTemplateSpecificationRequestProperty.Version``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplatespecificationrequest.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if launch_template_id is not None:
                self._values["launch_template_id"] = launch_template_id
            if launch_template_name is not None:
                self._values["launch_template_name"] = launch_template_name
            if version is not None:
                self._values["version"] = version

        @builtins.property
        def launch_template_id(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.FleetLaunchTemplateSpecificationRequestProperty.LaunchTemplateId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplatespecificationrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplatespecificationrequest-launchtemplateid
            '''
            result = self._values.get("launch_template_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def launch_template_name(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.FleetLaunchTemplateSpecificationRequestProperty.LaunchTemplateName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplatespecificationrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplatespecificationrequest-launchtemplatename
            '''
            result = self._values.get("launch_template_name")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def version(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.FleetLaunchTemplateSpecificationRequestProperty.Version``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplatespecificationrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplatespecificationrequest-version
            '''
            result = self._values.get("version")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "FleetLaunchTemplateSpecificationRequestProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnEC2Fleet.OnDemandOptionsRequestProperty",
        jsii_struct_bases=[],
        name_mapping={
            "allocation_strategy": "allocationStrategy",
            "capacity_reservation_options": "capacityReservationOptions",
            "max_total_price": "maxTotalPrice",
            "min_target_capacity": "minTargetCapacity",
            "single_availability_zone": "singleAvailabilityZone",
            "single_instance_type": "singleInstanceType",
        },
    )
    class OnDemandOptionsRequestProperty:
        def __init__(
            self,
            *,
            allocation_strategy: typing.Optional[builtins.str] = None,
            capacity_reservation_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.CapacityReservationOptionsRequestProperty"]] = None,
            max_total_price: typing.Optional[builtins.str] = None,
            min_target_capacity: typing.Optional[jsii.Number] = None,
            single_availability_zone: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            single_instance_type: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ) -> None:
            '''
            :param allocation_strategy: ``CfnEC2Fleet.OnDemandOptionsRequestProperty.AllocationStrategy``.
            :param capacity_reservation_options: ``CfnEC2Fleet.OnDemandOptionsRequestProperty.CapacityReservationOptions``.
            :param max_total_price: ``CfnEC2Fleet.OnDemandOptionsRequestProperty.MaxTotalPrice``.
            :param min_target_capacity: ``CfnEC2Fleet.OnDemandOptionsRequestProperty.MinTargetCapacity``.
            :param single_availability_zone: ``CfnEC2Fleet.OnDemandOptionsRequestProperty.SingleAvailabilityZone``.
            :param single_instance_type: ``CfnEC2Fleet.OnDemandOptionsRequestProperty.SingleInstanceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-ondemandoptionsrequest.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if allocation_strategy is not None:
                self._values["allocation_strategy"] = allocation_strategy
            if capacity_reservation_options is not None:
                self._values["capacity_reservation_options"] = capacity_reservation_options
            if max_total_price is not None:
                self._values["max_total_price"] = max_total_price
            if min_target_capacity is not None:
                self._values["min_target_capacity"] = min_target_capacity
            if single_availability_zone is not None:
                self._values["single_availability_zone"] = single_availability_zone
            if single_instance_type is not None:
                self._values["single_instance_type"] = single_instance_type

        @builtins.property
        def allocation_strategy(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.OnDemandOptionsRequestProperty.AllocationStrategy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-ondemandoptionsrequest.html#cfn-ec2-ec2fleet-ondemandoptionsrequest-allocationstrategy
            '''
            result = self._values.get("allocation_strategy")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def capacity_reservation_options(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.CapacityReservationOptionsRequestProperty"]]:
            '''``CfnEC2Fleet.OnDemandOptionsRequestProperty.CapacityReservationOptions``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-ondemandoptionsrequest.html#cfn-ec2-ec2fleet-ondemandoptionsrequest-capacityreservationoptions
            '''
            result = self._values.get("capacity_reservation_options")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnEC2Fleet.CapacityReservationOptionsRequestProperty"]], result)

        @builtins.property
        def max_total_price(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.OnDemandOptionsRequestProperty.MaxTotalPrice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-ondemandoptionsrequest.html#cfn-ec2-ec2fleet-ondemandoptionsrequest-maxtotalprice
            '''
            result = self._values.get("max_total_price")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def min_target_capacity(self) -> typing.Optional[jsii.Number]:
            '''``CfnEC2Fleet.OnDemandOptionsRequestProperty.MinTargetCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-ondemandoptionsrequest.html#cfn-ec2-ec2fleet-ondemandoptionsrequest-mintargetcapacity
            '''
            result = self._values.get("min_target_capacity")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def single_availability_zone(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnEC2Fleet.OnDemandOptionsRequestProperty.SingleAvailabilityZone``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-ondemandoptionsrequest.html#cfn-ec2-ec2fleet-ondemandoptionsrequest-singleavailabilityzone
            '''
            result = self._values.get("single_availability_zone")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def single_instance_type(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnEC2Fleet.OnDemandOptionsRequestProperty.SingleInstanceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-ondemandoptionsrequest.html#cfn-ec2-ec2fleet-ondemandoptionsrequest-singleinstancetype
            '''
            result = self._values.get("single_instance_type")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "OnDemandOptionsRequestProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnEC2Fleet.PlacementProperty",
        jsii_struct_bases=[],
        name_mapping={
            "affinity": "affinity",
            "availability_zone": "availabilityZone",
            "group_name": "groupName",
            "host_id": "hostId",
            "host_resource_group_arn": "hostResourceGroupArn",
            "partition_number": "partitionNumber",
            "spread_domain": "spreadDomain",
            "tenancy": "tenancy",
        },
    )
    class PlacementProperty:
        def __init__(
            self,
            *,
            affinity: typing.Optional[builtins.str] = None,
            availability_zone: typing.Optional[builtins.str] = None,
            group_name: typing.Optional[builtins.str] = None,
            host_id: typing.Optional[builtins.str] = None,
            host_resource_group_arn: typing.Optional[builtins.str] = None,
            partition_number: typing.Optional[jsii.Number] = None,
            spread_domain: typing.Optional[builtins.str] = None,
            tenancy: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param affinity: ``CfnEC2Fleet.PlacementProperty.Affinity``.
            :param availability_zone: ``CfnEC2Fleet.PlacementProperty.AvailabilityZone``.
            :param group_name: ``CfnEC2Fleet.PlacementProperty.GroupName``.
            :param host_id: ``CfnEC2Fleet.PlacementProperty.HostId``.
            :param host_resource_group_arn: ``CfnEC2Fleet.PlacementProperty.HostResourceGroupArn``.
            :param partition_number: ``CfnEC2Fleet.PlacementProperty.PartitionNumber``.
            :param spread_domain: ``CfnEC2Fleet.PlacementProperty.SpreadDomain``.
            :param tenancy: ``CfnEC2Fleet.PlacementProperty.Tenancy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-placement.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if affinity is not None:
                self._values["affinity"] = affinity
            if availability_zone is not None:
                self._values["availability_zone"] = availability_zone
            if group_name is not None:
                self._values["group_name"] = group_name
            if host_id is not None:
                self._values["host_id"] = host_id
            if host_resource_group_arn is not None:
                self._values["host_resource_group_arn"] = host_resource_group_arn
            if partition_number is not None:
                self._values["partition_number"] = partition_number
            if spread_domain is not None:
                self._values["spread_domain"] = spread_domain
            if tenancy is not None:
                self._values["tenancy"] = tenancy

        @builtins.property
        def affinity(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.PlacementProperty.Affinity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-placement.html#cfn-ec2-ec2fleet-placement-affinity
            '''
            result = self._values.get("affinity")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def availability_zone(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.PlacementProperty.AvailabilityZone``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-placement.html#cfn-ec2-ec2fleet-placement-availabilityzone
            '''
            result = self._values.get("availability_zone")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def group_name(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.PlacementProperty.GroupName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-placement.html#cfn-ec2-ec2fleet-placement-groupname
            '''
            result = self._values.get("group_name")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def host_id(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.PlacementProperty.HostId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-placement.html#cfn-ec2-ec2fleet-placement-hostid
            '''
            result = self._values.get("host_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def host_resource_group_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.PlacementProperty.HostResourceGroupArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-placement.html#cfn-ec2-ec2fleet-placement-hostresourcegrouparn
            '''
            result = self._values.get("host_resource_group_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def partition_number(self) -> typing.Optional[jsii.Number]:
            '''``CfnEC2Fleet.PlacementProperty.PartitionNumber``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-placement.html#cfn-ec2-ec2fleet-placement-partitionnumber
            '''
            result = self._values.get("partition_number")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def spread_domain(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.PlacementProperty.SpreadDomain``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-placement.html#cfn-ec2-ec2fleet-placement-spreaddomain
            '''
            result = self._values.get("spread_domain")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def tenancy(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.PlacementProperty.Tenancy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-placement.html#cfn-ec2-ec2fleet-placement-tenancy
            '''
            result = self._values.get("tenancy")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PlacementProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnEC2Fleet.SpotOptionsRequestProperty",
        jsii_struct_bases=[],
        name_mapping={
            "allocation_strategy": "allocationStrategy",
            "instance_interruption_behavior": "instanceInterruptionBehavior",
            "instance_pools_to_use_count": "instancePoolsToUseCount",
            "max_total_price": "maxTotalPrice",
            "min_target_capacity": "minTargetCapacity",
            "single_availability_zone": "singleAvailabilityZone",
            "single_instance_type": "singleInstanceType",
        },
    )
    class SpotOptionsRequestProperty:
        def __init__(
            self,
            *,
            allocation_strategy: typing.Optional[builtins.str] = None,
            instance_interruption_behavior: typing.Optional[builtins.str] = None,
            instance_pools_to_use_count: typing.Optional[jsii.Number] = None,
            max_total_price: typing.Optional[builtins.str] = None,
            min_target_capacity: typing.Optional[jsii.Number] = None,
            single_availability_zone: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            single_instance_type: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ) -> None:
            '''
            :param allocation_strategy: ``CfnEC2Fleet.SpotOptionsRequestProperty.AllocationStrategy``.
            :param instance_interruption_behavior: ``CfnEC2Fleet.SpotOptionsRequestProperty.InstanceInterruptionBehavior``.
            :param instance_pools_to_use_count: ``CfnEC2Fleet.SpotOptionsRequestProperty.InstancePoolsToUseCount``.
            :param max_total_price: ``CfnEC2Fleet.SpotOptionsRequestProperty.MaxTotalPrice``.
            :param min_target_capacity: ``CfnEC2Fleet.SpotOptionsRequestProperty.MinTargetCapacity``.
            :param single_availability_zone: ``CfnEC2Fleet.SpotOptionsRequestProperty.SingleAvailabilityZone``.
            :param single_instance_type: ``CfnEC2Fleet.SpotOptionsRequestProperty.SingleInstanceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if allocation_strategy is not None:
                self._values["allocation_strategy"] = allocation_strategy
            if instance_interruption_behavior is not None:
                self._values["instance_interruption_behavior"] = instance_interruption_behavior
            if instance_pools_to_use_count is not None:
                self._values["instance_pools_to_use_count"] = instance_pools_to_use_count
            if max_total_price is not None:
                self._values["max_total_price"] = max_total_price
            if min_target_capacity is not None:
                self._values["min_target_capacity"] = min_target_capacity
            if single_availability_zone is not None:
                self._values["single_availability_zone"] = single_availability_zone
            if single_instance_type is not None:
                self._values["single_instance_type"] = single_instance_type

        @builtins.property
        def allocation_strategy(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.SpotOptionsRequestProperty.AllocationStrategy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-allocationstrategy
            '''
            result = self._values.get("allocation_strategy")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def instance_interruption_behavior(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.SpotOptionsRequestProperty.InstanceInterruptionBehavior``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-instanceinterruptionbehavior
            '''
            result = self._values.get("instance_interruption_behavior")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def instance_pools_to_use_count(self) -> typing.Optional[jsii.Number]:
            '''``CfnEC2Fleet.SpotOptionsRequestProperty.InstancePoolsToUseCount``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-instancepoolstousecount
            '''
            result = self._values.get("instance_pools_to_use_count")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def max_total_price(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.SpotOptionsRequestProperty.MaxTotalPrice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-maxtotalprice
            '''
            result = self._values.get("max_total_price")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def min_target_capacity(self) -> typing.Optional[jsii.Number]:
            '''``CfnEC2Fleet.SpotOptionsRequestProperty.MinTargetCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-mintargetcapacity
            '''
            result = self._values.get("min_target_capacity")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def single_availability_zone(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnEC2Fleet.SpotOptionsRequestProperty.SingleAvailabilityZone``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-singleavailabilityzone
            '''
            result = self._values.get("single_availability_zone")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def single_instance_type(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnEC2Fleet.SpotOptionsRequestProperty.SingleInstanceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-singleinstancetype
            '''
            result = self._values.get("single_instance_type")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SpotOptionsRequestProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnEC2Fleet.TagSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"resource_type": "resourceType", "tags": "tags"},
    )
    class TagSpecificationProperty:
        def __init__(
            self,
            *,
            resource_type: typing.Optional[builtins.str] = None,
            tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        ) -> None:
            '''
            :param resource_type: ``CfnEC2Fleet.TagSpecificationProperty.ResourceType``.
            :param tags: ``CfnEC2Fleet.TagSpecificationProperty.Tags``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-tagspecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if resource_type is not None:
                self._values["resource_type"] = resource_type
            if tags is not None:
                self._values["tags"] = tags

        @builtins.property
        def resource_type(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.TagSpecificationProperty.ResourceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-tagspecification.html#cfn-ec2-ec2fleet-tagspecification-resourcetype
            '''
            result = self._values.get("resource_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
            '''``CfnEC2Fleet.TagSpecificationProperty.Tags``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-tagspecification.html#cfn-ec2-ec2fleet-tagspecification-tags
            '''
            result = self._values.get("tags")
            return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TagSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnEC2Fleet.TargetCapacitySpecificationRequestProperty",
        jsii_struct_bases=[],
        name_mapping={
            "total_target_capacity": "totalTargetCapacity",
            "default_target_capacity_type": "defaultTargetCapacityType",
            "on_demand_target_capacity": "onDemandTargetCapacity",
            "spot_target_capacity": "spotTargetCapacity",
        },
    )
    class TargetCapacitySpecificationRequestProperty:
        def __init__(
            self,
            *,
            total_target_capacity: jsii.Number,
            default_target_capacity_type: typing.Optional[builtins.str] = None,
            on_demand_target_capacity: typing.Optional[jsii.Number] = None,
            spot_target_capacity: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param total_target_capacity: ``CfnEC2Fleet.TargetCapacitySpecificationRequestProperty.TotalTargetCapacity``.
            :param default_target_capacity_type: ``CfnEC2Fleet.TargetCapacitySpecificationRequestProperty.DefaultTargetCapacityType``.
            :param on_demand_target_capacity: ``CfnEC2Fleet.TargetCapacitySpecificationRequestProperty.OnDemandTargetCapacity``.
            :param spot_target_capacity: ``CfnEC2Fleet.TargetCapacitySpecificationRequestProperty.SpotTargetCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-targetcapacityspecificationrequest.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "total_target_capacity": total_target_capacity,
            }
            if default_target_capacity_type is not None:
                self._values["default_target_capacity_type"] = default_target_capacity_type
            if on_demand_target_capacity is not None:
                self._values["on_demand_target_capacity"] = on_demand_target_capacity
            if spot_target_capacity is not None:
                self._values["spot_target_capacity"] = spot_target_capacity

        @builtins.property
        def total_target_capacity(self) -> jsii.Number:
            '''``CfnEC2Fleet.TargetCapacitySpecificationRequestProperty.TotalTargetCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-targetcapacityspecificationrequest.html#cfn-ec2-ec2fleet-targetcapacityspecificationrequest-totaltargetcapacity
            '''
            result = self._values.get("total_target_capacity")
            assert result is not None, "Required property 'total_target_capacity' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def default_target_capacity_type(self) -> typing.Optional[builtins.str]:
            '''``CfnEC2Fleet.TargetCapacitySpecificationRequestProperty.DefaultTargetCapacityType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-targetcapacityspecificationrequest.html#cfn-ec2-ec2fleet-targetcapacityspecificationrequest-defaulttargetcapacitytype
            '''
            result = self._values.get("default_target_capacity_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def on_demand_target_capacity(self) -> typing.Optional[jsii.Number]:
            '''``CfnEC2Fleet.TargetCapacitySpecificationRequestProperty.OnDemandTargetCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-targetcapacityspecificationrequest.html#cfn-ec2-ec2fleet-targetcapacityspecificationrequest-ondemandtargetcapacity
            '''
            result = self._values.get("on_demand_target_capacity")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def spot_target_capacity(self) -> typing.Optional[jsii.Number]:
            '''``CfnEC2Fleet.TargetCapacitySpecificationRequestProperty.SpotTargetCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-targetcapacityspecificationrequest.html#cfn-ec2-ec2fleet-targetcapacityspecificationrequest-spottargetcapacity
            '''
            result = self._values.get("spot_target_capacity")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TargetCapacitySpecificationRequestProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnEC2FleetProps",
    jsii_struct_bases=[],
    name_mapping={
        "launch_template_configs": "launchTemplateConfigs",
        "target_capacity_specification": "targetCapacitySpecification",
        "excess_capacity_termination_policy": "excessCapacityTerminationPolicy",
        "on_demand_options": "onDemandOptions",
        "replace_unhealthy_instances": "replaceUnhealthyInstances",
        "spot_options": "spotOptions",
        "tag_specifications": "tagSpecifications",
        "terminate_instances_with_expiration": "terminateInstancesWithExpiration",
        "type": "type",
        "valid_from": "validFrom",
        "valid_until": "validUntil",
    },
)
class CfnEC2FleetProps:
    def __init__(
        self,
        *,
        launch_template_configs: typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty]]],
        target_capacity_specification: typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.TargetCapacitySpecificationRequestProperty],
        excess_capacity_termination_policy: typing.Optional[builtins.str] = None,
        on_demand_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.OnDemandOptionsRequestProperty]] = None,
        replace_unhealthy_instances: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        spot_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.SpotOptionsRequestProperty]] = None,
        tag_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.TagSpecificationProperty]]]] = None,
        terminate_instances_with_expiration: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        type: typing.Optional[builtins.str] = None,
        valid_from: typing.Optional[builtins.str] = None,
        valid_until: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::EC2Fleet``.

        :param launch_template_configs: ``AWS::EC2::EC2Fleet.LaunchTemplateConfigs``.
        :param target_capacity_specification: ``AWS::EC2::EC2Fleet.TargetCapacitySpecification``.
        :param excess_capacity_termination_policy: ``AWS::EC2::EC2Fleet.ExcessCapacityTerminationPolicy``.
        :param on_demand_options: ``AWS::EC2::EC2Fleet.OnDemandOptions``.
        :param replace_unhealthy_instances: ``AWS::EC2::EC2Fleet.ReplaceUnhealthyInstances``.
        :param spot_options: ``AWS::EC2::EC2Fleet.SpotOptions``.
        :param tag_specifications: ``AWS::EC2::EC2Fleet.TagSpecifications``.
        :param terminate_instances_with_expiration: ``AWS::EC2::EC2Fleet.TerminateInstancesWithExpiration``.
        :param type: ``AWS::EC2::EC2Fleet.Type``.
        :param valid_from: ``AWS::EC2::EC2Fleet.ValidFrom``.
        :param valid_until: ``AWS::EC2::EC2Fleet.ValidUntil``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "launch_template_configs": launch_template_configs,
            "target_capacity_specification": target_capacity_specification,
        }
        if excess_capacity_termination_policy is not None:
            self._values["excess_capacity_termination_policy"] = excess_capacity_termination_policy
        if on_demand_options is not None:
            self._values["on_demand_options"] = on_demand_options
        if replace_unhealthy_instances is not None:
            self._values["replace_unhealthy_instances"] = replace_unhealthy_instances
        if spot_options is not None:
            self._values["spot_options"] = spot_options
        if tag_specifications is not None:
            self._values["tag_specifications"] = tag_specifications
        if terminate_instances_with_expiration is not None:
            self._values["terminate_instances_with_expiration"] = terminate_instances_with_expiration
        if type is not None:
            self._values["type"] = type
        if valid_from is not None:
            self._values["valid_from"] = valid_from
        if valid_until is not None:
            self._values["valid_until"] = valid_until

    @builtins.property
    def launch_template_configs(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty]]]:
        '''``AWS::EC2::EC2Fleet.LaunchTemplateConfigs``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-launchtemplateconfigs
        '''
        result = self._values.get("launch_template_configs")
        assert result is not None, "Required property 'launch_template_configs' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.FleetLaunchTemplateConfigRequestProperty]]], result)

    @builtins.property
    def target_capacity_specification(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.TargetCapacitySpecificationRequestProperty]:
        '''``AWS::EC2::EC2Fleet.TargetCapacitySpecification``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-targetcapacityspecification
        '''
        result = self._values.get("target_capacity_specification")
        assert result is not None, "Required property 'target_capacity_specification' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.TargetCapacitySpecificationRequestProperty], result)

    @builtins.property
    def excess_capacity_termination_policy(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EC2Fleet.ExcessCapacityTerminationPolicy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-excesscapacityterminationpolicy
        '''
        result = self._values.get("excess_capacity_termination_policy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def on_demand_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.OnDemandOptionsRequestProperty]]:
        '''``AWS::EC2::EC2Fleet.OnDemandOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-ondemandoptions
        '''
        result = self._values.get("on_demand_options")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.OnDemandOptionsRequestProperty]], result)

    @builtins.property
    def replace_unhealthy_instances(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::EC2Fleet.ReplaceUnhealthyInstances``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-replaceunhealthyinstances
        '''
        result = self._values.get("replace_unhealthy_instances")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def spot_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.SpotOptionsRequestProperty]]:
        '''``AWS::EC2::EC2Fleet.SpotOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-spotoptions
        '''
        result = self._values.get("spot_options")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.SpotOptionsRequestProperty]], result)

    @builtins.property
    def tag_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.TagSpecificationProperty]]]]:
        '''``AWS::EC2::EC2Fleet.TagSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-tagspecifications
        '''
        result = self._values.get("tag_specifications")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnEC2Fleet.TagSpecificationProperty]]]], result)

    @builtins.property
    def terminate_instances_with_expiration(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::EC2Fleet.TerminateInstancesWithExpiration``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-terminateinstanceswithexpiration
        '''
        result = self._values.get("terminate_instances_with_expiration")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EC2Fleet.Type``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-type
        '''
        result = self._values.get("type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def valid_from(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EC2Fleet.ValidFrom``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-validfrom
        '''
        result = self._values.get("valid_from")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def valid_until(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EC2Fleet.ValidUntil``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ec2fleet.html#cfn-ec2-ec2fleet-validuntil
        '''
        result = self._values.get("valid_until")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnEC2FleetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnEIP(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnEIP",
):
    '''A CloudFormation ``AWS::EC2::EIP``.

    :cloudformationResource: AWS::EC2::EIP
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        domain: typing.Optional[builtins.str] = None,
        instance_id: typing.Optional[builtins.str] = None,
        public_ipv4_pool: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::EIP``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param domain: ``AWS::EC2::EIP.Domain``.
        :param instance_id: ``AWS::EC2::EIP.InstanceId``.
        :param public_ipv4_pool: ``AWS::EC2::EIP.PublicIpv4Pool``.
        :param tags: ``AWS::EC2::EIP.Tags``.
        '''
        props = CfnEIPProps(
            domain=domain,
            instance_id=instance_id,
            public_ipv4_pool=public_ipv4_pool,
            tags=tags,
        )

        jsii.create(CfnEIP, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAllocationId")
    def attr_allocation_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: AllocationId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrAllocationId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::EIP.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html#cfn-ec2-eip-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="domain")
    def domain(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIP.Domain``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html#cfn-ec2-eip-domain
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "domain"))

    @domain.setter
    def domain(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "domain", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceId")
    def instance_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIP.InstanceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html#cfn-ec2-eip-instanceid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "instanceId"))

    @instance_id.setter
    def instance_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "instanceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="publicIpv4Pool")
    def public_ipv4_pool(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIP.PublicIpv4Pool``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html#cfn-ec2-eip-publicipv4pool
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "publicIpv4Pool"))

    @public_ipv4_pool.setter
    def public_ipv4_pool(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "publicIpv4Pool", value)


@jsii.implements(aws_cdk.core.IInspectable)
class CfnEIPAssociation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnEIPAssociation",
):
    '''A CloudFormation ``AWS::EC2::EIPAssociation``.

    :cloudformationResource: AWS::EC2::EIPAssociation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        allocation_id: typing.Optional[builtins.str] = None,
        eip: typing.Optional[builtins.str] = None,
        instance_id: typing.Optional[builtins.str] = None,
        network_interface_id: typing.Optional[builtins.str] = None,
        private_ip_address: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::EIPAssociation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param allocation_id: ``AWS::EC2::EIPAssociation.AllocationId``.
        :param eip: ``AWS::EC2::EIPAssociation.EIP``.
        :param instance_id: ``AWS::EC2::EIPAssociation.InstanceId``.
        :param network_interface_id: ``AWS::EC2::EIPAssociation.NetworkInterfaceId``.
        :param private_ip_address: ``AWS::EC2::EIPAssociation.PrivateIpAddress``.
        '''
        props = CfnEIPAssociationProps(
            allocation_id=allocation_id,
            eip=eip,
            instance_id=instance_id,
            network_interface_id=network_interface_id,
            private_ip_address=private_ip_address,
        )

        jsii.create(CfnEIPAssociation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="allocationId")
    def allocation_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIPAssociation.AllocationId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html#cfn-ec2-eipassociation-allocationid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "allocationId"))

    @allocation_id.setter
    def allocation_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "allocationId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="eip")
    def eip(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIPAssociation.EIP``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html#cfn-ec2-eipassociation-eip
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "eip"))

    @eip.setter
    def eip(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "eip", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceId")
    def instance_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIPAssociation.InstanceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html#cfn-ec2-eipassociation-instanceid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "instanceId"))

    @instance_id.setter
    def instance_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "instanceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkInterfaceId")
    def network_interface_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIPAssociation.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html#cfn-ec2-eipassociation-networkinterfaceid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "networkInterfaceId"))

    @network_interface_id.setter
    def network_interface_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "networkInterfaceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateIpAddress")
    def private_ip_address(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIPAssociation.PrivateIpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html#cfn-ec2-eipassociation-PrivateIpAddress
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "privateIpAddress"))

    @private_ip_address.setter
    def private_ip_address(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "privateIpAddress", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnEIPAssociationProps",
    jsii_struct_bases=[],
    name_mapping={
        "allocation_id": "allocationId",
        "eip": "eip",
        "instance_id": "instanceId",
        "network_interface_id": "networkInterfaceId",
        "private_ip_address": "privateIpAddress",
    },
)
class CfnEIPAssociationProps:
    def __init__(
        self,
        *,
        allocation_id: typing.Optional[builtins.str] = None,
        eip: typing.Optional[builtins.str] = None,
        instance_id: typing.Optional[builtins.str] = None,
        network_interface_id: typing.Optional[builtins.str] = None,
        private_ip_address: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::EIPAssociation``.

        :param allocation_id: ``AWS::EC2::EIPAssociation.AllocationId``.
        :param eip: ``AWS::EC2::EIPAssociation.EIP``.
        :param instance_id: ``AWS::EC2::EIPAssociation.InstanceId``.
        :param network_interface_id: ``AWS::EC2::EIPAssociation.NetworkInterfaceId``.
        :param private_ip_address: ``AWS::EC2::EIPAssociation.PrivateIpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if allocation_id is not None:
            self._values["allocation_id"] = allocation_id
        if eip is not None:
            self._values["eip"] = eip
        if instance_id is not None:
            self._values["instance_id"] = instance_id
        if network_interface_id is not None:
            self._values["network_interface_id"] = network_interface_id
        if private_ip_address is not None:
            self._values["private_ip_address"] = private_ip_address

    @builtins.property
    def allocation_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIPAssociation.AllocationId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html#cfn-ec2-eipassociation-allocationid
        '''
        result = self._values.get("allocation_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def eip(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIPAssociation.EIP``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html#cfn-ec2-eipassociation-eip
        '''
        result = self._values.get("eip")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def instance_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIPAssociation.InstanceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html#cfn-ec2-eipassociation-instanceid
        '''
        result = self._values.get("instance_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def network_interface_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIPAssociation.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html#cfn-ec2-eipassociation-networkinterfaceid
        '''
        result = self._values.get("network_interface_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def private_ip_address(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIPAssociation.PrivateIpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip-association.html#cfn-ec2-eipassociation-PrivateIpAddress
        '''
        result = self._values.get("private_ip_address")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnEIPAssociationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnEIPProps",
    jsii_struct_bases=[],
    name_mapping={
        "domain": "domain",
        "instance_id": "instanceId",
        "public_ipv4_pool": "publicIpv4Pool",
        "tags": "tags",
    },
)
class CfnEIPProps:
    def __init__(
        self,
        *,
        domain: typing.Optional[builtins.str] = None,
        instance_id: typing.Optional[builtins.str] = None,
        public_ipv4_pool: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::EIP``.

        :param domain: ``AWS::EC2::EIP.Domain``.
        :param instance_id: ``AWS::EC2::EIP.InstanceId``.
        :param public_ipv4_pool: ``AWS::EC2::EIP.PublicIpv4Pool``.
        :param tags: ``AWS::EC2::EIP.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if domain is not None:
            self._values["domain"] = domain
        if instance_id is not None:
            self._values["instance_id"] = instance_id
        if public_ipv4_pool is not None:
            self._values["public_ipv4_pool"] = public_ipv4_pool
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def domain(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIP.Domain``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html#cfn-ec2-eip-domain
        '''
        result = self._values.get("domain")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def instance_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIP.InstanceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html#cfn-ec2-eip-instanceid
        '''
        result = self._values.get("instance_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def public_ipv4_pool(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::EIP.PublicIpv4Pool``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html#cfn-ec2-eip-publicipv4pool
        '''
        result = self._values.get("public_ipv4_pool")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::EIP.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html#cfn-ec2-eip-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnEIPProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnEgressOnlyInternetGateway(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnEgressOnlyInternetGateway",
):
    '''A CloudFormation ``AWS::EC2::EgressOnlyInternetGateway``.

    :cloudformationResource: AWS::EC2::EgressOnlyInternetGateway
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-egressonlyinternetgateway.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        vpc_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::EgressOnlyInternetGateway``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param vpc_id: ``AWS::EC2::EgressOnlyInternetGateway.VpcId``.
        '''
        props = CfnEgressOnlyInternetGatewayProps(vpc_id=vpc_id)

        jsii.create(CfnEgressOnlyInternetGateway, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::EgressOnlyInternetGateway.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-egressonlyinternetgateway.html#cfn-ec2-egressonlyinternetgateway-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnEgressOnlyInternetGatewayProps",
    jsii_struct_bases=[],
    name_mapping={"vpc_id": "vpcId"},
)
class CfnEgressOnlyInternetGatewayProps:
    def __init__(self, *, vpc_id: builtins.str) -> None:
        '''Properties for defining a ``AWS::EC2::EgressOnlyInternetGateway``.

        :param vpc_id: ``AWS::EC2::EgressOnlyInternetGateway.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-egressonlyinternetgateway.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "vpc_id": vpc_id,
        }

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::EgressOnlyInternetGateway.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-egressonlyinternetgateway.html#cfn-ec2-egressonlyinternetgateway-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnEgressOnlyInternetGatewayProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnFlowLog(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnFlowLog",
):
    '''A CloudFormation ``AWS::EC2::FlowLog``.

    :cloudformationResource: AWS::EC2::FlowLog
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        resource_id: builtins.str,
        resource_type: builtins.str,
        traffic_type: builtins.str,
        deliver_logs_permission_arn: typing.Optional[builtins.str] = None,
        log_destination: typing.Optional[builtins.str] = None,
        log_destination_type: typing.Optional[builtins.str] = None,
        log_format: typing.Optional[builtins.str] = None,
        log_group_name: typing.Optional[builtins.str] = None,
        max_aggregation_interval: typing.Optional[jsii.Number] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::FlowLog``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param resource_id: ``AWS::EC2::FlowLog.ResourceId``.
        :param resource_type: ``AWS::EC2::FlowLog.ResourceType``.
        :param traffic_type: ``AWS::EC2::FlowLog.TrafficType``.
        :param deliver_logs_permission_arn: ``AWS::EC2::FlowLog.DeliverLogsPermissionArn``.
        :param log_destination: ``AWS::EC2::FlowLog.LogDestination``.
        :param log_destination_type: ``AWS::EC2::FlowLog.LogDestinationType``.
        :param log_format: ``AWS::EC2::FlowLog.LogFormat``.
        :param log_group_name: ``AWS::EC2::FlowLog.LogGroupName``.
        :param max_aggregation_interval: ``AWS::EC2::FlowLog.MaxAggregationInterval``.
        :param tags: ``AWS::EC2::FlowLog.Tags``.
        '''
        props = CfnFlowLogProps(
            resource_id=resource_id,
            resource_type=resource_type,
            traffic_type=traffic_type,
            deliver_logs_permission_arn=deliver_logs_permission_arn,
            log_destination=log_destination,
            log_destination_type=log_destination_type,
            log_format=log_format,
            log_group_name=log_group_name,
            max_aggregation_interval=max_aggregation_interval,
            tags=tags,
        )

        jsii.create(CfnFlowLog, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrId")
    def attr_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: Id
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::FlowLog.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="resourceId")
    def resource_id(self) -> builtins.str:
        '''``AWS::EC2::FlowLog.ResourceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-resourceid
        '''
        return typing.cast(builtins.str, jsii.get(self, "resourceId"))

    @resource_id.setter
    def resource_id(self, value: builtins.str) -> None:
        jsii.set(self, "resourceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="resourceType")
    def resource_type(self) -> builtins.str:
        '''``AWS::EC2::FlowLog.ResourceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-resourcetype
        '''
        return typing.cast(builtins.str, jsii.get(self, "resourceType"))

    @resource_type.setter
    def resource_type(self, value: builtins.str) -> None:
        jsii.set(self, "resourceType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="trafficType")
    def traffic_type(self) -> builtins.str:
        '''``AWS::EC2::FlowLog.TrafficType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-traffictype
        '''
        return typing.cast(builtins.str, jsii.get(self, "trafficType"))

    @traffic_type.setter
    def traffic_type(self, value: builtins.str) -> None:
        jsii.set(self, "trafficType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="deliverLogsPermissionArn")
    def deliver_logs_permission_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::FlowLog.DeliverLogsPermissionArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-deliverlogspermissionarn
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "deliverLogsPermissionArn"))

    @deliver_logs_permission_arn.setter
    def deliver_logs_permission_arn(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "deliverLogsPermissionArn", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="logDestination")
    def log_destination(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::FlowLog.LogDestination``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-logdestination
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "logDestination"))

    @log_destination.setter
    def log_destination(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "logDestination", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="logDestinationType")
    def log_destination_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::FlowLog.LogDestinationType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-logdestinationtype
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "logDestinationType"))

    @log_destination_type.setter
    def log_destination_type(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "logDestinationType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="logFormat")
    def log_format(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::FlowLog.LogFormat``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-logformat
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "logFormat"))

    @log_format.setter
    def log_format(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "logFormat", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="logGroupName")
    def log_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::FlowLog.LogGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-loggroupname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "logGroupName"))

    @log_group_name.setter
    def log_group_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "logGroupName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="maxAggregationInterval")
    def max_aggregation_interval(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::FlowLog.MaxAggregationInterval``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-maxaggregationinterval
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "maxAggregationInterval"))

    @max_aggregation_interval.setter
    def max_aggregation_interval(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "maxAggregationInterval", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnFlowLogProps",
    jsii_struct_bases=[],
    name_mapping={
        "resource_id": "resourceId",
        "resource_type": "resourceType",
        "traffic_type": "trafficType",
        "deliver_logs_permission_arn": "deliverLogsPermissionArn",
        "log_destination": "logDestination",
        "log_destination_type": "logDestinationType",
        "log_format": "logFormat",
        "log_group_name": "logGroupName",
        "max_aggregation_interval": "maxAggregationInterval",
        "tags": "tags",
    },
)
class CfnFlowLogProps:
    def __init__(
        self,
        *,
        resource_id: builtins.str,
        resource_type: builtins.str,
        traffic_type: builtins.str,
        deliver_logs_permission_arn: typing.Optional[builtins.str] = None,
        log_destination: typing.Optional[builtins.str] = None,
        log_destination_type: typing.Optional[builtins.str] = None,
        log_format: typing.Optional[builtins.str] = None,
        log_group_name: typing.Optional[builtins.str] = None,
        max_aggregation_interval: typing.Optional[jsii.Number] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::FlowLog``.

        :param resource_id: ``AWS::EC2::FlowLog.ResourceId``.
        :param resource_type: ``AWS::EC2::FlowLog.ResourceType``.
        :param traffic_type: ``AWS::EC2::FlowLog.TrafficType``.
        :param deliver_logs_permission_arn: ``AWS::EC2::FlowLog.DeliverLogsPermissionArn``.
        :param log_destination: ``AWS::EC2::FlowLog.LogDestination``.
        :param log_destination_type: ``AWS::EC2::FlowLog.LogDestinationType``.
        :param log_format: ``AWS::EC2::FlowLog.LogFormat``.
        :param log_group_name: ``AWS::EC2::FlowLog.LogGroupName``.
        :param max_aggregation_interval: ``AWS::EC2::FlowLog.MaxAggregationInterval``.
        :param tags: ``AWS::EC2::FlowLog.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "resource_id": resource_id,
            "resource_type": resource_type,
            "traffic_type": traffic_type,
        }
        if deliver_logs_permission_arn is not None:
            self._values["deliver_logs_permission_arn"] = deliver_logs_permission_arn
        if log_destination is not None:
            self._values["log_destination"] = log_destination
        if log_destination_type is not None:
            self._values["log_destination_type"] = log_destination_type
        if log_format is not None:
            self._values["log_format"] = log_format
        if log_group_name is not None:
            self._values["log_group_name"] = log_group_name
        if max_aggregation_interval is not None:
            self._values["max_aggregation_interval"] = max_aggregation_interval
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def resource_id(self) -> builtins.str:
        '''``AWS::EC2::FlowLog.ResourceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-resourceid
        '''
        result = self._values.get("resource_id")
        assert result is not None, "Required property 'resource_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def resource_type(self) -> builtins.str:
        '''``AWS::EC2::FlowLog.ResourceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-resourcetype
        '''
        result = self._values.get("resource_type")
        assert result is not None, "Required property 'resource_type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def traffic_type(self) -> builtins.str:
        '''``AWS::EC2::FlowLog.TrafficType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-traffictype
        '''
        result = self._values.get("traffic_type")
        assert result is not None, "Required property 'traffic_type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def deliver_logs_permission_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::FlowLog.DeliverLogsPermissionArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-deliverlogspermissionarn
        '''
        result = self._values.get("deliver_logs_permission_arn")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def log_destination(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::FlowLog.LogDestination``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-logdestination
        '''
        result = self._values.get("log_destination")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def log_destination_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::FlowLog.LogDestinationType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-logdestinationtype
        '''
        result = self._values.get("log_destination_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def log_format(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::FlowLog.LogFormat``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-logformat
        '''
        result = self._values.get("log_format")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def log_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::FlowLog.LogGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-loggroupname
        '''
        result = self._values.get("log_group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def max_aggregation_interval(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::FlowLog.MaxAggregationInterval``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-maxaggregationinterval
        '''
        result = self._values.get("max_aggregation_interval")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::FlowLog.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html#cfn-ec2-flowlog-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnFlowLogProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnGatewayRouteTableAssociation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnGatewayRouteTableAssociation",
):
    '''A CloudFormation ``AWS::EC2::GatewayRouteTableAssociation``.

    :cloudformationResource: AWS::EC2::GatewayRouteTableAssociation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-gatewayroutetableassociation.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        gateway_id: builtins.str,
        route_table_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::GatewayRouteTableAssociation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param gateway_id: ``AWS::EC2::GatewayRouteTableAssociation.GatewayId``.
        :param route_table_id: ``AWS::EC2::GatewayRouteTableAssociation.RouteTableId``.
        '''
        props = CfnGatewayRouteTableAssociationProps(
            gateway_id=gateway_id, route_table_id=route_table_id
        )

        jsii.create(CfnGatewayRouteTableAssociation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAssociationId")
    def attr_association_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: AssociationId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrAssociationId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="gatewayId")
    def gateway_id(self) -> builtins.str:
        '''``AWS::EC2::GatewayRouteTableAssociation.GatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-gatewayroutetableassociation.html#cfn-ec2-gatewayroutetableassociation-gatewayid
        '''
        return typing.cast(builtins.str, jsii.get(self, "gatewayId"))

    @gateway_id.setter
    def gateway_id(self, value: builtins.str) -> None:
        jsii.set(self, "gatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="routeTableId")
    def route_table_id(self) -> builtins.str:
        '''``AWS::EC2::GatewayRouteTableAssociation.RouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-gatewayroutetableassociation.html#cfn-ec2-gatewayroutetableassociation-routetableid
        '''
        return typing.cast(builtins.str, jsii.get(self, "routeTableId"))

    @route_table_id.setter
    def route_table_id(self, value: builtins.str) -> None:
        jsii.set(self, "routeTableId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnGatewayRouteTableAssociationProps",
    jsii_struct_bases=[],
    name_mapping={"gateway_id": "gatewayId", "route_table_id": "routeTableId"},
)
class CfnGatewayRouteTableAssociationProps:
    def __init__(
        self,
        *,
        gateway_id: builtins.str,
        route_table_id: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::GatewayRouteTableAssociation``.

        :param gateway_id: ``AWS::EC2::GatewayRouteTableAssociation.GatewayId``.
        :param route_table_id: ``AWS::EC2::GatewayRouteTableAssociation.RouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-gatewayroutetableassociation.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "gateway_id": gateway_id,
            "route_table_id": route_table_id,
        }

    @builtins.property
    def gateway_id(self) -> builtins.str:
        '''``AWS::EC2::GatewayRouteTableAssociation.GatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-gatewayroutetableassociation.html#cfn-ec2-gatewayroutetableassociation-gatewayid
        '''
        result = self._values.get("gateway_id")
        assert result is not None, "Required property 'gateway_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def route_table_id(self) -> builtins.str:
        '''``AWS::EC2::GatewayRouteTableAssociation.RouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-gatewayroutetableassociation.html#cfn-ec2-gatewayroutetableassociation-routetableid
        '''
        result = self._values.get("route_table_id")
        assert result is not None, "Required property 'route_table_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnGatewayRouteTableAssociationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnHost(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnHost",
):
    '''A CloudFormation ``AWS::EC2::Host``.

    :cloudformationResource: AWS::EC2::Host
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-host.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        availability_zone: builtins.str,
        instance_type: builtins.str,
        auto_placement: typing.Optional[builtins.str] = None,
        host_recovery: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::Host``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param availability_zone: ``AWS::EC2::Host.AvailabilityZone``.
        :param instance_type: ``AWS::EC2::Host.InstanceType``.
        :param auto_placement: ``AWS::EC2::Host.AutoPlacement``.
        :param host_recovery: ``AWS::EC2::Host.HostRecovery``.
        '''
        props = CfnHostProps(
            availability_zone=availability_zone,
            instance_type=instance_type,
            auto_placement=auto_placement,
            host_recovery=host_recovery,
        )

        jsii.create(CfnHost, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> builtins.str:
        '''``AWS::EC2::Host.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-host.html#cfn-ec2-host-availabilityzone
        '''
        return typing.cast(builtins.str, jsii.get(self, "availabilityZone"))

    @availability_zone.setter
    def availability_zone(self, value: builtins.str) -> None:
        jsii.set(self, "availabilityZone", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceType")
    def instance_type(self) -> builtins.str:
        '''``AWS::EC2::Host.InstanceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-host.html#cfn-ec2-host-instancetype
        '''
        return typing.cast(builtins.str, jsii.get(self, "instanceType"))

    @instance_type.setter
    def instance_type(self, value: builtins.str) -> None:
        jsii.set(self, "instanceType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="autoPlacement")
    def auto_placement(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Host.AutoPlacement``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-host.html#cfn-ec2-host-autoplacement
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "autoPlacement"))

    @auto_placement.setter
    def auto_placement(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "autoPlacement", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="hostRecovery")
    def host_recovery(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Host.HostRecovery``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-host.html#cfn-ec2-host-hostrecovery
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "hostRecovery"))

    @host_recovery.setter
    def host_recovery(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "hostRecovery", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnHostProps",
    jsii_struct_bases=[],
    name_mapping={
        "availability_zone": "availabilityZone",
        "instance_type": "instanceType",
        "auto_placement": "autoPlacement",
        "host_recovery": "hostRecovery",
    },
)
class CfnHostProps:
    def __init__(
        self,
        *,
        availability_zone: builtins.str,
        instance_type: builtins.str,
        auto_placement: typing.Optional[builtins.str] = None,
        host_recovery: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::Host``.

        :param availability_zone: ``AWS::EC2::Host.AvailabilityZone``.
        :param instance_type: ``AWS::EC2::Host.InstanceType``.
        :param auto_placement: ``AWS::EC2::Host.AutoPlacement``.
        :param host_recovery: ``AWS::EC2::Host.HostRecovery``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-host.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "availability_zone": availability_zone,
            "instance_type": instance_type,
        }
        if auto_placement is not None:
            self._values["auto_placement"] = auto_placement
        if host_recovery is not None:
            self._values["host_recovery"] = host_recovery

    @builtins.property
    def availability_zone(self) -> builtins.str:
        '''``AWS::EC2::Host.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-host.html#cfn-ec2-host-availabilityzone
        '''
        result = self._values.get("availability_zone")
        assert result is not None, "Required property 'availability_zone' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def instance_type(self) -> builtins.str:
        '''``AWS::EC2::Host.InstanceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-host.html#cfn-ec2-host-instancetype
        '''
        result = self._values.get("instance_type")
        assert result is not None, "Required property 'instance_type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def auto_placement(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Host.AutoPlacement``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-host.html#cfn-ec2-host-autoplacement
        '''
        result = self._values.get("auto_placement")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def host_recovery(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Host.HostRecovery``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-host.html#cfn-ec2-host-hostrecovery
        '''
        result = self._values.get("host_recovery")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnHostProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnInstance(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnInstance",
):
    '''A CloudFormation ``AWS::EC2::Instance``.

    :cloudformationResource: AWS::EC2::Instance
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        additional_info: typing.Optional[builtins.str] = None,
        affinity: typing.Optional[builtins.str] = None,
        availability_zone: typing.Optional[builtins.str] = None,
        block_device_mappings: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.BlockDeviceMappingProperty"]]]] = None,
        cpu_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.CpuOptionsProperty"]] = None,
        credit_specification: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.CreditSpecificationProperty"]] = None,
        disable_api_termination: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ebs_optimized: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        elastic_gpu_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.ElasticGpuSpecificationProperty"]]]] = None,
        elastic_inference_accelerators: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.ElasticInferenceAcceleratorProperty"]]]] = None,
        enclave_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.EnclaveOptionsProperty"]] = None,
        hibernation_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.HibernationOptionsProperty"]] = None,
        host_id: typing.Optional[builtins.str] = None,
        host_resource_group_arn: typing.Optional[builtins.str] = None,
        iam_instance_profile: typing.Optional[builtins.str] = None,
        image_id: typing.Optional[builtins.str] = None,
        instance_initiated_shutdown_behavior: typing.Optional[builtins.str] = None,
        instance_type: typing.Optional[builtins.str] = None,
        ipv6_address_count: typing.Optional[jsii.Number] = None,
        ipv6_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.InstanceIpv6AddressProperty"]]]] = None,
        kernel_id: typing.Optional[builtins.str] = None,
        key_name: typing.Optional[builtins.str] = None,
        launch_template: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.LaunchTemplateSpecificationProperty"]] = None,
        license_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.LicenseSpecificationProperty"]]]] = None,
        monitoring: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        network_interfaces: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.NetworkInterfaceProperty"]]]] = None,
        placement_group_name: typing.Optional[builtins.str] = None,
        private_ip_address: typing.Optional[builtins.str] = None,
        ramdisk_id: typing.Optional[builtins.str] = None,
        security_group_ids: typing.Optional[typing.List[builtins.str]] = None,
        security_groups: typing.Optional[typing.List[builtins.str]] = None,
        source_dest_check: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ssm_associations: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.SsmAssociationProperty"]]]] = None,
        subnet_id: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        tenancy: typing.Optional[builtins.str] = None,
        user_data: typing.Optional[builtins.str] = None,
        volumes: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.VolumeProperty"]]]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::Instance``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param additional_info: ``AWS::EC2::Instance.AdditionalInfo``.
        :param affinity: ``AWS::EC2::Instance.Affinity``.
        :param availability_zone: ``AWS::EC2::Instance.AvailabilityZone``.
        :param block_device_mappings: ``AWS::EC2::Instance.BlockDeviceMappings``.
        :param cpu_options: ``AWS::EC2::Instance.CpuOptions``.
        :param credit_specification: ``AWS::EC2::Instance.CreditSpecification``.
        :param disable_api_termination: ``AWS::EC2::Instance.DisableApiTermination``.
        :param ebs_optimized: ``AWS::EC2::Instance.EbsOptimized``.
        :param elastic_gpu_specifications: ``AWS::EC2::Instance.ElasticGpuSpecifications``.
        :param elastic_inference_accelerators: ``AWS::EC2::Instance.ElasticInferenceAccelerators``.
        :param enclave_options: ``AWS::EC2::Instance.EnclaveOptions``.
        :param hibernation_options: ``AWS::EC2::Instance.HibernationOptions``.
        :param host_id: ``AWS::EC2::Instance.HostId``.
        :param host_resource_group_arn: ``AWS::EC2::Instance.HostResourceGroupArn``.
        :param iam_instance_profile: ``AWS::EC2::Instance.IamInstanceProfile``.
        :param image_id: ``AWS::EC2::Instance.ImageId``.
        :param instance_initiated_shutdown_behavior: ``AWS::EC2::Instance.InstanceInitiatedShutdownBehavior``.
        :param instance_type: ``AWS::EC2::Instance.InstanceType``.
        :param ipv6_address_count: ``AWS::EC2::Instance.Ipv6AddressCount``.
        :param ipv6_addresses: ``AWS::EC2::Instance.Ipv6Addresses``.
        :param kernel_id: ``AWS::EC2::Instance.KernelId``.
        :param key_name: ``AWS::EC2::Instance.KeyName``.
        :param launch_template: ``AWS::EC2::Instance.LaunchTemplate``.
        :param license_specifications: ``AWS::EC2::Instance.LicenseSpecifications``.
        :param monitoring: ``AWS::EC2::Instance.Monitoring``.
        :param network_interfaces: ``AWS::EC2::Instance.NetworkInterfaces``.
        :param placement_group_name: ``AWS::EC2::Instance.PlacementGroupName``.
        :param private_ip_address: ``AWS::EC2::Instance.PrivateIpAddress``.
        :param ramdisk_id: ``AWS::EC2::Instance.RamdiskId``.
        :param security_group_ids: ``AWS::EC2::Instance.SecurityGroupIds``.
        :param security_groups: ``AWS::EC2::Instance.SecurityGroups``.
        :param source_dest_check: ``AWS::EC2::Instance.SourceDestCheck``.
        :param ssm_associations: ``AWS::EC2::Instance.SsmAssociations``.
        :param subnet_id: ``AWS::EC2::Instance.SubnetId``.
        :param tags: ``AWS::EC2::Instance.Tags``.
        :param tenancy: ``AWS::EC2::Instance.Tenancy``.
        :param user_data: ``AWS::EC2::Instance.UserData``.
        :param volumes: ``AWS::EC2::Instance.Volumes``.
        '''
        props = CfnInstanceProps(
            additional_info=additional_info,
            affinity=affinity,
            availability_zone=availability_zone,
            block_device_mappings=block_device_mappings,
            cpu_options=cpu_options,
            credit_specification=credit_specification,
            disable_api_termination=disable_api_termination,
            ebs_optimized=ebs_optimized,
            elastic_gpu_specifications=elastic_gpu_specifications,
            elastic_inference_accelerators=elastic_inference_accelerators,
            enclave_options=enclave_options,
            hibernation_options=hibernation_options,
            host_id=host_id,
            host_resource_group_arn=host_resource_group_arn,
            iam_instance_profile=iam_instance_profile,
            image_id=image_id,
            instance_initiated_shutdown_behavior=instance_initiated_shutdown_behavior,
            instance_type=instance_type,
            ipv6_address_count=ipv6_address_count,
            ipv6_addresses=ipv6_addresses,
            kernel_id=kernel_id,
            key_name=key_name,
            launch_template=launch_template,
            license_specifications=license_specifications,
            monitoring=monitoring,
            network_interfaces=network_interfaces,
            placement_group_name=placement_group_name,
            private_ip_address=private_ip_address,
            ramdisk_id=ramdisk_id,
            security_group_ids=security_group_ids,
            security_groups=security_groups,
            source_dest_check=source_dest_check,
            ssm_associations=ssm_associations,
            subnet_id=subnet_id,
            tags=tags,
            tenancy=tenancy,
            user_data=user_data,
            volumes=volumes,
        )

        jsii.create(CfnInstance, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAvailabilityZone")
    def attr_availability_zone(self) -> builtins.str:
        '''
        :cloudformationAttribute: AvailabilityZone
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrAvailabilityZone"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrPrivateDnsName")
    def attr_private_dns_name(self) -> builtins.str:
        '''
        :cloudformationAttribute: PrivateDnsName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrPrivateDnsName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrPrivateIp")
    def attr_private_ip(self) -> builtins.str:
        '''
        :cloudformationAttribute: PrivateIp
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrPrivateIp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrPublicDnsName")
    def attr_public_dns_name(self) -> builtins.str:
        '''
        :cloudformationAttribute: PublicDnsName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrPublicDnsName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrPublicIp")
    def attr_public_ip(self) -> builtins.str:
        '''
        :cloudformationAttribute: PublicIp
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrPublicIp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::Instance.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="additionalInfo")
    def additional_info(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.AdditionalInfo``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-additionalinfo
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "additionalInfo"))

    @additional_info.setter
    def additional_info(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "additionalInfo", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="affinity")
    def affinity(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.Affinity``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-affinity
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "affinity"))

    @affinity.setter
    def affinity(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "affinity", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-availabilityzone
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "availabilityZone"))

    @availability_zone.setter
    def availability_zone(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "availabilityZone", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="blockDeviceMappings")
    def block_device_mappings(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.BlockDeviceMappingProperty"]]]]:
        '''``AWS::EC2::Instance.BlockDeviceMappings``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-blockdevicemappings
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.BlockDeviceMappingProperty"]]]], jsii.get(self, "blockDeviceMappings"))

    @block_device_mappings.setter
    def block_device_mappings(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.BlockDeviceMappingProperty"]]]],
    ) -> None:
        jsii.set(self, "blockDeviceMappings", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cpuOptions")
    def cpu_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.CpuOptionsProperty"]]:
        '''``AWS::EC2::Instance.CpuOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-cpuoptions
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.CpuOptionsProperty"]], jsii.get(self, "cpuOptions"))

    @cpu_options.setter
    def cpu_options(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.CpuOptionsProperty"]],
    ) -> None:
        jsii.set(self, "cpuOptions", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="creditSpecification")
    def credit_specification(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.CreditSpecificationProperty"]]:
        '''``AWS::EC2::Instance.CreditSpecification``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-creditspecification
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.CreditSpecificationProperty"]], jsii.get(self, "creditSpecification"))

    @credit_specification.setter
    def credit_specification(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.CreditSpecificationProperty"]],
    ) -> None:
        jsii.set(self, "creditSpecification", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="disableApiTermination")
    def disable_api_termination(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Instance.DisableApiTermination``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-disableapitermination
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "disableApiTermination"))

    @disable_api_termination.setter
    def disable_api_termination(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "disableApiTermination", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ebsOptimized")
    def ebs_optimized(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Instance.EbsOptimized``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-ebsoptimized
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "ebsOptimized"))

    @ebs_optimized.setter
    def ebs_optimized(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "ebsOptimized", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elasticGpuSpecifications")
    def elastic_gpu_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.ElasticGpuSpecificationProperty"]]]]:
        '''``AWS::EC2::Instance.ElasticGpuSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-elasticgpuspecifications
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.ElasticGpuSpecificationProperty"]]]], jsii.get(self, "elasticGpuSpecifications"))

    @elastic_gpu_specifications.setter
    def elastic_gpu_specifications(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.ElasticGpuSpecificationProperty"]]]],
    ) -> None:
        jsii.set(self, "elasticGpuSpecifications", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elasticInferenceAccelerators")
    def elastic_inference_accelerators(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.ElasticInferenceAcceleratorProperty"]]]]:
        '''``AWS::EC2::Instance.ElasticInferenceAccelerators``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-elasticinferenceaccelerators
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.ElasticInferenceAcceleratorProperty"]]]], jsii.get(self, "elasticInferenceAccelerators"))

    @elastic_inference_accelerators.setter
    def elastic_inference_accelerators(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.ElasticInferenceAcceleratorProperty"]]]],
    ) -> None:
        jsii.set(self, "elasticInferenceAccelerators", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="enclaveOptions")
    def enclave_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.EnclaveOptionsProperty"]]:
        '''``AWS::EC2::Instance.EnclaveOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-enclaveoptions
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.EnclaveOptionsProperty"]], jsii.get(self, "enclaveOptions"))

    @enclave_options.setter
    def enclave_options(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.EnclaveOptionsProperty"]],
    ) -> None:
        jsii.set(self, "enclaveOptions", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="hibernationOptions")
    def hibernation_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.HibernationOptionsProperty"]]:
        '''``AWS::EC2::Instance.HibernationOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-hibernationoptions
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.HibernationOptionsProperty"]], jsii.get(self, "hibernationOptions"))

    @hibernation_options.setter
    def hibernation_options(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.HibernationOptionsProperty"]],
    ) -> None:
        jsii.set(self, "hibernationOptions", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="hostId")
    def host_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.HostId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-hostid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "hostId"))

    @host_id.setter
    def host_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "hostId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="hostResourceGroupArn")
    def host_resource_group_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.HostResourceGroupArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-hostresourcegrouparn
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "hostResourceGroupArn"))

    @host_resource_group_arn.setter
    def host_resource_group_arn(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "hostResourceGroupArn", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="iamInstanceProfile")
    def iam_instance_profile(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.IamInstanceProfile``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-iaminstanceprofile
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "iamInstanceProfile"))

    @iam_instance_profile.setter
    def iam_instance_profile(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "iamInstanceProfile", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="imageId")
    def image_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.ImageId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-imageid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "imageId"))

    @image_id.setter
    def image_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "imageId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceInitiatedShutdownBehavior")
    def instance_initiated_shutdown_behavior(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.InstanceInitiatedShutdownBehavior``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-instanceinitiatedshutdownbehavior
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "instanceInitiatedShutdownBehavior"))

    @instance_initiated_shutdown_behavior.setter
    def instance_initiated_shutdown_behavior(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "instanceInitiatedShutdownBehavior", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceType")
    def instance_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.InstanceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-instancetype
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "instanceType"))

    @instance_type.setter
    def instance_type(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "instanceType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipv6AddressCount")
    def ipv6_address_count(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::Instance.Ipv6AddressCount``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-ipv6addresscount
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "ipv6AddressCount"))

    @ipv6_address_count.setter
    def ipv6_address_count(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "ipv6AddressCount", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipv6Addresses")
    def ipv6_addresses(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.InstanceIpv6AddressProperty"]]]]:
        '''``AWS::EC2::Instance.Ipv6Addresses``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-ipv6addresses
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.InstanceIpv6AddressProperty"]]]], jsii.get(self, "ipv6Addresses"))

    @ipv6_addresses.setter
    def ipv6_addresses(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.InstanceIpv6AddressProperty"]]]],
    ) -> None:
        jsii.set(self, "ipv6Addresses", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="kernelId")
    def kernel_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.KernelId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-kernelid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "kernelId"))

    @kernel_id.setter
    def kernel_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "kernelId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="keyName")
    def key_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.KeyName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-keyname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "keyName"))

    @key_name.setter
    def key_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "keyName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="launchTemplate")
    def launch_template(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.LaunchTemplateSpecificationProperty"]]:
        '''``AWS::EC2::Instance.LaunchTemplate``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-launchtemplate
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.LaunchTemplateSpecificationProperty"]], jsii.get(self, "launchTemplate"))

    @launch_template.setter
    def launch_template(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.LaunchTemplateSpecificationProperty"]],
    ) -> None:
        jsii.set(self, "launchTemplate", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="licenseSpecifications")
    def license_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.LicenseSpecificationProperty"]]]]:
        '''``AWS::EC2::Instance.LicenseSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-licensespecifications
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.LicenseSpecificationProperty"]]]], jsii.get(self, "licenseSpecifications"))

    @license_specifications.setter
    def license_specifications(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.LicenseSpecificationProperty"]]]],
    ) -> None:
        jsii.set(self, "licenseSpecifications", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="monitoring")
    def monitoring(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Instance.Monitoring``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-monitoring
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "monitoring"))

    @monitoring.setter
    def monitoring(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "monitoring", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkInterfaces")
    def network_interfaces(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.NetworkInterfaceProperty"]]]]:
        '''``AWS::EC2::Instance.NetworkInterfaces``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-networkinterfaces
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.NetworkInterfaceProperty"]]]], jsii.get(self, "networkInterfaces"))

    @network_interfaces.setter
    def network_interfaces(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.NetworkInterfaceProperty"]]]],
    ) -> None:
        jsii.set(self, "networkInterfaces", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="placementGroupName")
    def placement_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.PlacementGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-placementgroupname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "placementGroupName"))

    @placement_group_name.setter
    def placement_group_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "placementGroupName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateIpAddress")
    def private_ip_address(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.PrivateIpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-privateipaddress
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "privateIpAddress"))

    @private_ip_address.setter
    def private_ip_address(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "privateIpAddress", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ramdiskId")
    def ramdisk_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.RamdiskId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-ramdiskid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "ramdiskId"))

    @ramdisk_id.setter
    def ramdisk_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "ramdiskId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroupIds")
    def security_group_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::Instance.SecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-securitygroupids
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "securityGroupIds"))

    @security_group_ids.setter
    def security_group_ids(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "securityGroupIds", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroups")
    def security_groups(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::Instance.SecurityGroups``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-securitygroups
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "securityGroups"))

    @security_groups.setter
    def security_groups(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "securityGroups", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sourceDestCheck")
    def source_dest_check(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Instance.SourceDestCheck``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-sourcedestcheck
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "sourceDestCheck"))

    @source_dest_check.setter
    def source_dest_check(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "sourceDestCheck", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ssmAssociations")
    def ssm_associations(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.SsmAssociationProperty"]]]]:
        '''``AWS::EC2::Instance.SsmAssociations``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-ssmassociations
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.SsmAssociationProperty"]]]], jsii.get(self, "ssmAssociations"))

    @ssm_associations.setter
    def ssm_associations(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.SsmAssociationProperty"]]]],
    ) -> None:
        jsii.set(self, "ssmAssociations", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetId")
    def subnet_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-subnetid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "subnetId"))

    @subnet_id.setter
    def subnet_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "subnetId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tenancy")
    def tenancy(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.Tenancy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-tenancy
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "tenancy"))

    @tenancy.setter
    def tenancy(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "tenancy", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="userData")
    def user_data(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.UserData``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-userdata
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "userData"))

    @user_data.setter
    def user_data(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "userData", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="volumes")
    def volumes(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.VolumeProperty"]]]]:
        '''``AWS::EC2::Instance.Volumes``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-volumes
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.VolumeProperty"]]]], jsii.get(self, "volumes"))

    @volumes.setter
    def volumes(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.VolumeProperty"]]]],
    ) -> None:
        jsii.set(self, "volumes", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.AssociationParameterProperty",
        jsii_struct_bases=[],
        name_mapping={"key": "key", "value": "value"},
    )
    class AssociationParameterProperty:
        def __init__(
            self,
            *,
            key: builtins.str,
            value: typing.List[builtins.str],
        ) -> None:
            '''
            :param key: ``CfnInstance.AssociationParameterProperty.Key``.
            :param value: ``CfnInstance.AssociationParameterProperty.Value``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-ssmassociations-associationparameters.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "key": key,
                "value": value,
            }

        @builtins.property
        def key(self) -> builtins.str:
            '''``CfnInstance.AssociationParameterProperty.Key``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-ssmassociations-associationparameters.html#cfn-ec2-instance-ssmassociations-associationparameters-key
            '''
            result = self._values.get("key")
            assert result is not None, "Required property 'key' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def value(self) -> typing.List[builtins.str]:
            '''``CfnInstance.AssociationParameterProperty.Value``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-ssmassociations-associationparameters.html#cfn-ec2-instance-ssmassociations-associationparameters-value
            '''
            result = self._values.get("value")
            assert result is not None, "Required property 'value' is missing"
            return typing.cast(typing.List[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AssociationParameterProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.BlockDeviceMappingProperty",
        jsii_struct_bases=[],
        name_mapping={
            "device_name": "deviceName",
            "ebs": "ebs",
            "no_device": "noDevice",
            "virtual_name": "virtualName",
        },
    )
    class BlockDeviceMappingProperty:
        def __init__(
            self,
            *,
            device_name: builtins.str,
            ebs: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.EbsProperty"]] = None,
            no_device: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.NoDeviceProperty"]] = None,
            virtual_name: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param device_name: ``CfnInstance.BlockDeviceMappingProperty.DeviceName``.
            :param ebs: ``CfnInstance.BlockDeviceMappingProperty.Ebs``.
            :param no_device: ``CfnInstance.BlockDeviceMappingProperty.NoDevice``.
            :param virtual_name: ``CfnInstance.BlockDeviceMappingProperty.VirtualName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-mapping.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "device_name": device_name,
            }
            if ebs is not None:
                self._values["ebs"] = ebs
            if no_device is not None:
                self._values["no_device"] = no_device
            if virtual_name is not None:
                self._values["virtual_name"] = virtual_name

        @builtins.property
        def device_name(self) -> builtins.str:
            '''``CfnInstance.BlockDeviceMappingProperty.DeviceName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-mapping.html#cfn-ec2-blockdev-mapping-devicename
            '''
            result = self._values.get("device_name")
            assert result is not None, "Required property 'device_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def ebs(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.EbsProperty"]]:
            '''``CfnInstance.BlockDeviceMappingProperty.Ebs``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-mapping.html#cfn-ec2-blockdev-mapping-ebs
            '''
            result = self._values.get("ebs")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.EbsProperty"]], result)

        @builtins.property
        def no_device(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.NoDeviceProperty"]]:
            '''``CfnInstance.BlockDeviceMappingProperty.NoDevice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-mapping.html#cfn-ec2-blockdev-mapping-nodevice
            '''
            result = self._values.get("no_device")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.NoDeviceProperty"]], result)

        @builtins.property
        def virtual_name(self) -> typing.Optional[builtins.str]:
            '''``CfnInstance.BlockDeviceMappingProperty.VirtualName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-mapping.html#cfn-ec2-blockdev-mapping-virtualname
            '''
            result = self._values.get("virtual_name")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "BlockDeviceMappingProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.CpuOptionsProperty",
        jsii_struct_bases=[],
        name_mapping={"core_count": "coreCount", "threads_per_core": "threadsPerCore"},
    )
    class CpuOptionsProperty:
        def __init__(
            self,
            *,
            core_count: typing.Optional[jsii.Number] = None,
            threads_per_core: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param core_count: ``CfnInstance.CpuOptionsProperty.CoreCount``.
            :param threads_per_core: ``CfnInstance.CpuOptionsProperty.ThreadsPerCore``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-cpuoptions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if core_count is not None:
                self._values["core_count"] = core_count
            if threads_per_core is not None:
                self._values["threads_per_core"] = threads_per_core

        @builtins.property
        def core_count(self) -> typing.Optional[jsii.Number]:
            '''``CfnInstance.CpuOptionsProperty.CoreCount``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-cpuoptions.html#cfn-ec2-instance-cpuoptions-corecount
            '''
            result = self._values.get("core_count")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def threads_per_core(self) -> typing.Optional[jsii.Number]:
            '''``CfnInstance.CpuOptionsProperty.ThreadsPerCore``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-cpuoptions.html#cfn-ec2-instance-cpuoptions-threadspercore
            '''
            result = self._values.get("threads_per_core")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CpuOptionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.CreditSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"cpu_credits": "cpuCredits"},
    )
    class CreditSpecificationProperty:
        def __init__(
            self,
            *,
            cpu_credits: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param cpu_credits: ``CfnInstance.CreditSpecificationProperty.CPUCredits``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-creditspecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if cpu_credits is not None:
                self._values["cpu_credits"] = cpu_credits

        @builtins.property
        def cpu_credits(self) -> typing.Optional[builtins.str]:
            '''``CfnInstance.CreditSpecificationProperty.CPUCredits``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-creditspecification.html#cfn-ec2-instance-creditspecification-cpucredits
            '''
            result = self._values.get("cpu_credits")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CreditSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.EbsProperty",
        jsii_struct_bases=[],
        name_mapping={
            "delete_on_termination": "deleteOnTermination",
            "encrypted": "encrypted",
            "iops": "iops",
            "kms_key_id": "kmsKeyId",
            "snapshot_id": "snapshotId",
            "volume_size": "volumeSize",
            "volume_type": "volumeType",
        },
    )
    class EbsProperty:
        def __init__(
            self,
            *,
            delete_on_termination: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            encrypted: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            iops: typing.Optional[jsii.Number] = None,
            kms_key_id: typing.Optional[builtins.str] = None,
            snapshot_id: typing.Optional[builtins.str] = None,
            volume_size: typing.Optional[jsii.Number] = None,
            volume_type: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param delete_on_termination: ``CfnInstance.EbsProperty.DeleteOnTermination``.
            :param encrypted: ``CfnInstance.EbsProperty.Encrypted``.
            :param iops: ``CfnInstance.EbsProperty.Iops``.
            :param kms_key_id: ``CfnInstance.EbsProperty.KmsKeyId``.
            :param snapshot_id: ``CfnInstance.EbsProperty.SnapshotId``.
            :param volume_size: ``CfnInstance.EbsProperty.VolumeSize``.
            :param volume_type: ``CfnInstance.EbsProperty.VolumeType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if delete_on_termination is not None:
                self._values["delete_on_termination"] = delete_on_termination
            if encrypted is not None:
                self._values["encrypted"] = encrypted
            if iops is not None:
                self._values["iops"] = iops
            if kms_key_id is not None:
                self._values["kms_key_id"] = kms_key_id
            if snapshot_id is not None:
                self._values["snapshot_id"] = snapshot_id
            if volume_size is not None:
                self._values["volume_size"] = volume_size
            if volume_type is not None:
                self._values["volume_type"] = volume_type

        @builtins.property
        def delete_on_termination(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnInstance.EbsProperty.DeleteOnTermination``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html#cfn-ec2-blockdev-template-deleteontermination
            '''
            result = self._values.get("delete_on_termination")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def encrypted(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnInstance.EbsProperty.Encrypted``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html#cfn-ec2-blockdev-template-encrypted
            '''
            result = self._values.get("encrypted")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def iops(self) -> typing.Optional[jsii.Number]:
            '''``CfnInstance.EbsProperty.Iops``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html#cfn-ec2-blockdev-template-iops
            '''
            result = self._values.get("iops")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def kms_key_id(self) -> typing.Optional[builtins.str]:
            '''``CfnInstance.EbsProperty.KmsKeyId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html#cfn-ec2-instance-ebs-kmskeyid
            '''
            result = self._values.get("kms_key_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def snapshot_id(self) -> typing.Optional[builtins.str]:
            '''``CfnInstance.EbsProperty.SnapshotId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html#cfn-ec2-blockdev-template-snapshotid
            '''
            result = self._values.get("snapshot_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def volume_size(self) -> typing.Optional[jsii.Number]:
            '''``CfnInstance.EbsProperty.VolumeSize``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html#cfn-ec2-blockdev-template-volumesize
            '''
            result = self._values.get("volume_size")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def volume_type(self) -> typing.Optional[builtins.str]:
            '''``CfnInstance.EbsProperty.VolumeType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-blockdev-template.html#cfn-ec2-blockdev-template-volumetype
            '''
            result = self._values.get("volume_type")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "EbsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.ElasticGpuSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"type": "type"},
    )
    class ElasticGpuSpecificationProperty:
        def __init__(self, *, type: builtins.str) -> None:
            '''
            :param type: ``CfnInstance.ElasticGpuSpecificationProperty.Type``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-elasticgpuspecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "type": type,
            }

        @builtins.property
        def type(self) -> builtins.str:
            '''``CfnInstance.ElasticGpuSpecificationProperty.Type``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-elasticgpuspecification.html#cfn-ec2-instance-elasticgpuspecification-type
            '''
            result = self._values.get("type")
            assert result is not None, "Required property 'type' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ElasticGpuSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.ElasticInferenceAcceleratorProperty",
        jsii_struct_bases=[],
        name_mapping={"type": "type", "count": "count"},
    )
    class ElasticInferenceAcceleratorProperty:
        def __init__(
            self,
            *,
            type: builtins.str,
            count: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param type: ``CfnInstance.ElasticInferenceAcceleratorProperty.Type``.
            :param count: ``CfnInstance.ElasticInferenceAcceleratorProperty.Count``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-elasticinferenceaccelerator.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "type": type,
            }
            if count is not None:
                self._values["count"] = count

        @builtins.property
        def type(self) -> builtins.str:
            '''``CfnInstance.ElasticInferenceAcceleratorProperty.Type``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-elasticinferenceaccelerator.html#cfn-ec2-instance-elasticinferenceaccelerator-type
            '''
            result = self._values.get("type")
            assert result is not None, "Required property 'type' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def count(self) -> typing.Optional[jsii.Number]:
            '''``CfnInstance.ElasticInferenceAcceleratorProperty.Count``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-elasticinferenceaccelerator.html#cfn-ec2-instance-elasticinferenceaccelerator-count
            '''
            result = self._values.get("count")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ElasticInferenceAcceleratorProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.EnclaveOptionsProperty",
        jsii_struct_bases=[],
        name_mapping={"enabled": "enabled"},
    )
    class EnclaveOptionsProperty:
        def __init__(
            self,
            *,
            enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ) -> None:
            '''
            :param enabled: ``CfnInstance.EnclaveOptionsProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-enclaveoptions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if enabled is not None:
                self._values["enabled"] = enabled

        @builtins.property
        def enabled(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnInstance.EnclaveOptionsProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-enclaveoptions.html#cfn-ec2-instance-enclaveoptions-enabled
            '''
            result = self._values.get("enabled")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "EnclaveOptionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.HibernationOptionsProperty",
        jsii_struct_bases=[],
        name_mapping={"configured": "configured"},
    )
    class HibernationOptionsProperty:
        def __init__(
            self,
            *,
            configured: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ) -> None:
            '''
            :param configured: ``CfnInstance.HibernationOptionsProperty.Configured``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-hibernationoptions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if configured is not None:
                self._values["configured"] = configured

        @builtins.property
        def configured(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnInstance.HibernationOptionsProperty.Configured``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-hibernationoptions.html#cfn-ec2-instance-hibernationoptions-configured
            '''
            result = self._values.get("configured")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HibernationOptionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.InstanceIpv6AddressProperty",
        jsii_struct_bases=[],
        name_mapping={"ipv6_address": "ipv6Address"},
    )
    class InstanceIpv6AddressProperty:
        def __init__(self, *, ipv6_address: builtins.str) -> None:
            '''
            :param ipv6_address: ``CfnInstance.InstanceIpv6AddressProperty.Ipv6Address``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-instanceipv6address.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "ipv6_address": ipv6_address,
            }

        @builtins.property
        def ipv6_address(self) -> builtins.str:
            '''``CfnInstance.InstanceIpv6AddressProperty.Ipv6Address``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-instanceipv6address.html#cfn-ec2-instance-instanceipv6address-ipv6address
            '''
            result = self._values.get("ipv6_address")
            assert result is not None, "Required property 'ipv6_address' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "InstanceIpv6AddressProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.LaunchTemplateSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={
            "version": "version",
            "launch_template_id": "launchTemplateId",
            "launch_template_name": "launchTemplateName",
        },
    )
    class LaunchTemplateSpecificationProperty:
        def __init__(
            self,
            *,
            version: builtins.str,
            launch_template_id: typing.Optional[builtins.str] = None,
            launch_template_name: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param version: ``CfnInstance.LaunchTemplateSpecificationProperty.Version``.
            :param launch_template_id: ``CfnInstance.LaunchTemplateSpecificationProperty.LaunchTemplateId``.
            :param launch_template_name: ``CfnInstance.LaunchTemplateSpecificationProperty.LaunchTemplateName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-launchtemplatespecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "version": version,
            }
            if launch_template_id is not None:
                self._values["launch_template_id"] = launch_template_id
            if launch_template_name is not None:
                self._values["launch_template_name"] = launch_template_name

        @builtins.property
        def version(self) -> builtins.str:
            '''``CfnInstance.LaunchTemplateSpecificationProperty.Version``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-launchtemplatespecification.html#cfn-ec2-instance-launchtemplatespecification-version
            '''
            result = self._values.get("version")
            assert result is not None, "Required property 'version' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def launch_template_id(self) -> typing.Optional[builtins.str]:
            '''``CfnInstance.LaunchTemplateSpecificationProperty.LaunchTemplateId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-launchtemplatespecification.html#cfn-ec2-instance-launchtemplatespecification-launchtemplateid
            '''
            result = self._values.get("launch_template_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def launch_template_name(self) -> typing.Optional[builtins.str]:
            '''``CfnInstance.LaunchTemplateSpecificationProperty.LaunchTemplateName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-launchtemplatespecification.html#cfn-ec2-instance-launchtemplatespecification-launchtemplatename
            '''
            result = self._values.get("launch_template_name")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LaunchTemplateSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.LicenseSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"license_configuration_arn": "licenseConfigurationArn"},
    )
    class LicenseSpecificationProperty:
        def __init__(self, *, license_configuration_arn: builtins.str) -> None:
            '''
            :param license_configuration_arn: ``CfnInstance.LicenseSpecificationProperty.LicenseConfigurationArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-licensespecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "license_configuration_arn": license_configuration_arn,
            }

        @builtins.property
        def license_configuration_arn(self) -> builtins.str:
            '''``CfnInstance.LicenseSpecificationProperty.LicenseConfigurationArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-licensespecification.html#cfn-ec2-instance-licensespecification-licenseconfigurationarn
            '''
            result = self._values.get("license_configuration_arn")
            assert result is not None, "Required property 'license_configuration_arn' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LicenseSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.NetworkInterfaceProperty",
        jsii_struct_bases=[],
        name_mapping={
            "device_index": "deviceIndex",
            "associate_public_ip_address": "associatePublicIpAddress",
            "delete_on_termination": "deleteOnTermination",
            "description": "description",
            "group_set": "groupSet",
            "ipv6_address_count": "ipv6AddressCount",
            "ipv6_addresses": "ipv6Addresses",
            "network_interface_id": "networkInterfaceId",
            "private_ip_address": "privateIpAddress",
            "private_ip_addresses": "privateIpAddresses",
            "secondary_private_ip_address_count": "secondaryPrivateIpAddressCount",
            "subnet_id": "subnetId",
        },
    )
    class NetworkInterfaceProperty:
        def __init__(
            self,
            *,
            device_index: builtins.str,
            associate_public_ip_address: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            delete_on_termination: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            description: typing.Optional[builtins.str] = None,
            group_set: typing.Optional[typing.List[builtins.str]] = None,
            ipv6_address_count: typing.Optional[jsii.Number] = None,
            ipv6_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.InstanceIpv6AddressProperty"]]]] = None,
            network_interface_id: typing.Optional[builtins.str] = None,
            private_ip_address: typing.Optional[builtins.str] = None,
            private_ip_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.PrivateIpAddressSpecificationProperty"]]]] = None,
            secondary_private_ip_address_count: typing.Optional[jsii.Number] = None,
            subnet_id: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param device_index: ``CfnInstance.NetworkInterfaceProperty.DeviceIndex``.
            :param associate_public_ip_address: ``CfnInstance.NetworkInterfaceProperty.AssociatePublicIpAddress``.
            :param delete_on_termination: ``CfnInstance.NetworkInterfaceProperty.DeleteOnTermination``.
            :param description: ``CfnInstance.NetworkInterfaceProperty.Description``.
            :param group_set: ``CfnInstance.NetworkInterfaceProperty.GroupSet``.
            :param ipv6_address_count: ``CfnInstance.NetworkInterfaceProperty.Ipv6AddressCount``.
            :param ipv6_addresses: ``CfnInstance.NetworkInterfaceProperty.Ipv6Addresses``.
            :param network_interface_id: ``CfnInstance.NetworkInterfaceProperty.NetworkInterfaceId``.
            :param private_ip_address: ``CfnInstance.NetworkInterfaceProperty.PrivateIpAddress``.
            :param private_ip_addresses: ``CfnInstance.NetworkInterfaceProperty.PrivateIpAddresses``.
            :param secondary_private_ip_address_count: ``CfnInstance.NetworkInterfaceProperty.SecondaryPrivateIpAddressCount``.
            :param subnet_id: ``CfnInstance.NetworkInterfaceProperty.SubnetId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "device_index": device_index,
            }
            if associate_public_ip_address is not None:
                self._values["associate_public_ip_address"] = associate_public_ip_address
            if delete_on_termination is not None:
                self._values["delete_on_termination"] = delete_on_termination
            if description is not None:
                self._values["description"] = description
            if group_set is not None:
                self._values["group_set"] = group_set
            if ipv6_address_count is not None:
                self._values["ipv6_address_count"] = ipv6_address_count
            if ipv6_addresses is not None:
                self._values["ipv6_addresses"] = ipv6_addresses
            if network_interface_id is not None:
                self._values["network_interface_id"] = network_interface_id
            if private_ip_address is not None:
                self._values["private_ip_address"] = private_ip_address
            if private_ip_addresses is not None:
                self._values["private_ip_addresses"] = private_ip_addresses
            if secondary_private_ip_address_count is not None:
                self._values["secondary_private_ip_address_count"] = secondary_private_ip_address_count
            if subnet_id is not None:
                self._values["subnet_id"] = subnet_id

        @builtins.property
        def device_index(self) -> builtins.str:
            '''``CfnInstance.NetworkInterfaceProperty.DeviceIndex``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#aws-properties-ec2-network-iface-embedded-deviceindex
            '''
            result = self._values.get("device_index")
            assert result is not None, "Required property 'device_index' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def associate_public_ip_address(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnInstance.NetworkInterfaceProperty.AssociatePublicIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#aws-properties-ec2-network-iface-embedded-associatepubip
            '''
            result = self._values.get("associate_public_ip_address")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def delete_on_termination(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnInstance.NetworkInterfaceProperty.DeleteOnTermination``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#aws-properties-ec2-network-iface-embedded-delete
            '''
            result = self._values.get("delete_on_termination")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def description(self) -> typing.Optional[builtins.str]:
            '''``CfnInstance.NetworkInterfaceProperty.Description``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#aws-properties-ec2-network-iface-embedded-description
            '''
            result = self._values.get("description")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def group_set(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnInstance.NetworkInterfaceProperty.GroupSet``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#aws-properties-ec2-network-iface-embedded-groupset
            '''
            result = self._values.get("group_set")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def ipv6_address_count(self) -> typing.Optional[jsii.Number]:
            '''``CfnInstance.NetworkInterfaceProperty.Ipv6AddressCount``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#cfn-ec2-instance-networkinterface-ipv6addresscount
            '''
            result = self._values.get("ipv6_address_count")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def ipv6_addresses(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.InstanceIpv6AddressProperty"]]]]:
            '''``CfnInstance.NetworkInterfaceProperty.Ipv6Addresses``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#cfn-ec2-instance-networkinterface-ipv6addresses
            '''
            result = self._values.get("ipv6_addresses")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.InstanceIpv6AddressProperty"]]]], result)

        @builtins.property
        def network_interface_id(self) -> typing.Optional[builtins.str]:
            '''``CfnInstance.NetworkInterfaceProperty.NetworkInterfaceId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#aws-properties-ec2-network-iface-embedded-network-iface
            '''
            result = self._values.get("network_interface_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def private_ip_address(self) -> typing.Optional[builtins.str]:
            '''``CfnInstance.NetworkInterfaceProperty.PrivateIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#aws-properties-ec2-network-iface-embedded-privateipaddress
            '''
            result = self._values.get("private_ip_address")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def private_ip_addresses(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.PrivateIpAddressSpecificationProperty"]]]]:
            '''``CfnInstance.NetworkInterfaceProperty.PrivateIpAddresses``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#aws-properties-ec2-network-iface-embedded-privateipaddresses
            '''
            result = self._values.get("private_ip_addresses")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.PrivateIpAddressSpecificationProperty"]]]], result)

        @builtins.property
        def secondary_private_ip_address_count(self) -> typing.Optional[jsii.Number]:
            '''``CfnInstance.NetworkInterfaceProperty.SecondaryPrivateIpAddressCount``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#aws-properties-ec2-network-iface-embedded-secondprivateip
            '''
            result = self._values.get("secondary_private_ip_address_count")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def subnet_id(self) -> typing.Optional[builtins.str]:
            '''``CfnInstance.NetworkInterfaceProperty.SubnetId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#aws-properties-ec2-network-iface-embedded-subnetid
            '''
            result = self._values.get("subnet_id")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "NetworkInterfaceProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.NoDeviceProperty",
        jsii_struct_bases=[],
        name_mapping={},
    )
    class NoDeviceProperty:
        def __init__(self) -> None:
            '''
            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-nodevice.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "NoDeviceProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.PrivateIpAddressSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"primary": "primary", "private_ip_address": "privateIpAddress"},
    )
    class PrivateIpAddressSpecificationProperty:
        def __init__(
            self,
            *,
            primary: typing.Union[builtins.bool, aws_cdk.core.IResolvable],
            private_ip_address: builtins.str,
        ) -> None:
            '''
            :param primary: ``CfnInstance.PrivateIpAddressSpecificationProperty.Primary``.
            :param private_ip_address: ``CfnInstance.PrivateIpAddressSpecificationProperty.PrivateIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "primary": primary,
                "private_ip_address": private_ip_address,
            }

        @builtins.property
        def primary(self) -> typing.Union[builtins.bool, aws_cdk.core.IResolvable]:
            '''``CfnInstance.PrivateIpAddressSpecificationProperty.Primary``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-primary
            '''
            result = self._values.get("primary")
            assert result is not None, "Required property 'primary' is missing"
            return typing.cast(typing.Union[builtins.bool, aws_cdk.core.IResolvable], result)

        @builtins.property
        def private_ip_address(self) -> builtins.str:
            '''``CfnInstance.PrivateIpAddressSpecificationProperty.PrivateIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-privateipaddress
            '''
            result = self._values.get("private_ip_address")
            assert result is not None, "Required property 'private_ip_address' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PrivateIpAddressSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.SsmAssociationProperty",
        jsii_struct_bases=[],
        name_mapping={
            "document_name": "documentName",
            "association_parameters": "associationParameters",
        },
    )
    class SsmAssociationProperty:
        def __init__(
            self,
            *,
            document_name: builtins.str,
            association_parameters: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.AssociationParameterProperty"]]]] = None,
        ) -> None:
            '''
            :param document_name: ``CfnInstance.SsmAssociationProperty.DocumentName``.
            :param association_parameters: ``CfnInstance.SsmAssociationProperty.AssociationParameters``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-ssmassociations.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "document_name": document_name,
            }
            if association_parameters is not None:
                self._values["association_parameters"] = association_parameters

        @builtins.property
        def document_name(self) -> builtins.str:
            '''``CfnInstance.SsmAssociationProperty.DocumentName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-ssmassociations.html#cfn-ec2-instance-ssmassociations-documentname
            '''
            result = self._values.get("document_name")
            assert result is not None, "Required property 'document_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def association_parameters(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.AssociationParameterProperty"]]]]:
            '''``CfnInstance.SsmAssociationProperty.AssociationParameters``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-ssmassociations.html#cfn-ec2-instance-ssmassociations-associationparameters
            '''
            result = self._values.get("association_parameters")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnInstance.AssociationParameterProperty"]]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SsmAssociationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnInstance.VolumeProperty",
        jsii_struct_bases=[],
        name_mapping={"device": "device", "volume_id": "volumeId"},
    )
    class VolumeProperty:
        def __init__(self, *, device: builtins.str, volume_id: builtins.str) -> None:
            '''
            :param device: ``CfnInstance.VolumeProperty.Device``.
            :param volume_id: ``CfnInstance.VolumeProperty.VolumeId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-mount-point.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "device": device,
                "volume_id": volume_id,
            }

        @builtins.property
        def device(self) -> builtins.str:
            '''``CfnInstance.VolumeProperty.Device``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-mount-point.html#cfn-ec2-mountpoint-device
            '''
            result = self._values.get("device")
            assert result is not None, "Required property 'device' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def volume_id(self) -> builtins.str:
            '''``CfnInstance.VolumeProperty.VolumeId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-mount-point.html#cfn-ec2-mountpoint-volumeid
            '''
            result = self._values.get("volume_id")
            assert result is not None, "Required property 'volume_id' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VolumeProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnInstanceProps",
    jsii_struct_bases=[],
    name_mapping={
        "additional_info": "additionalInfo",
        "affinity": "affinity",
        "availability_zone": "availabilityZone",
        "block_device_mappings": "blockDeviceMappings",
        "cpu_options": "cpuOptions",
        "credit_specification": "creditSpecification",
        "disable_api_termination": "disableApiTermination",
        "ebs_optimized": "ebsOptimized",
        "elastic_gpu_specifications": "elasticGpuSpecifications",
        "elastic_inference_accelerators": "elasticInferenceAccelerators",
        "enclave_options": "enclaveOptions",
        "hibernation_options": "hibernationOptions",
        "host_id": "hostId",
        "host_resource_group_arn": "hostResourceGroupArn",
        "iam_instance_profile": "iamInstanceProfile",
        "image_id": "imageId",
        "instance_initiated_shutdown_behavior": "instanceInitiatedShutdownBehavior",
        "instance_type": "instanceType",
        "ipv6_address_count": "ipv6AddressCount",
        "ipv6_addresses": "ipv6Addresses",
        "kernel_id": "kernelId",
        "key_name": "keyName",
        "launch_template": "launchTemplate",
        "license_specifications": "licenseSpecifications",
        "monitoring": "monitoring",
        "network_interfaces": "networkInterfaces",
        "placement_group_name": "placementGroupName",
        "private_ip_address": "privateIpAddress",
        "ramdisk_id": "ramdiskId",
        "security_group_ids": "securityGroupIds",
        "security_groups": "securityGroups",
        "source_dest_check": "sourceDestCheck",
        "ssm_associations": "ssmAssociations",
        "subnet_id": "subnetId",
        "tags": "tags",
        "tenancy": "tenancy",
        "user_data": "userData",
        "volumes": "volumes",
    },
)
class CfnInstanceProps:
    def __init__(
        self,
        *,
        additional_info: typing.Optional[builtins.str] = None,
        affinity: typing.Optional[builtins.str] = None,
        availability_zone: typing.Optional[builtins.str] = None,
        block_device_mappings: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.BlockDeviceMappingProperty]]]] = None,
        cpu_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.CpuOptionsProperty]] = None,
        credit_specification: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.CreditSpecificationProperty]] = None,
        disable_api_termination: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ebs_optimized: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        elastic_gpu_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.ElasticGpuSpecificationProperty]]]] = None,
        elastic_inference_accelerators: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.ElasticInferenceAcceleratorProperty]]]] = None,
        enclave_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.EnclaveOptionsProperty]] = None,
        hibernation_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.HibernationOptionsProperty]] = None,
        host_id: typing.Optional[builtins.str] = None,
        host_resource_group_arn: typing.Optional[builtins.str] = None,
        iam_instance_profile: typing.Optional[builtins.str] = None,
        image_id: typing.Optional[builtins.str] = None,
        instance_initiated_shutdown_behavior: typing.Optional[builtins.str] = None,
        instance_type: typing.Optional[builtins.str] = None,
        ipv6_address_count: typing.Optional[jsii.Number] = None,
        ipv6_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.InstanceIpv6AddressProperty]]]] = None,
        kernel_id: typing.Optional[builtins.str] = None,
        key_name: typing.Optional[builtins.str] = None,
        launch_template: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.LaunchTemplateSpecificationProperty]] = None,
        license_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.LicenseSpecificationProperty]]]] = None,
        monitoring: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        network_interfaces: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.NetworkInterfaceProperty]]]] = None,
        placement_group_name: typing.Optional[builtins.str] = None,
        private_ip_address: typing.Optional[builtins.str] = None,
        ramdisk_id: typing.Optional[builtins.str] = None,
        security_group_ids: typing.Optional[typing.List[builtins.str]] = None,
        security_groups: typing.Optional[typing.List[builtins.str]] = None,
        source_dest_check: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ssm_associations: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.SsmAssociationProperty]]]] = None,
        subnet_id: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        tenancy: typing.Optional[builtins.str] = None,
        user_data: typing.Optional[builtins.str] = None,
        volumes: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.VolumeProperty]]]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::Instance``.

        :param additional_info: ``AWS::EC2::Instance.AdditionalInfo``.
        :param affinity: ``AWS::EC2::Instance.Affinity``.
        :param availability_zone: ``AWS::EC2::Instance.AvailabilityZone``.
        :param block_device_mappings: ``AWS::EC2::Instance.BlockDeviceMappings``.
        :param cpu_options: ``AWS::EC2::Instance.CpuOptions``.
        :param credit_specification: ``AWS::EC2::Instance.CreditSpecification``.
        :param disable_api_termination: ``AWS::EC2::Instance.DisableApiTermination``.
        :param ebs_optimized: ``AWS::EC2::Instance.EbsOptimized``.
        :param elastic_gpu_specifications: ``AWS::EC2::Instance.ElasticGpuSpecifications``.
        :param elastic_inference_accelerators: ``AWS::EC2::Instance.ElasticInferenceAccelerators``.
        :param enclave_options: ``AWS::EC2::Instance.EnclaveOptions``.
        :param hibernation_options: ``AWS::EC2::Instance.HibernationOptions``.
        :param host_id: ``AWS::EC2::Instance.HostId``.
        :param host_resource_group_arn: ``AWS::EC2::Instance.HostResourceGroupArn``.
        :param iam_instance_profile: ``AWS::EC2::Instance.IamInstanceProfile``.
        :param image_id: ``AWS::EC2::Instance.ImageId``.
        :param instance_initiated_shutdown_behavior: ``AWS::EC2::Instance.InstanceInitiatedShutdownBehavior``.
        :param instance_type: ``AWS::EC2::Instance.InstanceType``.
        :param ipv6_address_count: ``AWS::EC2::Instance.Ipv6AddressCount``.
        :param ipv6_addresses: ``AWS::EC2::Instance.Ipv6Addresses``.
        :param kernel_id: ``AWS::EC2::Instance.KernelId``.
        :param key_name: ``AWS::EC2::Instance.KeyName``.
        :param launch_template: ``AWS::EC2::Instance.LaunchTemplate``.
        :param license_specifications: ``AWS::EC2::Instance.LicenseSpecifications``.
        :param monitoring: ``AWS::EC2::Instance.Monitoring``.
        :param network_interfaces: ``AWS::EC2::Instance.NetworkInterfaces``.
        :param placement_group_name: ``AWS::EC2::Instance.PlacementGroupName``.
        :param private_ip_address: ``AWS::EC2::Instance.PrivateIpAddress``.
        :param ramdisk_id: ``AWS::EC2::Instance.RamdiskId``.
        :param security_group_ids: ``AWS::EC2::Instance.SecurityGroupIds``.
        :param security_groups: ``AWS::EC2::Instance.SecurityGroups``.
        :param source_dest_check: ``AWS::EC2::Instance.SourceDestCheck``.
        :param ssm_associations: ``AWS::EC2::Instance.SsmAssociations``.
        :param subnet_id: ``AWS::EC2::Instance.SubnetId``.
        :param tags: ``AWS::EC2::Instance.Tags``.
        :param tenancy: ``AWS::EC2::Instance.Tenancy``.
        :param user_data: ``AWS::EC2::Instance.UserData``.
        :param volumes: ``AWS::EC2::Instance.Volumes``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if additional_info is not None:
            self._values["additional_info"] = additional_info
        if affinity is not None:
            self._values["affinity"] = affinity
        if availability_zone is not None:
            self._values["availability_zone"] = availability_zone
        if block_device_mappings is not None:
            self._values["block_device_mappings"] = block_device_mappings
        if cpu_options is not None:
            self._values["cpu_options"] = cpu_options
        if credit_specification is not None:
            self._values["credit_specification"] = credit_specification
        if disable_api_termination is not None:
            self._values["disable_api_termination"] = disable_api_termination
        if ebs_optimized is not None:
            self._values["ebs_optimized"] = ebs_optimized
        if elastic_gpu_specifications is not None:
            self._values["elastic_gpu_specifications"] = elastic_gpu_specifications
        if elastic_inference_accelerators is not None:
            self._values["elastic_inference_accelerators"] = elastic_inference_accelerators
        if enclave_options is not None:
            self._values["enclave_options"] = enclave_options
        if hibernation_options is not None:
            self._values["hibernation_options"] = hibernation_options
        if host_id is not None:
            self._values["host_id"] = host_id
        if host_resource_group_arn is not None:
            self._values["host_resource_group_arn"] = host_resource_group_arn
        if iam_instance_profile is not None:
            self._values["iam_instance_profile"] = iam_instance_profile
        if image_id is not None:
            self._values["image_id"] = image_id
        if instance_initiated_shutdown_behavior is not None:
            self._values["instance_initiated_shutdown_behavior"] = instance_initiated_shutdown_behavior
        if instance_type is not None:
            self._values["instance_type"] = instance_type
        if ipv6_address_count is not None:
            self._values["ipv6_address_count"] = ipv6_address_count
        if ipv6_addresses is not None:
            self._values["ipv6_addresses"] = ipv6_addresses
        if kernel_id is not None:
            self._values["kernel_id"] = kernel_id
        if key_name is not None:
            self._values["key_name"] = key_name
        if launch_template is not None:
            self._values["launch_template"] = launch_template
        if license_specifications is not None:
            self._values["license_specifications"] = license_specifications
        if monitoring is not None:
            self._values["monitoring"] = monitoring
        if network_interfaces is not None:
            self._values["network_interfaces"] = network_interfaces
        if placement_group_name is not None:
            self._values["placement_group_name"] = placement_group_name
        if private_ip_address is not None:
            self._values["private_ip_address"] = private_ip_address
        if ramdisk_id is not None:
            self._values["ramdisk_id"] = ramdisk_id
        if security_group_ids is not None:
            self._values["security_group_ids"] = security_group_ids
        if security_groups is not None:
            self._values["security_groups"] = security_groups
        if source_dest_check is not None:
            self._values["source_dest_check"] = source_dest_check
        if ssm_associations is not None:
            self._values["ssm_associations"] = ssm_associations
        if subnet_id is not None:
            self._values["subnet_id"] = subnet_id
        if tags is not None:
            self._values["tags"] = tags
        if tenancy is not None:
            self._values["tenancy"] = tenancy
        if user_data is not None:
            self._values["user_data"] = user_data
        if volumes is not None:
            self._values["volumes"] = volumes

    @builtins.property
    def additional_info(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.AdditionalInfo``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-additionalinfo
        '''
        result = self._values.get("additional_info")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def affinity(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.Affinity``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-affinity
        '''
        result = self._values.get("affinity")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def availability_zone(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-availabilityzone
        '''
        result = self._values.get("availability_zone")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def block_device_mappings(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.BlockDeviceMappingProperty]]]]:
        '''``AWS::EC2::Instance.BlockDeviceMappings``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-blockdevicemappings
        '''
        result = self._values.get("block_device_mappings")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.BlockDeviceMappingProperty]]]], result)

    @builtins.property
    def cpu_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.CpuOptionsProperty]]:
        '''``AWS::EC2::Instance.CpuOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-cpuoptions
        '''
        result = self._values.get("cpu_options")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.CpuOptionsProperty]], result)

    @builtins.property
    def credit_specification(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.CreditSpecificationProperty]]:
        '''``AWS::EC2::Instance.CreditSpecification``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-creditspecification
        '''
        result = self._values.get("credit_specification")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.CreditSpecificationProperty]], result)

    @builtins.property
    def disable_api_termination(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Instance.DisableApiTermination``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-disableapitermination
        '''
        result = self._values.get("disable_api_termination")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def ebs_optimized(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Instance.EbsOptimized``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-ebsoptimized
        '''
        result = self._values.get("ebs_optimized")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def elastic_gpu_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.ElasticGpuSpecificationProperty]]]]:
        '''``AWS::EC2::Instance.ElasticGpuSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-elasticgpuspecifications
        '''
        result = self._values.get("elastic_gpu_specifications")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.ElasticGpuSpecificationProperty]]]], result)

    @builtins.property
    def elastic_inference_accelerators(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.ElasticInferenceAcceleratorProperty]]]]:
        '''``AWS::EC2::Instance.ElasticInferenceAccelerators``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-elasticinferenceaccelerators
        '''
        result = self._values.get("elastic_inference_accelerators")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.ElasticInferenceAcceleratorProperty]]]], result)

    @builtins.property
    def enclave_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.EnclaveOptionsProperty]]:
        '''``AWS::EC2::Instance.EnclaveOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-enclaveoptions
        '''
        result = self._values.get("enclave_options")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.EnclaveOptionsProperty]], result)

    @builtins.property
    def hibernation_options(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.HibernationOptionsProperty]]:
        '''``AWS::EC2::Instance.HibernationOptions``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-hibernationoptions
        '''
        result = self._values.get("hibernation_options")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.HibernationOptionsProperty]], result)

    @builtins.property
    def host_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.HostId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-hostid
        '''
        result = self._values.get("host_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def host_resource_group_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.HostResourceGroupArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-hostresourcegrouparn
        '''
        result = self._values.get("host_resource_group_arn")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def iam_instance_profile(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.IamInstanceProfile``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-iaminstanceprofile
        '''
        result = self._values.get("iam_instance_profile")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def image_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.ImageId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-imageid
        '''
        result = self._values.get("image_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def instance_initiated_shutdown_behavior(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.InstanceInitiatedShutdownBehavior``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-instanceinitiatedshutdownbehavior
        '''
        result = self._values.get("instance_initiated_shutdown_behavior")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def instance_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.InstanceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-instancetype
        '''
        result = self._values.get("instance_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ipv6_address_count(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::Instance.Ipv6AddressCount``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-ipv6addresscount
        '''
        result = self._values.get("ipv6_address_count")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def ipv6_addresses(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.InstanceIpv6AddressProperty]]]]:
        '''``AWS::EC2::Instance.Ipv6Addresses``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-ipv6addresses
        '''
        result = self._values.get("ipv6_addresses")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.InstanceIpv6AddressProperty]]]], result)

    @builtins.property
    def kernel_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.KernelId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-kernelid
        '''
        result = self._values.get("kernel_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def key_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.KeyName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-keyname
        '''
        result = self._values.get("key_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def launch_template(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.LaunchTemplateSpecificationProperty]]:
        '''``AWS::EC2::Instance.LaunchTemplate``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-launchtemplate
        '''
        result = self._values.get("launch_template")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnInstance.LaunchTemplateSpecificationProperty]], result)

    @builtins.property
    def license_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.LicenseSpecificationProperty]]]]:
        '''``AWS::EC2::Instance.LicenseSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-licensespecifications
        '''
        result = self._values.get("license_specifications")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.LicenseSpecificationProperty]]]], result)

    @builtins.property
    def monitoring(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Instance.Monitoring``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-monitoring
        '''
        result = self._values.get("monitoring")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def network_interfaces(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.NetworkInterfaceProperty]]]]:
        '''``AWS::EC2::Instance.NetworkInterfaces``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-networkinterfaces
        '''
        result = self._values.get("network_interfaces")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.NetworkInterfaceProperty]]]], result)

    @builtins.property
    def placement_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.PlacementGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-placementgroupname
        '''
        result = self._values.get("placement_group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def private_ip_address(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.PrivateIpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-privateipaddress
        '''
        result = self._values.get("private_ip_address")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ramdisk_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.RamdiskId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-ramdiskid
        '''
        result = self._values.get("ramdisk_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def security_group_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::Instance.SecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-securitygroupids
        '''
        result = self._values.get("security_group_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def security_groups(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::Instance.SecurityGroups``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-securitygroups
        '''
        result = self._values.get("security_groups")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def source_dest_check(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Instance.SourceDestCheck``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-sourcedestcheck
        '''
        result = self._values.get("source_dest_check")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def ssm_associations(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.SsmAssociationProperty]]]]:
        '''``AWS::EC2::Instance.SsmAssociations``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-ssmassociations
        '''
        result = self._values.get("ssm_associations")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.SsmAssociationProperty]]]], result)

    @builtins.property
    def subnet_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-subnetid
        '''
        result = self._values.get("subnet_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::Instance.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    @builtins.property
    def tenancy(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.Tenancy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-tenancy
        '''
        result = self._values.get("tenancy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def user_data(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Instance.UserData``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-userdata
        '''
        result = self._values.get("user_data")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def volumes(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.VolumeProperty]]]]:
        '''``AWS::EC2::Instance.Volumes``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-volumes
        '''
        result = self._values.get("volumes")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnInstance.VolumeProperty]]]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnInstanceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnInternetGateway(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnInternetGateway",
):
    '''A CloudFormation ``AWS::EC2::InternetGateway``.

    :cloudformationResource: AWS::EC2::InternetGateway
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::InternetGateway``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param tags: ``AWS::EC2::InternetGateway.Tags``.
        '''
        props = CfnInternetGatewayProps(tags=tags)

        jsii.create(CfnInternetGateway, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::InternetGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html#cfn-ec2-internetgateway-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnInternetGatewayProps",
    jsii_struct_bases=[],
    name_mapping={"tags": "tags"},
)
class CfnInternetGatewayProps:
    def __init__(
        self,
        *,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::InternetGateway``.

        :param tags: ``AWS::EC2::InternetGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::InternetGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html#cfn-ec2-internetgateway-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnInternetGatewayProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnLaunchTemplate(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate",
):
    '''A CloudFormation ``AWS::EC2::LaunchTemplate``.

    :cloudformationResource: AWS::EC2::LaunchTemplate
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-launchtemplate.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        launch_template_data: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.LaunchTemplateDataProperty"]] = None,
        launch_template_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::LaunchTemplate``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param launch_template_data: ``AWS::EC2::LaunchTemplate.LaunchTemplateData``.
        :param launch_template_name: ``AWS::EC2::LaunchTemplate.LaunchTemplateName``.
        '''
        props = CfnLaunchTemplateProps(
            launch_template_data=launch_template_data,
            launch_template_name=launch_template_name,
        )

        jsii.create(CfnLaunchTemplate, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrDefaultVersionNumber")
    def attr_default_version_number(self) -> builtins.str:
        '''
        :cloudformationAttribute: DefaultVersionNumber
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrDefaultVersionNumber"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrLatestVersionNumber")
    def attr_latest_version_number(self) -> builtins.str:
        '''
        :cloudformationAttribute: LatestVersionNumber
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrLatestVersionNumber"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="launchTemplateData")
    def launch_template_data(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.LaunchTemplateDataProperty"]]:
        '''``AWS::EC2::LaunchTemplate.LaunchTemplateData``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-launchtemplate.html#cfn-ec2-launchtemplate-launchtemplatedata
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.LaunchTemplateDataProperty"]], jsii.get(self, "launchTemplateData"))

    @launch_template_data.setter
    def launch_template_data(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.LaunchTemplateDataProperty"]],
    ) -> None:
        jsii.set(self, "launchTemplateData", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="launchTemplateName")
    def launch_template_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::LaunchTemplate.LaunchTemplateName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-launchtemplate.html#cfn-ec2-launchtemplate-launchtemplatename
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "launchTemplateName"))

    @launch_template_name.setter
    def launch_template_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "launchTemplateName", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.BlockDeviceMappingProperty",
        jsii_struct_bases=[],
        name_mapping={
            "device_name": "deviceName",
            "ebs": "ebs",
            "no_device": "noDevice",
            "virtual_name": "virtualName",
        },
    )
    class BlockDeviceMappingProperty:
        def __init__(
            self,
            *,
            device_name: typing.Optional[builtins.str] = None,
            ebs: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.EbsProperty"]] = None,
            no_device: typing.Optional[builtins.str] = None,
            virtual_name: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param device_name: ``CfnLaunchTemplate.BlockDeviceMappingProperty.DeviceName``.
            :param ebs: ``CfnLaunchTemplate.BlockDeviceMappingProperty.Ebs``.
            :param no_device: ``CfnLaunchTemplate.BlockDeviceMappingProperty.NoDevice``.
            :param virtual_name: ``CfnLaunchTemplate.BlockDeviceMappingProperty.VirtualName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if device_name is not None:
                self._values["device_name"] = device_name
            if ebs is not None:
                self._values["ebs"] = ebs
            if no_device is not None:
                self._values["no_device"] = no_device
            if virtual_name is not None:
                self._values["virtual_name"] = virtual_name

        @builtins.property
        def device_name(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.BlockDeviceMappingProperty.DeviceName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping.html#cfn-ec2-launchtemplate-blockdevicemapping-devicename
            '''
            result = self._values.get("device_name")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def ebs(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.EbsProperty"]]:
            '''``CfnLaunchTemplate.BlockDeviceMappingProperty.Ebs``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping.html#cfn-ec2-launchtemplate-blockdevicemapping-ebs
            '''
            result = self._values.get("ebs")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.EbsProperty"]], result)

        @builtins.property
        def no_device(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.BlockDeviceMappingProperty.NoDevice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping.html#cfn-ec2-launchtemplate-blockdevicemapping-nodevice
            '''
            result = self._values.get("no_device")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def virtual_name(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.BlockDeviceMappingProperty.VirtualName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping.html#cfn-ec2-launchtemplate-blockdevicemapping-virtualname
            '''
            result = self._values.get("virtual_name")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "BlockDeviceMappingProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.CapacityReservationSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={
            "capacity_reservation_preference": "capacityReservationPreference",
            "capacity_reservation_target": "capacityReservationTarget",
        },
    )
    class CapacityReservationSpecificationProperty:
        def __init__(
            self,
            *,
            capacity_reservation_preference: typing.Optional[builtins.str] = None,
            capacity_reservation_target: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CapacityReservationTargetProperty"]] = None,
        ) -> None:
            '''
            :param capacity_reservation_preference: ``CfnLaunchTemplate.CapacityReservationSpecificationProperty.CapacityReservationPreference``.
            :param capacity_reservation_target: ``CfnLaunchTemplate.CapacityReservationSpecificationProperty.CapacityReservationTarget``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-capacityreservationspecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if capacity_reservation_preference is not None:
                self._values["capacity_reservation_preference"] = capacity_reservation_preference
            if capacity_reservation_target is not None:
                self._values["capacity_reservation_target"] = capacity_reservation_target

        @builtins.property
        def capacity_reservation_preference(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.CapacityReservationSpecificationProperty.CapacityReservationPreference``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-capacityreservationspecification.html#cfn-ec2-launchtemplate-launchtemplatedata-capacityreservationspecification-capacityreservationpreference
            '''
            result = self._values.get("capacity_reservation_preference")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def capacity_reservation_target(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CapacityReservationTargetProperty"]]:
            '''``CfnLaunchTemplate.CapacityReservationSpecificationProperty.CapacityReservationTarget``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-capacityreservationspecification.html#cfn-ec2-launchtemplate-launchtemplatedata-capacityreservationspecification-capacityreservationtarget
            '''
            result = self._values.get("capacity_reservation_target")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CapacityReservationTargetProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CapacityReservationSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.CapacityReservationTargetProperty",
        jsii_struct_bases=[],
        name_mapping={
            "capacity_reservation_id": "capacityReservationId",
            "capacity_reservation_resource_group_arn": "capacityReservationResourceGroupArn",
        },
    )
    class CapacityReservationTargetProperty:
        def __init__(
            self,
            *,
            capacity_reservation_id: typing.Optional[builtins.str] = None,
            capacity_reservation_resource_group_arn: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param capacity_reservation_id: ``CfnLaunchTemplate.CapacityReservationTargetProperty.CapacityReservationId``.
            :param capacity_reservation_resource_group_arn: ``CfnLaunchTemplate.CapacityReservationTargetProperty.CapacityReservationResourceGroupArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-capacityreservationtarget.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if capacity_reservation_id is not None:
                self._values["capacity_reservation_id"] = capacity_reservation_id
            if capacity_reservation_resource_group_arn is not None:
                self._values["capacity_reservation_resource_group_arn"] = capacity_reservation_resource_group_arn

        @builtins.property
        def capacity_reservation_id(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.CapacityReservationTargetProperty.CapacityReservationId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-capacityreservationtarget.html#cfn-ec2-launchtemplate-capacityreservationtarget-capacityreservationid
            '''
            result = self._values.get("capacity_reservation_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def capacity_reservation_resource_group_arn(
            self,
        ) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.CapacityReservationTargetProperty.CapacityReservationResourceGroupArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-capacityreservationtarget.html#cfn-ec2-launchtemplate-capacityreservationtarget-capacityreservationresourcegrouparn
            '''
            result = self._values.get("capacity_reservation_resource_group_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CapacityReservationTargetProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.CpuOptionsProperty",
        jsii_struct_bases=[],
        name_mapping={"core_count": "coreCount", "threads_per_core": "threadsPerCore"},
    )
    class CpuOptionsProperty:
        def __init__(
            self,
            *,
            core_count: typing.Optional[jsii.Number] = None,
            threads_per_core: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param core_count: ``CfnLaunchTemplate.CpuOptionsProperty.CoreCount``.
            :param threads_per_core: ``CfnLaunchTemplate.CpuOptionsProperty.ThreadsPerCore``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-cpuoptions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if core_count is not None:
                self._values["core_count"] = core_count
            if threads_per_core is not None:
                self._values["threads_per_core"] = threads_per_core

        @builtins.property
        def core_count(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.CpuOptionsProperty.CoreCount``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-cpuoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-cpuoptions-corecount
            '''
            result = self._values.get("core_count")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def threads_per_core(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.CpuOptionsProperty.ThreadsPerCore``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-cpuoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-cpuoptions-threadspercore
            '''
            result = self._values.get("threads_per_core")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CpuOptionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.CreditSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"cpu_credits": "cpuCredits"},
    )
    class CreditSpecificationProperty:
        def __init__(
            self,
            *,
            cpu_credits: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param cpu_credits: ``CfnLaunchTemplate.CreditSpecificationProperty.CpuCredits``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-creditspecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if cpu_credits is not None:
                self._values["cpu_credits"] = cpu_credits

        @builtins.property
        def cpu_credits(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.CreditSpecificationProperty.CpuCredits``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-creditspecification.html#cfn-ec2-launchtemplate-launchtemplatedata-creditspecification-cpucredits
            '''
            result = self._values.get("cpu_credits")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CreditSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.EbsProperty",
        jsii_struct_bases=[],
        name_mapping={
            "delete_on_termination": "deleteOnTermination",
            "encrypted": "encrypted",
            "iops": "iops",
            "kms_key_id": "kmsKeyId",
            "snapshot_id": "snapshotId",
            "throughput": "throughput",
            "volume_size": "volumeSize",
            "volume_type": "volumeType",
        },
    )
    class EbsProperty:
        def __init__(
            self,
            *,
            delete_on_termination: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            encrypted: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            iops: typing.Optional[jsii.Number] = None,
            kms_key_id: typing.Optional[builtins.str] = None,
            snapshot_id: typing.Optional[builtins.str] = None,
            throughput: typing.Optional[jsii.Number] = None,
            volume_size: typing.Optional[jsii.Number] = None,
            volume_type: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param delete_on_termination: ``CfnLaunchTemplate.EbsProperty.DeleteOnTermination``.
            :param encrypted: ``CfnLaunchTemplate.EbsProperty.Encrypted``.
            :param iops: ``CfnLaunchTemplate.EbsProperty.Iops``.
            :param kms_key_id: ``CfnLaunchTemplate.EbsProperty.KmsKeyId``.
            :param snapshot_id: ``CfnLaunchTemplate.EbsProperty.SnapshotId``.
            :param throughput: ``CfnLaunchTemplate.EbsProperty.Throughput``.
            :param volume_size: ``CfnLaunchTemplate.EbsProperty.VolumeSize``.
            :param volume_type: ``CfnLaunchTemplate.EbsProperty.VolumeType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping-ebs.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if delete_on_termination is not None:
                self._values["delete_on_termination"] = delete_on_termination
            if encrypted is not None:
                self._values["encrypted"] = encrypted
            if iops is not None:
                self._values["iops"] = iops
            if kms_key_id is not None:
                self._values["kms_key_id"] = kms_key_id
            if snapshot_id is not None:
                self._values["snapshot_id"] = snapshot_id
            if throughput is not None:
                self._values["throughput"] = throughput
            if volume_size is not None:
                self._values["volume_size"] = volume_size
            if volume_type is not None:
                self._values["volume_type"] = volume_type

        @builtins.property
        def delete_on_termination(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnLaunchTemplate.EbsProperty.DeleteOnTermination``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping-ebs.html#cfn-ec2-launchtemplate-blockdevicemapping-ebs-deleteontermination
            '''
            result = self._values.get("delete_on_termination")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def encrypted(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnLaunchTemplate.EbsProperty.Encrypted``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping-ebs.html#cfn-ec2-launchtemplate-blockdevicemapping-ebs-encrypted
            '''
            result = self._values.get("encrypted")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def iops(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.EbsProperty.Iops``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping-ebs.html#cfn-ec2-launchtemplate-blockdevicemapping-ebs-iops
            '''
            result = self._values.get("iops")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def kms_key_id(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.EbsProperty.KmsKeyId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping-ebs.html#cfn-ec2-launchtemplate-blockdevicemapping-ebs-kmskeyid
            '''
            result = self._values.get("kms_key_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def snapshot_id(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.EbsProperty.SnapshotId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping-ebs.html#cfn-ec2-launchtemplate-blockdevicemapping-ebs-snapshotid
            '''
            result = self._values.get("snapshot_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def throughput(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.EbsProperty.Throughput``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping-ebs.html#cfn-ec2-launchtemplate-blockdevicemapping-ebs-throughput
            '''
            result = self._values.get("throughput")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def volume_size(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.EbsProperty.VolumeSize``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping-ebs.html#cfn-ec2-launchtemplate-blockdevicemapping-ebs-volumesize
            '''
            result = self._values.get("volume_size")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def volume_type(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.EbsProperty.VolumeType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-blockdevicemapping-ebs.html#cfn-ec2-launchtemplate-blockdevicemapping-ebs-volumetype
            '''
            result = self._values.get("volume_type")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "EbsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.ElasticGpuSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"type": "type"},
    )
    class ElasticGpuSpecificationProperty:
        def __init__(self, *, type: typing.Optional[builtins.str] = None) -> None:
            '''
            :param type: ``CfnLaunchTemplate.ElasticGpuSpecificationProperty.Type``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-elasticgpuspecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if type is not None:
                self._values["type"] = type

        @builtins.property
        def type(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.ElasticGpuSpecificationProperty.Type``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-elasticgpuspecification.html#cfn-ec2-launchtemplate-elasticgpuspecification-type
            '''
            result = self._values.get("type")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ElasticGpuSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.EnclaveOptionsProperty",
        jsii_struct_bases=[],
        name_mapping={"enabled": "enabled"},
    )
    class EnclaveOptionsProperty:
        def __init__(
            self,
            *,
            enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ) -> None:
            '''
            :param enabled: ``CfnLaunchTemplate.EnclaveOptionsProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-enclaveoptions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if enabled is not None:
                self._values["enabled"] = enabled

        @builtins.property
        def enabled(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnLaunchTemplate.EnclaveOptionsProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-enclaveoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-enclaveoptions-enabled
            '''
            result = self._values.get("enabled")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "EnclaveOptionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.HibernationOptionsProperty",
        jsii_struct_bases=[],
        name_mapping={"configured": "configured"},
    )
    class HibernationOptionsProperty:
        def __init__(
            self,
            *,
            configured: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ) -> None:
            '''
            :param configured: ``CfnLaunchTemplate.HibernationOptionsProperty.Configured``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-hibernationoptions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if configured is not None:
                self._values["configured"] = configured

        @builtins.property
        def configured(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnLaunchTemplate.HibernationOptionsProperty.Configured``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-hibernationoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-hibernationoptions-configured
            '''
            result = self._values.get("configured")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HibernationOptionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.IamInstanceProfileProperty",
        jsii_struct_bases=[],
        name_mapping={"arn": "arn", "name": "name"},
    )
    class IamInstanceProfileProperty:
        def __init__(
            self,
            *,
            arn: typing.Optional[builtins.str] = None,
            name: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param arn: ``CfnLaunchTemplate.IamInstanceProfileProperty.Arn``.
            :param name: ``CfnLaunchTemplate.IamInstanceProfileProperty.Name``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-iaminstanceprofile.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if arn is not None:
                self._values["arn"] = arn
            if name is not None:
                self._values["name"] = name

        @builtins.property
        def arn(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.IamInstanceProfileProperty.Arn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-iaminstanceprofile.html#cfn-ec2-launchtemplate-launchtemplatedata-iaminstanceprofile-arn
            '''
            result = self._values.get("arn")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def name(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.IamInstanceProfileProperty.Name``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-iaminstanceprofile.html#cfn-ec2-launchtemplate-launchtemplatedata-iaminstanceprofile-name
            '''
            result = self._values.get("name")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "IamInstanceProfileProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.InstanceMarketOptionsProperty",
        jsii_struct_bases=[],
        name_mapping={"market_type": "marketType", "spot_options": "spotOptions"},
    )
    class InstanceMarketOptionsProperty:
        def __init__(
            self,
            *,
            market_type: typing.Optional[builtins.str] = None,
            spot_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.SpotOptionsProperty"]] = None,
        ) -> None:
            '''
            :param market_type: ``CfnLaunchTemplate.InstanceMarketOptionsProperty.MarketType``.
            :param spot_options: ``CfnLaunchTemplate.InstanceMarketOptionsProperty.SpotOptions``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-instancemarketoptions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if market_type is not None:
                self._values["market_type"] = market_type
            if spot_options is not None:
                self._values["spot_options"] = spot_options

        @builtins.property
        def market_type(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.InstanceMarketOptionsProperty.MarketType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-instancemarketoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-markettype
            '''
            result = self._values.get("market_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def spot_options(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.SpotOptionsProperty"]]:
            '''``CfnLaunchTemplate.InstanceMarketOptionsProperty.SpotOptions``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-instancemarketoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions
            '''
            result = self._values.get("spot_options")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.SpotOptionsProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "InstanceMarketOptionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.Ipv6AddProperty",
        jsii_struct_bases=[],
        name_mapping={"ipv6_address": "ipv6Address"},
    )
    class Ipv6AddProperty:
        def __init__(
            self,
            *,
            ipv6_address: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param ipv6_address: ``CfnLaunchTemplate.Ipv6AddProperty.Ipv6Address``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-ipv6add.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if ipv6_address is not None:
                self._values["ipv6_address"] = ipv6_address

        @builtins.property
        def ipv6_address(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.Ipv6AddProperty.Ipv6Address``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-ipv6add.html#cfn-ec2-launchtemplate-ipv6add-ipv6address
            '''
            result = self._values.get("ipv6_address")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "Ipv6AddProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.LaunchTemplateDataProperty",
        jsii_struct_bases=[],
        name_mapping={
            "block_device_mappings": "blockDeviceMappings",
            "capacity_reservation_specification": "capacityReservationSpecification",
            "cpu_options": "cpuOptions",
            "credit_specification": "creditSpecification",
            "disable_api_termination": "disableApiTermination",
            "ebs_optimized": "ebsOptimized",
            "elastic_gpu_specifications": "elasticGpuSpecifications",
            "elastic_inference_accelerators": "elasticInferenceAccelerators",
            "enclave_options": "enclaveOptions",
            "hibernation_options": "hibernationOptions",
            "iam_instance_profile": "iamInstanceProfile",
            "image_id": "imageId",
            "instance_initiated_shutdown_behavior": "instanceInitiatedShutdownBehavior",
            "instance_market_options": "instanceMarketOptions",
            "instance_type": "instanceType",
            "kernel_id": "kernelId",
            "key_name": "keyName",
            "license_specifications": "licenseSpecifications",
            "metadata_options": "metadataOptions",
            "monitoring": "monitoring",
            "network_interfaces": "networkInterfaces",
            "placement": "placement",
            "ram_disk_id": "ramDiskId",
            "security_group_ids": "securityGroupIds",
            "security_groups": "securityGroups",
            "tag_specifications": "tagSpecifications",
            "user_data": "userData",
        },
    )
    class LaunchTemplateDataProperty:
        def __init__(
            self,
            *,
            block_device_mappings: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.BlockDeviceMappingProperty"]]]] = None,
            capacity_reservation_specification: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CapacityReservationSpecificationProperty"]] = None,
            cpu_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CpuOptionsProperty"]] = None,
            credit_specification: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CreditSpecificationProperty"]] = None,
            disable_api_termination: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            ebs_optimized: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            elastic_gpu_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.ElasticGpuSpecificationProperty"]]]] = None,
            elastic_inference_accelerators: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.LaunchTemplateElasticInferenceAcceleratorProperty"]]]] = None,
            enclave_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.EnclaveOptionsProperty"]] = None,
            hibernation_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.HibernationOptionsProperty"]] = None,
            iam_instance_profile: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.IamInstanceProfileProperty"]] = None,
            image_id: typing.Optional[builtins.str] = None,
            instance_initiated_shutdown_behavior: typing.Optional[builtins.str] = None,
            instance_market_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.InstanceMarketOptionsProperty"]] = None,
            instance_type: typing.Optional[builtins.str] = None,
            kernel_id: typing.Optional[builtins.str] = None,
            key_name: typing.Optional[builtins.str] = None,
            license_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.LicenseSpecificationProperty"]]]] = None,
            metadata_options: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.MetadataOptionsProperty"]] = None,
            monitoring: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.MonitoringProperty"]] = None,
            network_interfaces: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.NetworkInterfaceProperty"]]]] = None,
            placement: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.PlacementProperty"]] = None,
            ram_disk_id: typing.Optional[builtins.str] = None,
            security_group_ids: typing.Optional[typing.List[builtins.str]] = None,
            security_groups: typing.Optional[typing.List[builtins.str]] = None,
            tag_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.TagSpecificationProperty"]]]] = None,
            user_data: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param block_device_mappings: ``CfnLaunchTemplate.LaunchTemplateDataProperty.BlockDeviceMappings``.
            :param capacity_reservation_specification: ``CfnLaunchTemplate.LaunchTemplateDataProperty.CapacityReservationSpecification``.
            :param cpu_options: ``CfnLaunchTemplate.LaunchTemplateDataProperty.CpuOptions``.
            :param credit_specification: ``CfnLaunchTemplate.LaunchTemplateDataProperty.CreditSpecification``.
            :param disable_api_termination: ``CfnLaunchTemplate.LaunchTemplateDataProperty.DisableApiTermination``.
            :param ebs_optimized: ``CfnLaunchTemplate.LaunchTemplateDataProperty.EbsOptimized``.
            :param elastic_gpu_specifications: ``CfnLaunchTemplate.LaunchTemplateDataProperty.ElasticGpuSpecifications``.
            :param elastic_inference_accelerators: ``CfnLaunchTemplate.LaunchTemplateDataProperty.ElasticInferenceAccelerators``.
            :param enclave_options: ``CfnLaunchTemplate.LaunchTemplateDataProperty.EnclaveOptions``.
            :param hibernation_options: ``CfnLaunchTemplate.LaunchTemplateDataProperty.HibernationOptions``.
            :param iam_instance_profile: ``CfnLaunchTemplate.LaunchTemplateDataProperty.IamInstanceProfile``.
            :param image_id: ``CfnLaunchTemplate.LaunchTemplateDataProperty.ImageId``.
            :param instance_initiated_shutdown_behavior: ``CfnLaunchTemplate.LaunchTemplateDataProperty.InstanceInitiatedShutdownBehavior``.
            :param instance_market_options: ``CfnLaunchTemplate.LaunchTemplateDataProperty.InstanceMarketOptions``.
            :param instance_type: ``CfnLaunchTemplate.LaunchTemplateDataProperty.InstanceType``.
            :param kernel_id: ``CfnLaunchTemplate.LaunchTemplateDataProperty.KernelId``.
            :param key_name: ``CfnLaunchTemplate.LaunchTemplateDataProperty.KeyName``.
            :param license_specifications: ``CfnLaunchTemplate.LaunchTemplateDataProperty.LicenseSpecifications``.
            :param metadata_options: ``CfnLaunchTemplate.LaunchTemplateDataProperty.MetadataOptions``.
            :param monitoring: ``CfnLaunchTemplate.LaunchTemplateDataProperty.Monitoring``.
            :param network_interfaces: ``CfnLaunchTemplate.LaunchTemplateDataProperty.NetworkInterfaces``.
            :param placement: ``CfnLaunchTemplate.LaunchTemplateDataProperty.Placement``.
            :param ram_disk_id: ``CfnLaunchTemplate.LaunchTemplateDataProperty.RamDiskId``.
            :param security_group_ids: ``CfnLaunchTemplate.LaunchTemplateDataProperty.SecurityGroupIds``.
            :param security_groups: ``CfnLaunchTemplate.LaunchTemplateDataProperty.SecurityGroups``.
            :param tag_specifications: ``CfnLaunchTemplate.LaunchTemplateDataProperty.TagSpecifications``.
            :param user_data: ``CfnLaunchTemplate.LaunchTemplateDataProperty.UserData``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if block_device_mappings is not None:
                self._values["block_device_mappings"] = block_device_mappings
            if capacity_reservation_specification is not None:
                self._values["capacity_reservation_specification"] = capacity_reservation_specification
            if cpu_options is not None:
                self._values["cpu_options"] = cpu_options
            if credit_specification is not None:
                self._values["credit_specification"] = credit_specification
            if disable_api_termination is not None:
                self._values["disable_api_termination"] = disable_api_termination
            if ebs_optimized is not None:
                self._values["ebs_optimized"] = ebs_optimized
            if elastic_gpu_specifications is not None:
                self._values["elastic_gpu_specifications"] = elastic_gpu_specifications
            if elastic_inference_accelerators is not None:
                self._values["elastic_inference_accelerators"] = elastic_inference_accelerators
            if enclave_options is not None:
                self._values["enclave_options"] = enclave_options
            if hibernation_options is not None:
                self._values["hibernation_options"] = hibernation_options
            if iam_instance_profile is not None:
                self._values["iam_instance_profile"] = iam_instance_profile
            if image_id is not None:
                self._values["image_id"] = image_id
            if instance_initiated_shutdown_behavior is not None:
                self._values["instance_initiated_shutdown_behavior"] = instance_initiated_shutdown_behavior
            if instance_market_options is not None:
                self._values["instance_market_options"] = instance_market_options
            if instance_type is not None:
                self._values["instance_type"] = instance_type
            if kernel_id is not None:
                self._values["kernel_id"] = kernel_id
            if key_name is not None:
                self._values["key_name"] = key_name
            if license_specifications is not None:
                self._values["license_specifications"] = license_specifications
            if metadata_options is not None:
                self._values["metadata_options"] = metadata_options
            if monitoring is not None:
                self._values["monitoring"] = monitoring
            if network_interfaces is not None:
                self._values["network_interfaces"] = network_interfaces
            if placement is not None:
                self._values["placement"] = placement
            if ram_disk_id is not None:
                self._values["ram_disk_id"] = ram_disk_id
            if security_group_ids is not None:
                self._values["security_group_ids"] = security_group_ids
            if security_groups is not None:
                self._values["security_groups"] = security_groups
            if tag_specifications is not None:
                self._values["tag_specifications"] = tag_specifications
            if user_data is not None:
                self._values["user_data"] = user_data

        @builtins.property
        def block_device_mappings(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.BlockDeviceMappingProperty"]]]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.BlockDeviceMappings``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-blockdevicemappings
            '''
            result = self._values.get("block_device_mappings")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.BlockDeviceMappingProperty"]]]], result)

        @builtins.property
        def capacity_reservation_specification(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CapacityReservationSpecificationProperty"]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.CapacityReservationSpecification``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-capacityreservationspecification
            '''
            result = self._values.get("capacity_reservation_specification")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CapacityReservationSpecificationProperty"]], result)

        @builtins.property
        def cpu_options(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CpuOptionsProperty"]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.CpuOptions``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-cpuoptions
            '''
            result = self._values.get("cpu_options")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CpuOptionsProperty"]], result)

        @builtins.property
        def credit_specification(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CreditSpecificationProperty"]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.CreditSpecification``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-creditspecification
            '''
            result = self._values.get("credit_specification")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.CreditSpecificationProperty"]], result)

        @builtins.property
        def disable_api_termination(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.DisableApiTermination``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-disableapitermination
            '''
            result = self._values.get("disable_api_termination")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def ebs_optimized(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.EbsOptimized``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-ebsoptimized
            '''
            result = self._values.get("ebs_optimized")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def elastic_gpu_specifications(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.ElasticGpuSpecificationProperty"]]]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.ElasticGpuSpecifications``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-elasticgpuspecifications
            '''
            result = self._values.get("elastic_gpu_specifications")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.ElasticGpuSpecificationProperty"]]]], result)

        @builtins.property
        def elastic_inference_accelerators(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.LaunchTemplateElasticInferenceAcceleratorProperty"]]]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.ElasticInferenceAccelerators``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-elasticinferenceaccelerators
            '''
            result = self._values.get("elastic_inference_accelerators")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.LaunchTemplateElasticInferenceAcceleratorProperty"]]]], result)

        @builtins.property
        def enclave_options(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.EnclaveOptionsProperty"]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.EnclaveOptions``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-enclaveoptions
            '''
            result = self._values.get("enclave_options")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.EnclaveOptionsProperty"]], result)

        @builtins.property
        def hibernation_options(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.HibernationOptionsProperty"]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.HibernationOptions``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-hibernationoptions
            '''
            result = self._values.get("hibernation_options")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.HibernationOptionsProperty"]], result)

        @builtins.property
        def iam_instance_profile(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.IamInstanceProfileProperty"]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.IamInstanceProfile``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-iaminstanceprofile
            '''
            result = self._values.get("iam_instance_profile")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.IamInstanceProfileProperty"]], result)

        @builtins.property
        def image_id(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.ImageId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-imageid
            '''
            result = self._values.get("image_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def instance_initiated_shutdown_behavior(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.InstanceInitiatedShutdownBehavior``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-instanceinitiatedshutdownbehavior
            '''
            result = self._values.get("instance_initiated_shutdown_behavior")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def instance_market_options(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.InstanceMarketOptionsProperty"]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.InstanceMarketOptions``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-instancemarketoptions
            '''
            result = self._values.get("instance_market_options")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.InstanceMarketOptionsProperty"]], result)

        @builtins.property
        def instance_type(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.InstanceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-instancetype
            '''
            result = self._values.get("instance_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def kernel_id(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.KernelId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-kernelid
            '''
            result = self._values.get("kernel_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def key_name(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.KeyName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-keyname
            '''
            result = self._values.get("key_name")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def license_specifications(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.LicenseSpecificationProperty"]]]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.LicenseSpecifications``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-licensespecifications
            '''
            result = self._values.get("license_specifications")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.LicenseSpecificationProperty"]]]], result)

        @builtins.property
        def metadata_options(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.MetadataOptionsProperty"]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.MetadataOptions``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-metadataoptions
            '''
            result = self._values.get("metadata_options")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.MetadataOptionsProperty"]], result)

        @builtins.property
        def monitoring(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.MonitoringProperty"]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.Monitoring``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-monitoring
            '''
            result = self._values.get("monitoring")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.MonitoringProperty"]], result)

        @builtins.property
        def network_interfaces(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.NetworkInterfaceProperty"]]]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.NetworkInterfaces``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-networkinterfaces
            '''
            result = self._values.get("network_interfaces")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.NetworkInterfaceProperty"]]]], result)

        @builtins.property
        def placement(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.PlacementProperty"]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.Placement``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-placement
            '''
            result = self._values.get("placement")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.PlacementProperty"]], result)

        @builtins.property
        def ram_disk_id(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.RamDiskId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-ramdiskid
            '''
            result = self._values.get("ram_disk_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def security_group_ids(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.SecurityGroupIds``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-securitygroupids
            '''
            result = self._values.get("security_group_ids")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def security_groups(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.SecurityGroups``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-securitygroups
            '''
            result = self._values.get("security_groups")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def tag_specifications(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.TagSpecificationProperty"]]]]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.TagSpecifications``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-tagspecifications
            '''
            result = self._values.get("tag_specifications")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.TagSpecificationProperty"]]]], result)

        @builtins.property
        def user_data(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.LaunchTemplateDataProperty.UserData``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata.html#cfn-ec2-launchtemplate-launchtemplatedata-userdata
            '''
            result = self._values.get("user_data")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LaunchTemplateDataProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.LaunchTemplateElasticInferenceAcceleratorProperty",
        jsii_struct_bases=[],
        name_mapping={"count": "count", "type": "type"},
    )
    class LaunchTemplateElasticInferenceAcceleratorProperty:
        def __init__(
            self,
            *,
            count: typing.Optional[jsii.Number] = None,
            type: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param count: ``CfnLaunchTemplate.LaunchTemplateElasticInferenceAcceleratorProperty.Count``.
            :param type: ``CfnLaunchTemplate.LaunchTemplateElasticInferenceAcceleratorProperty.Type``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplateelasticinferenceaccelerator.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if count is not None:
                self._values["count"] = count
            if type is not None:
                self._values["type"] = type

        @builtins.property
        def count(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.LaunchTemplateElasticInferenceAcceleratorProperty.Count``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplateelasticinferenceaccelerator.html#cfn-ec2-launchtemplate-launchtemplateelasticinferenceaccelerator-count
            '''
            result = self._values.get("count")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def type(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.LaunchTemplateElasticInferenceAcceleratorProperty.Type``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplateelasticinferenceaccelerator.html#cfn-ec2-launchtemplate-launchtemplateelasticinferenceaccelerator-type
            '''
            result = self._values.get("type")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LaunchTemplateElasticInferenceAcceleratorProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.LicenseSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"license_configuration_arn": "licenseConfigurationArn"},
    )
    class LicenseSpecificationProperty:
        def __init__(
            self,
            *,
            license_configuration_arn: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param license_configuration_arn: ``CfnLaunchTemplate.LicenseSpecificationProperty.LicenseConfigurationArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-licensespecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if license_configuration_arn is not None:
                self._values["license_configuration_arn"] = license_configuration_arn

        @builtins.property
        def license_configuration_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.LicenseSpecificationProperty.LicenseConfigurationArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-licensespecification.html#cfn-ec2-launchtemplate-licensespecification-licenseconfigurationarn
            '''
            result = self._values.get("license_configuration_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LicenseSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.MetadataOptionsProperty",
        jsii_struct_bases=[],
        name_mapping={
            "http_endpoint": "httpEndpoint",
            "http_put_response_hop_limit": "httpPutResponseHopLimit",
            "http_tokens": "httpTokens",
        },
    )
    class MetadataOptionsProperty:
        def __init__(
            self,
            *,
            http_endpoint: typing.Optional[builtins.str] = None,
            http_put_response_hop_limit: typing.Optional[jsii.Number] = None,
            http_tokens: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param http_endpoint: ``CfnLaunchTemplate.MetadataOptionsProperty.HttpEndpoint``.
            :param http_put_response_hop_limit: ``CfnLaunchTemplate.MetadataOptionsProperty.HttpPutResponseHopLimit``.
            :param http_tokens: ``CfnLaunchTemplate.MetadataOptionsProperty.HttpTokens``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-metadataoptions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if http_endpoint is not None:
                self._values["http_endpoint"] = http_endpoint
            if http_put_response_hop_limit is not None:
                self._values["http_put_response_hop_limit"] = http_put_response_hop_limit
            if http_tokens is not None:
                self._values["http_tokens"] = http_tokens

        @builtins.property
        def http_endpoint(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.MetadataOptionsProperty.HttpEndpoint``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-metadataoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-metadataoptions-httpendpoint
            '''
            result = self._values.get("http_endpoint")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def http_put_response_hop_limit(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.MetadataOptionsProperty.HttpPutResponseHopLimit``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-metadataoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-metadataoptions-httpputresponsehoplimit
            '''
            result = self._values.get("http_put_response_hop_limit")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def http_tokens(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.MetadataOptionsProperty.HttpTokens``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-metadataoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-metadataoptions-httptokens
            '''
            result = self._values.get("http_tokens")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "MetadataOptionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.MonitoringProperty",
        jsii_struct_bases=[],
        name_mapping={"enabled": "enabled"},
    )
    class MonitoringProperty:
        def __init__(
            self,
            *,
            enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ) -> None:
            '''
            :param enabled: ``CfnLaunchTemplate.MonitoringProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-monitoring.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if enabled is not None:
                self._values["enabled"] = enabled

        @builtins.property
        def enabled(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnLaunchTemplate.MonitoringProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-monitoring.html#cfn-ec2-launchtemplate-launchtemplatedata-monitoring-enabled
            '''
            result = self._values.get("enabled")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "MonitoringProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.NetworkInterfaceProperty",
        jsii_struct_bases=[],
        name_mapping={
            "associate_carrier_ip_address": "associateCarrierIpAddress",
            "associate_public_ip_address": "associatePublicIpAddress",
            "delete_on_termination": "deleteOnTermination",
            "description": "description",
            "device_index": "deviceIndex",
            "groups": "groups",
            "interface_type": "interfaceType",
            "ipv6_address_count": "ipv6AddressCount",
            "ipv6_addresses": "ipv6Addresses",
            "network_card_index": "networkCardIndex",
            "network_interface_id": "networkInterfaceId",
            "private_ip_address": "privateIpAddress",
            "private_ip_addresses": "privateIpAddresses",
            "secondary_private_ip_address_count": "secondaryPrivateIpAddressCount",
            "subnet_id": "subnetId",
        },
    )
    class NetworkInterfaceProperty:
        def __init__(
            self,
            *,
            associate_carrier_ip_address: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            associate_public_ip_address: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            delete_on_termination: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            description: typing.Optional[builtins.str] = None,
            device_index: typing.Optional[jsii.Number] = None,
            groups: typing.Optional[typing.List[builtins.str]] = None,
            interface_type: typing.Optional[builtins.str] = None,
            ipv6_address_count: typing.Optional[jsii.Number] = None,
            ipv6_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.Ipv6AddProperty"]]]] = None,
            network_card_index: typing.Optional[jsii.Number] = None,
            network_interface_id: typing.Optional[builtins.str] = None,
            private_ip_address: typing.Optional[builtins.str] = None,
            private_ip_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.PrivateIpAddProperty"]]]] = None,
            secondary_private_ip_address_count: typing.Optional[jsii.Number] = None,
            subnet_id: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param associate_carrier_ip_address: ``CfnLaunchTemplate.NetworkInterfaceProperty.AssociateCarrierIpAddress``.
            :param associate_public_ip_address: ``CfnLaunchTemplate.NetworkInterfaceProperty.AssociatePublicIpAddress``.
            :param delete_on_termination: ``CfnLaunchTemplate.NetworkInterfaceProperty.DeleteOnTermination``.
            :param description: ``CfnLaunchTemplate.NetworkInterfaceProperty.Description``.
            :param device_index: ``CfnLaunchTemplate.NetworkInterfaceProperty.DeviceIndex``.
            :param groups: ``CfnLaunchTemplate.NetworkInterfaceProperty.Groups``.
            :param interface_type: ``CfnLaunchTemplate.NetworkInterfaceProperty.InterfaceType``.
            :param ipv6_address_count: ``CfnLaunchTemplate.NetworkInterfaceProperty.Ipv6AddressCount``.
            :param ipv6_addresses: ``CfnLaunchTemplate.NetworkInterfaceProperty.Ipv6Addresses``.
            :param network_card_index: ``CfnLaunchTemplate.NetworkInterfaceProperty.NetworkCardIndex``.
            :param network_interface_id: ``CfnLaunchTemplate.NetworkInterfaceProperty.NetworkInterfaceId``.
            :param private_ip_address: ``CfnLaunchTemplate.NetworkInterfaceProperty.PrivateIpAddress``.
            :param private_ip_addresses: ``CfnLaunchTemplate.NetworkInterfaceProperty.PrivateIpAddresses``.
            :param secondary_private_ip_address_count: ``CfnLaunchTemplate.NetworkInterfaceProperty.SecondaryPrivateIpAddressCount``.
            :param subnet_id: ``CfnLaunchTemplate.NetworkInterfaceProperty.SubnetId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if associate_carrier_ip_address is not None:
                self._values["associate_carrier_ip_address"] = associate_carrier_ip_address
            if associate_public_ip_address is not None:
                self._values["associate_public_ip_address"] = associate_public_ip_address
            if delete_on_termination is not None:
                self._values["delete_on_termination"] = delete_on_termination
            if description is not None:
                self._values["description"] = description
            if device_index is not None:
                self._values["device_index"] = device_index
            if groups is not None:
                self._values["groups"] = groups
            if interface_type is not None:
                self._values["interface_type"] = interface_type
            if ipv6_address_count is not None:
                self._values["ipv6_address_count"] = ipv6_address_count
            if ipv6_addresses is not None:
                self._values["ipv6_addresses"] = ipv6_addresses
            if network_card_index is not None:
                self._values["network_card_index"] = network_card_index
            if network_interface_id is not None:
                self._values["network_interface_id"] = network_interface_id
            if private_ip_address is not None:
                self._values["private_ip_address"] = private_ip_address
            if private_ip_addresses is not None:
                self._values["private_ip_addresses"] = private_ip_addresses
            if secondary_private_ip_address_count is not None:
                self._values["secondary_private_ip_address_count"] = secondary_private_ip_address_count
            if subnet_id is not None:
                self._values["subnet_id"] = subnet_id

        @builtins.property
        def associate_carrier_ip_address(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.AssociateCarrierIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-associatecarrieripaddress
            '''
            result = self._values.get("associate_carrier_ip_address")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def associate_public_ip_address(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.AssociatePublicIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-associatepublicipaddress
            '''
            result = self._values.get("associate_public_ip_address")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def delete_on_termination(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.DeleteOnTermination``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-deleteontermination
            '''
            result = self._values.get("delete_on_termination")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def description(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.Description``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-description
            '''
            result = self._values.get("description")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def device_index(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.DeviceIndex``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-deviceindex
            '''
            result = self._values.get("device_index")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def groups(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.Groups``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-groups
            '''
            result = self._values.get("groups")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def interface_type(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.InterfaceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-interfacetype
            '''
            result = self._values.get("interface_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def ipv6_address_count(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.Ipv6AddressCount``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-ipv6addresscount
            '''
            result = self._values.get("ipv6_address_count")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def ipv6_addresses(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.Ipv6AddProperty"]]]]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.Ipv6Addresses``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-ipv6addresses
            '''
            result = self._values.get("ipv6_addresses")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.Ipv6AddProperty"]]]], result)

        @builtins.property
        def network_card_index(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.NetworkCardIndex``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-networkcardindex
            '''
            result = self._values.get("network_card_index")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def network_interface_id(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.NetworkInterfaceId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-networkinterfaceid
            '''
            result = self._values.get("network_interface_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def private_ip_address(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.PrivateIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-privateipaddress
            '''
            result = self._values.get("private_ip_address")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def private_ip_addresses(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.PrivateIpAddProperty"]]]]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.PrivateIpAddresses``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-privateipaddresses
            '''
            result = self._values.get("private_ip_addresses")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnLaunchTemplate.PrivateIpAddProperty"]]]], result)

        @builtins.property
        def secondary_private_ip_address_count(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.SecondaryPrivateIpAddressCount``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-secondaryprivateipaddresscount
            '''
            result = self._values.get("secondary_private_ip_address_count")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def subnet_id(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.NetworkInterfaceProperty.SubnetId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html#cfn-ec2-launchtemplate-networkinterface-subnetid
            '''
            result = self._values.get("subnet_id")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "NetworkInterfaceProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.PlacementProperty",
        jsii_struct_bases=[],
        name_mapping={
            "affinity": "affinity",
            "availability_zone": "availabilityZone",
            "group_name": "groupName",
            "host_id": "hostId",
            "host_resource_group_arn": "hostResourceGroupArn",
            "partition_number": "partitionNumber",
            "spread_domain": "spreadDomain",
            "tenancy": "tenancy",
        },
    )
    class PlacementProperty:
        def __init__(
            self,
            *,
            affinity: typing.Optional[builtins.str] = None,
            availability_zone: typing.Optional[builtins.str] = None,
            group_name: typing.Optional[builtins.str] = None,
            host_id: typing.Optional[builtins.str] = None,
            host_resource_group_arn: typing.Optional[builtins.str] = None,
            partition_number: typing.Optional[jsii.Number] = None,
            spread_domain: typing.Optional[builtins.str] = None,
            tenancy: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param affinity: ``CfnLaunchTemplate.PlacementProperty.Affinity``.
            :param availability_zone: ``CfnLaunchTemplate.PlacementProperty.AvailabilityZone``.
            :param group_name: ``CfnLaunchTemplate.PlacementProperty.GroupName``.
            :param host_id: ``CfnLaunchTemplate.PlacementProperty.HostId``.
            :param host_resource_group_arn: ``CfnLaunchTemplate.PlacementProperty.HostResourceGroupArn``.
            :param partition_number: ``CfnLaunchTemplate.PlacementProperty.PartitionNumber``.
            :param spread_domain: ``CfnLaunchTemplate.PlacementProperty.SpreadDomain``.
            :param tenancy: ``CfnLaunchTemplate.PlacementProperty.Tenancy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-placement.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if affinity is not None:
                self._values["affinity"] = affinity
            if availability_zone is not None:
                self._values["availability_zone"] = availability_zone
            if group_name is not None:
                self._values["group_name"] = group_name
            if host_id is not None:
                self._values["host_id"] = host_id
            if host_resource_group_arn is not None:
                self._values["host_resource_group_arn"] = host_resource_group_arn
            if partition_number is not None:
                self._values["partition_number"] = partition_number
            if spread_domain is not None:
                self._values["spread_domain"] = spread_domain
            if tenancy is not None:
                self._values["tenancy"] = tenancy

        @builtins.property
        def affinity(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.PlacementProperty.Affinity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-placement.html#cfn-ec2-launchtemplate-launchtemplatedata-placement-affinity
            '''
            result = self._values.get("affinity")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def availability_zone(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.PlacementProperty.AvailabilityZone``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-placement.html#cfn-ec2-launchtemplate-launchtemplatedata-placement-availabilityzone
            '''
            result = self._values.get("availability_zone")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def group_name(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.PlacementProperty.GroupName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-placement.html#cfn-ec2-launchtemplate-launchtemplatedata-placement-groupname
            '''
            result = self._values.get("group_name")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def host_id(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.PlacementProperty.HostId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-placement.html#cfn-ec2-launchtemplate-launchtemplatedata-placement-hostid
            '''
            result = self._values.get("host_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def host_resource_group_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.PlacementProperty.HostResourceGroupArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-placement.html#cfn-ec2-launchtemplate-launchtemplatedata-placement-hostresourcegrouparn
            '''
            result = self._values.get("host_resource_group_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def partition_number(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.PlacementProperty.PartitionNumber``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-placement.html#cfn-ec2-launchtemplate-launchtemplatedata-placement-partitionnumber
            '''
            result = self._values.get("partition_number")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def spread_domain(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.PlacementProperty.SpreadDomain``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-placement.html#cfn-ec2-launchtemplate-launchtemplatedata-placement-spreaddomain
            '''
            result = self._values.get("spread_domain")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def tenancy(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.PlacementProperty.Tenancy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-placement.html#cfn-ec2-launchtemplate-launchtemplatedata-placement-tenancy
            '''
            result = self._values.get("tenancy")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PlacementProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.PrivateIpAddProperty",
        jsii_struct_bases=[],
        name_mapping={"primary": "primary", "private_ip_address": "privateIpAddress"},
    )
    class PrivateIpAddProperty:
        def __init__(
            self,
            *,
            primary: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            private_ip_address: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param primary: ``CfnLaunchTemplate.PrivateIpAddProperty.Primary``.
            :param private_ip_address: ``CfnLaunchTemplate.PrivateIpAddProperty.PrivateIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-privateipadd.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if primary is not None:
                self._values["primary"] = primary
            if private_ip_address is not None:
                self._values["private_ip_address"] = private_ip_address

        @builtins.property
        def primary(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnLaunchTemplate.PrivateIpAddProperty.Primary``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-privateipadd.html#cfn-ec2-launchtemplate-privateipadd-primary
            '''
            result = self._values.get("primary")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def private_ip_address(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.PrivateIpAddProperty.PrivateIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-privateipadd.html#cfn-ec2-launchtemplate-privateipadd-privateipaddress
            '''
            result = self._values.get("private_ip_address")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PrivateIpAddProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.SpotOptionsProperty",
        jsii_struct_bases=[],
        name_mapping={
            "block_duration_minutes": "blockDurationMinutes",
            "instance_interruption_behavior": "instanceInterruptionBehavior",
            "max_price": "maxPrice",
            "spot_instance_type": "spotInstanceType",
            "valid_until": "validUntil",
        },
    )
    class SpotOptionsProperty:
        def __init__(
            self,
            *,
            block_duration_minutes: typing.Optional[jsii.Number] = None,
            instance_interruption_behavior: typing.Optional[builtins.str] = None,
            max_price: typing.Optional[builtins.str] = None,
            spot_instance_type: typing.Optional[builtins.str] = None,
            valid_until: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param block_duration_minutes: ``CfnLaunchTemplate.SpotOptionsProperty.BlockDurationMinutes``.
            :param instance_interruption_behavior: ``CfnLaunchTemplate.SpotOptionsProperty.InstanceInterruptionBehavior``.
            :param max_price: ``CfnLaunchTemplate.SpotOptionsProperty.MaxPrice``.
            :param spot_instance_type: ``CfnLaunchTemplate.SpotOptionsProperty.SpotInstanceType``.
            :param valid_until: ``CfnLaunchTemplate.SpotOptionsProperty.ValidUntil``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if block_duration_minutes is not None:
                self._values["block_duration_minutes"] = block_duration_minutes
            if instance_interruption_behavior is not None:
                self._values["instance_interruption_behavior"] = instance_interruption_behavior
            if max_price is not None:
                self._values["max_price"] = max_price
            if spot_instance_type is not None:
                self._values["spot_instance_type"] = spot_instance_type
            if valid_until is not None:
                self._values["valid_until"] = valid_until

        @builtins.property
        def block_duration_minutes(self) -> typing.Optional[jsii.Number]:
            '''``CfnLaunchTemplate.SpotOptionsProperty.BlockDurationMinutes``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions-blockdurationminutes
            '''
            result = self._values.get("block_duration_minutes")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def instance_interruption_behavior(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.SpotOptionsProperty.InstanceInterruptionBehavior``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions-instanceinterruptionbehavior
            '''
            result = self._values.get("instance_interruption_behavior")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def max_price(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.SpotOptionsProperty.MaxPrice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions-maxprice
            '''
            result = self._values.get("max_price")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def spot_instance_type(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.SpotOptionsProperty.SpotInstanceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions-spotinstancetype
            '''
            result = self._values.get("spot_instance_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def valid_until(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.SpotOptionsProperty.ValidUntil``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions.html#cfn-ec2-launchtemplate-launchtemplatedata-instancemarketoptions-spotoptions-validuntil
            '''
            result = self._values.get("valid_until")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SpotOptionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplate.TagSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"resource_type": "resourceType", "tags": "tags"},
    )
    class TagSpecificationProperty:
        def __init__(
            self,
            *,
            resource_type: typing.Optional[builtins.str] = None,
            tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        ) -> None:
            '''
            :param resource_type: ``CfnLaunchTemplate.TagSpecificationProperty.ResourceType``.
            :param tags: ``CfnLaunchTemplate.TagSpecificationProperty.Tags``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-tagspecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if resource_type is not None:
                self._values["resource_type"] = resource_type
            if tags is not None:
                self._values["tags"] = tags

        @builtins.property
        def resource_type(self) -> typing.Optional[builtins.str]:
            '''``CfnLaunchTemplate.TagSpecificationProperty.ResourceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-tagspecification.html#cfn-ec2-launchtemplate-tagspecification-resourcetype
            '''
            result = self._values.get("resource_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
            '''``CfnLaunchTemplate.TagSpecificationProperty.Tags``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-tagspecification.html#cfn-ec2-launchtemplate-tagspecification-tags
            '''
            result = self._values.get("tags")
            return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TagSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnLaunchTemplateProps",
    jsii_struct_bases=[],
    name_mapping={
        "launch_template_data": "launchTemplateData",
        "launch_template_name": "launchTemplateName",
    },
)
class CfnLaunchTemplateProps:
    def __init__(
        self,
        *,
        launch_template_data: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnLaunchTemplate.LaunchTemplateDataProperty]] = None,
        launch_template_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::LaunchTemplate``.

        :param launch_template_data: ``AWS::EC2::LaunchTemplate.LaunchTemplateData``.
        :param launch_template_name: ``AWS::EC2::LaunchTemplate.LaunchTemplateName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-launchtemplate.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if launch_template_data is not None:
            self._values["launch_template_data"] = launch_template_data
        if launch_template_name is not None:
            self._values["launch_template_name"] = launch_template_name

    @builtins.property
    def launch_template_data(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnLaunchTemplate.LaunchTemplateDataProperty]]:
        '''``AWS::EC2::LaunchTemplate.LaunchTemplateData``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-launchtemplate.html#cfn-ec2-launchtemplate-launchtemplatedata
        '''
        result = self._values.get("launch_template_data")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnLaunchTemplate.LaunchTemplateDataProperty]], result)

    @builtins.property
    def launch_template_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::LaunchTemplate.LaunchTemplateName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-launchtemplate.html#cfn-ec2-launchtemplate-launchtemplatename
        '''
        result = self._values.get("launch_template_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnLaunchTemplateProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnLocalGatewayRoute(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnLocalGatewayRoute",
):
    '''A CloudFormation ``AWS::EC2::LocalGatewayRoute``.

    :cloudformationResource: AWS::EC2::LocalGatewayRoute
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroute.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        destination_cidr_block: builtins.str,
        local_gateway_route_table_id: builtins.str,
        local_gateway_virtual_interface_group_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::LocalGatewayRoute``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param destination_cidr_block: ``AWS::EC2::LocalGatewayRoute.DestinationCidrBlock``.
        :param local_gateway_route_table_id: ``AWS::EC2::LocalGatewayRoute.LocalGatewayRouteTableId``.
        :param local_gateway_virtual_interface_group_id: ``AWS::EC2::LocalGatewayRoute.LocalGatewayVirtualInterfaceGroupId``.
        '''
        props = CfnLocalGatewayRouteProps(
            destination_cidr_block=destination_cidr_block,
            local_gateway_route_table_id=local_gateway_route_table_id,
            local_gateway_virtual_interface_group_id=local_gateway_virtual_interface_group_id,
        )

        jsii.create(CfnLocalGatewayRoute, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrState")
    def attr_state(self) -> builtins.str:
        '''
        :cloudformationAttribute: State
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrState"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrType")
    def attr_type(self) -> builtins.str:
        '''
        :cloudformationAttribute: Type
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrType"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationCidrBlock")
    def destination_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::LocalGatewayRoute.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroute.html#cfn-ec2-localgatewayroute-destinationcidrblock
        '''
        return typing.cast(builtins.str, jsii.get(self, "destinationCidrBlock"))

    @destination_cidr_block.setter
    def destination_cidr_block(self, value: builtins.str) -> None:
        jsii.set(self, "destinationCidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="localGatewayRouteTableId")
    def local_gateway_route_table_id(self) -> builtins.str:
        '''``AWS::EC2::LocalGatewayRoute.LocalGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroute.html#cfn-ec2-localgatewayroute-localgatewayroutetableid
        '''
        return typing.cast(builtins.str, jsii.get(self, "localGatewayRouteTableId"))

    @local_gateway_route_table_id.setter
    def local_gateway_route_table_id(self, value: builtins.str) -> None:
        jsii.set(self, "localGatewayRouteTableId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="localGatewayVirtualInterfaceGroupId")
    def local_gateway_virtual_interface_group_id(self) -> builtins.str:
        '''``AWS::EC2::LocalGatewayRoute.LocalGatewayVirtualInterfaceGroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroute.html#cfn-ec2-localgatewayroute-localgatewayvirtualinterfacegroupid
        '''
        return typing.cast(builtins.str, jsii.get(self, "localGatewayVirtualInterfaceGroupId"))

    @local_gateway_virtual_interface_group_id.setter
    def local_gateway_virtual_interface_group_id(self, value: builtins.str) -> None:
        jsii.set(self, "localGatewayVirtualInterfaceGroupId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnLocalGatewayRouteProps",
    jsii_struct_bases=[],
    name_mapping={
        "destination_cidr_block": "destinationCidrBlock",
        "local_gateway_route_table_id": "localGatewayRouteTableId",
        "local_gateway_virtual_interface_group_id": "localGatewayVirtualInterfaceGroupId",
    },
)
class CfnLocalGatewayRouteProps:
    def __init__(
        self,
        *,
        destination_cidr_block: builtins.str,
        local_gateway_route_table_id: builtins.str,
        local_gateway_virtual_interface_group_id: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::LocalGatewayRoute``.

        :param destination_cidr_block: ``AWS::EC2::LocalGatewayRoute.DestinationCidrBlock``.
        :param local_gateway_route_table_id: ``AWS::EC2::LocalGatewayRoute.LocalGatewayRouteTableId``.
        :param local_gateway_virtual_interface_group_id: ``AWS::EC2::LocalGatewayRoute.LocalGatewayVirtualInterfaceGroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroute.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "destination_cidr_block": destination_cidr_block,
            "local_gateway_route_table_id": local_gateway_route_table_id,
            "local_gateway_virtual_interface_group_id": local_gateway_virtual_interface_group_id,
        }

    @builtins.property
    def destination_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::LocalGatewayRoute.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroute.html#cfn-ec2-localgatewayroute-destinationcidrblock
        '''
        result = self._values.get("destination_cidr_block")
        assert result is not None, "Required property 'destination_cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def local_gateway_route_table_id(self) -> builtins.str:
        '''``AWS::EC2::LocalGatewayRoute.LocalGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroute.html#cfn-ec2-localgatewayroute-localgatewayroutetableid
        '''
        result = self._values.get("local_gateway_route_table_id")
        assert result is not None, "Required property 'local_gateway_route_table_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def local_gateway_virtual_interface_group_id(self) -> builtins.str:
        '''``AWS::EC2::LocalGatewayRoute.LocalGatewayVirtualInterfaceGroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroute.html#cfn-ec2-localgatewayroute-localgatewayvirtualinterfacegroupid
        '''
        result = self._values.get("local_gateway_virtual_interface_group_id")
        assert result is not None, "Required property 'local_gateway_virtual_interface_group_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnLocalGatewayRouteProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnLocalGatewayRouteTableVPCAssociation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnLocalGatewayRouteTableVPCAssociation",
):
    '''A CloudFormation ``AWS::EC2::LocalGatewayRouteTableVPCAssociation``.

    :cloudformationResource: AWS::EC2::LocalGatewayRouteTableVPCAssociation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroutetablevpcassociation.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        local_gateway_route_table_id: builtins.str,
        vpc_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::LocalGatewayRouteTableVPCAssociation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param local_gateway_route_table_id: ``AWS::EC2::LocalGatewayRouteTableVPCAssociation.LocalGatewayRouteTableId``.
        :param vpc_id: ``AWS::EC2::LocalGatewayRouteTableVPCAssociation.VpcId``.
        :param tags: ``AWS::EC2::LocalGatewayRouteTableVPCAssociation.Tags``.
        '''
        props = CfnLocalGatewayRouteTableVPCAssociationProps(
            local_gateway_route_table_id=local_gateway_route_table_id,
            vpc_id=vpc_id,
            tags=tags,
        )

        jsii.create(CfnLocalGatewayRouteTableVPCAssociation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrLocalGatewayId")
    def attr_local_gateway_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: LocalGatewayId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrLocalGatewayId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrLocalGatewayRouteTableVpcAssociationId")
    def attr_local_gateway_route_table_vpc_association_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: LocalGatewayRouteTableVpcAssociationId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrLocalGatewayRouteTableVpcAssociationId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrState")
    def attr_state(self) -> builtins.str:
        '''
        :cloudformationAttribute: State
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrState"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::LocalGatewayRouteTableVPCAssociation.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroutetablevpcassociation.html#cfn-ec2-localgatewayroutetablevpcassociation-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="localGatewayRouteTableId")
    def local_gateway_route_table_id(self) -> builtins.str:
        '''``AWS::EC2::LocalGatewayRouteTableVPCAssociation.LocalGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroutetablevpcassociation.html#cfn-ec2-localgatewayroutetablevpcassociation-localgatewayroutetableid
        '''
        return typing.cast(builtins.str, jsii.get(self, "localGatewayRouteTableId"))

    @local_gateway_route_table_id.setter
    def local_gateway_route_table_id(self, value: builtins.str) -> None:
        jsii.set(self, "localGatewayRouteTableId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::LocalGatewayRouteTableVPCAssociation.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroutetablevpcassociation.html#cfn-ec2-localgatewayroutetablevpcassociation-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnLocalGatewayRouteTableVPCAssociationProps",
    jsii_struct_bases=[],
    name_mapping={
        "local_gateway_route_table_id": "localGatewayRouteTableId",
        "vpc_id": "vpcId",
        "tags": "tags",
    },
)
class CfnLocalGatewayRouteTableVPCAssociationProps:
    def __init__(
        self,
        *,
        local_gateway_route_table_id: builtins.str,
        vpc_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::LocalGatewayRouteTableVPCAssociation``.

        :param local_gateway_route_table_id: ``AWS::EC2::LocalGatewayRouteTableVPCAssociation.LocalGatewayRouteTableId``.
        :param vpc_id: ``AWS::EC2::LocalGatewayRouteTableVPCAssociation.VpcId``.
        :param tags: ``AWS::EC2::LocalGatewayRouteTableVPCAssociation.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroutetablevpcassociation.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "local_gateway_route_table_id": local_gateway_route_table_id,
            "vpc_id": vpc_id,
        }
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def local_gateway_route_table_id(self) -> builtins.str:
        '''``AWS::EC2::LocalGatewayRouteTableVPCAssociation.LocalGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroutetablevpcassociation.html#cfn-ec2-localgatewayroutetablevpcassociation-localgatewayroutetableid
        '''
        result = self._values.get("local_gateway_route_table_id")
        assert result is not None, "Required property 'local_gateway_route_table_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::LocalGatewayRouteTableVPCAssociation.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroutetablevpcassociation.html#cfn-ec2-localgatewayroutetablevpcassociation-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::LocalGatewayRouteTableVPCAssociation.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-localgatewayroutetablevpcassociation.html#cfn-ec2-localgatewayroutetablevpcassociation-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnLocalGatewayRouteTableVPCAssociationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnNatGateway(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnNatGateway",
):
    '''A CloudFormation ``AWS::EC2::NatGateway``.

    :cloudformationResource: AWS::EC2::NatGateway
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-natgateway.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        allocation_id: builtins.str,
        subnet_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::NatGateway``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param allocation_id: ``AWS::EC2::NatGateway.AllocationId``.
        :param subnet_id: ``AWS::EC2::NatGateway.SubnetId``.
        :param tags: ``AWS::EC2::NatGateway.Tags``.
        '''
        props = CfnNatGatewayProps(
            allocation_id=allocation_id, subnet_id=subnet_id, tags=tags
        )

        jsii.create(CfnNatGateway, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::NatGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-natgateway.html#cfn-ec2-natgateway-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="allocationId")
    def allocation_id(self) -> builtins.str:
        '''``AWS::EC2::NatGateway.AllocationId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-natgateway.html#cfn-ec2-natgateway-allocationid
        '''
        return typing.cast(builtins.str, jsii.get(self, "allocationId"))

    @allocation_id.setter
    def allocation_id(self, value: builtins.str) -> None:
        jsii.set(self, "allocationId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetId")
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::NatGateway.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-natgateway.html#cfn-ec2-natgateway-subnetid
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetId"))

    @subnet_id.setter
    def subnet_id(self, value: builtins.str) -> None:
        jsii.set(self, "subnetId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnNatGatewayProps",
    jsii_struct_bases=[],
    name_mapping={
        "allocation_id": "allocationId",
        "subnet_id": "subnetId",
        "tags": "tags",
    },
)
class CfnNatGatewayProps:
    def __init__(
        self,
        *,
        allocation_id: builtins.str,
        subnet_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::NatGateway``.

        :param allocation_id: ``AWS::EC2::NatGateway.AllocationId``.
        :param subnet_id: ``AWS::EC2::NatGateway.SubnetId``.
        :param tags: ``AWS::EC2::NatGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-natgateway.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "allocation_id": allocation_id,
            "subnet_id": subnet_id,
        }
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def allocation_id(self) -> builtins.str:
        '''``AWS::EC2::NatGateway.AllocationId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-natgateway.html#cfn-ec2-natgateway-allocationid
        '''
        result = self._values.get("allocation_id")
        assert result is not None, "Required property 'allocation_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::NatGateway.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-natgateway.html#cfn-ec2-natgateway-subnetid
        '''
        result = self._values.get("subnet_id")
        assert result is not None, "Required property 'subnet_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::NatGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-natgateway.html#cfn-ec2-natgateway-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnNatGatewayProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnNetworkAcl(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkAcl",
):
    '''A CloudFormation ``AWS::EC2::NetworkAcl``.

    :cloudformationResource: AWS::EC2::NetworkAcl
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        vpc_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::NetworkAcl``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param vpc_id: ``AWS::EC2::NetworkAcl.VpcId``.
        :param tags: ``AWS::EC2::NetworkAcl.Tags``.
        '''
        props = CfnNetworkAclProps(vpc_id=vpc_id, tags=tags)

        jsii.create(CfnNetworkAcl, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::NetworkAcl.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkAcl.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)


@jsii.implements(aws_cdk.core.IInspectable)
class CfnNetworkAclEntry(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkAclEntry",
):
    '''A CloudFormation ``AWS::EC2::NetworkAclEntry``.

    :cloudformationResource: AWS::EC2::NetworkAclEntry
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        network_acl_id: builtins.str,
        protocol: jsii.Number,
        rule_action: builtins.str,
        rule_number: jsii.Number,
        cidr_block: typing.Optional[builtins.str] = None,
        egress: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        icmp: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkAclEntry.IcmpProperty"]] = None,
        ipv6_cidr_block: typing.Optional[builtins.str] = None,
        port_range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkAclEntry.PortRangeProperty"]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::NetworkAclEntry``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param network_acl_id: ``AWS::EC2::NetworkAclEntry.NetworkAclId``.
        :param protocol: ``AWS::EC2::NetworkAclEntry.Protocol``.
        :param rule_action: ``AWS::EC2::NetworkAclEntry.RuleAction``.
        :param rule_number: ``AWS::EC2::NetworkAclEntry.RuleNumber``.
        :param cidr_block: ``AWS::EC2::NetworkAclEntry.CidrBlock``.
        :param egress: ``AWS::EC2::NetworkAclEntry.Egress``.
        :param icmp: ``AWS::EC2::NetworkAclEntry.Icmp``.
        :param ipv6_cidr_block: ``AWS::EC2::NetworkAclEntry.Ipv6CidrBlock``.
        :param port_range: ``AWS::EC2::NetworkAclEntry.PortRange``.
        '''
        props = CfnNetworkAclEntryProps(
            network_acl_id=network_acl_id,
            protocol=protocol,
            rule_action=rule_action,
            rule_number=rule_number,
            cidr_block=cidr_block,
            egress=egress,
            icmp=icmp,
            ipv6_cidr_block=ipv6_cidr_block,
            port_range=port_range,
        )

        jsii.create(CfnNetworkAclEntry, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkAclId")
    def network_acl_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkAclEntry.NetworkAclId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-networkaclid
        '''
        return typing.cast(builtins.str, jsii.get(self, "networkAclId"))

    @network_acl_id.setter
    def network_acl_id(self, value: builtins.str) -> None:
        jsii.set(self, "networkAclId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="protocol")
    def protocol(self) -> jsii.Number:
        '''``AWS::EC2::NetworkAclEntry.Protocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-protocol
        '''
        return typing.cast(jsii.Number, jsii.get(self, "protocol"))

    @protocol.setter
    def protocol(self, value: jsii.Number) -> None:
        jsii.set(self, "protocol", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ruleAction")
    def rule_action(self) -> builtins.str:
        '''``AWS::EC2::NetworkAclEntry.RuleAction``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ruleaction
        '''
        return typing.cast(builtins.str, jsii.get(self, "ruleAction"))

    @rule_action.setter
    def rule_action(self, value: builtins.str) -> None:
        jsii.set(self, "ruleAction", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ruleNumber")
    def rule_number(self) -> jsii.Number:
        '''``AWS::EC2::NetworkAclEntry.RuleNumber``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-rulenumber
        '''
        return typing.cast(jsii.Number, jsii.get(self, "ruleNumber"))

    @rule_number.setter
    def rule_number(self, value: jsii.Number) -> None:
        jsii.set(self, "ruleNumber", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cidrBlock")
    def cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkAclEntry.CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-cidrblock
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "cidrBlock"))

    @cidr_block.setter
    def cidr_block(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "cidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="egress")
    def egress(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::NetworkAclEntry.Egress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-egress
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "egress"))

    @egress.setter
    def egress(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "egress", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="icmp")
    def icmp(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkAclEntry.IcmpProperty"]]:
        '''``AWS::EC2::NetworkAclEntry.Icmp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-icmp
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkAclEntry.IcmpProperty"]], jsii.get(self, "icmp"))

    @icmp.setter
    def icmp(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkAclEntry.IcmpProperty"]],
    ) -> None:
        jsii.set(self, "icmp", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipv6CidrBlock")
    def ipv6_cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkAclEntry.Ipv6CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ipv6cidrblock
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "ipv6CidrBlock"))

    @ipv6_cidr_block.setter
    def ipv6_cidr_block(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "ipv6CidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="portRange")
    def port_range(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkAclEntry.PortRangeProperty"]]:
        '''``AWS::EC2::NetworkAclEntry.PortRange``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-portrange
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkAclEntry.PortRangeProperty"]], jsii.get(self, "portRange"))

    @port_range.setter
    def port_range(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkAclEntry.PortRangeProperty"]],
    ) -> None:
        jsii.set(self, "portRange", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkAclEntry.IcmpProperty",
        jsii_struct_bases=[],
        name_mapping={"code": "code", "type": "type"},
    )
    class IcmpProperty:
        def __init__(
            self,
            *,
            code: typing.Optional[jsii.Number] = None,
            type: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param code: ``CfnNetworkAclEntry.IcmpProperty.Code``.
            :param type: ``CfnNetworkAclEntry.IcmpProperty.Type``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkaclentry-icmp.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if code is not None:
                self._values["code"] = code
            if type is not None:
                self._values["type"] = type

        @builtins.property
        def code(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkAclEntry.IcmpProperty.Code``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkaclentry-icmp.html#cfn-ec2-networkaclentry-icmp-code
            '''
            result = self._values.get("code")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def type(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkAclEntry.IcmpProperty.Type``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkaclentry-icmp.html#cfn-ec2-networkaclentry-icmp-type
            '''
            result = self._values.get("type")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "IcmpProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkAclEntry.PortRangeProperty",
        jsii_struct_bases=[],
        name_mapping={"from_": "from", "to": "to"},
    )
    class PortRangeProperty:
        def __init__(
            self,
            *,
            from_: typing.Optional[jsii.Number] = None,
            to: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param from_: ``CfnNetworkAclEntry.PortRangeProperty.From``.
            :param to: ``CfnNetworkAclEntry.PortRangeProperty.To``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkaclentry-portrange.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if from_ is not None:
                self._values["from_"] = from_
            if to is not None:
                self._values["to"] = to

        @builtins.property
        def from_(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkAclEntry.PortRangeProperty.From``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkaclentry-portrange.html#cfn-ec2-networkaclentry-portrange-from
            '''
            result = self._values.get("from_")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def to(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkAclEntry.PortRangeProperty.To``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkaclentry-portrange.html#cfn-ec2-networkaclentry-portrange-to
            '''
            result = self._values.get("to")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PortRangeProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkAclEntryProps",
    jsii_struct_bases=[],
    name_mapping={
        "network_acl_id": "networkAclId",
        "protocol": "protocol",
        "rule_action": "ruleAction",
        "rule_number": "ruleNumber",
        "cidr_block": "cidrBlock",
        "egress": "egress",
        "icmp": "icmp",
        "ipv6_cidr_block": "ipv6CidrBlock",
        "port_range": "portRange",
    },
)
class CfnNetworkAclEntryProps:
    def __init__(
        self,
        *,
        network_acl_id: builtins.str,
        protocol: jsii.Number,
        rule_action: builtins.str,
        rule_number: jsii.Number,
        cidr_block: typing.Optional[builtins.str] = None,
        egress: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        icmp: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnNetworkAclEntry.IcmpProperty]] = None,
        ipv6_cidr_block: typing.Optional[builtins.str] = None,
        port_range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnNetworkAclEntry.PortRangeProperty]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::NetworkAclEntry``.

        :param network_acl_id: ``AWS::EC2::NetworkAclEntry.NetworkAclId``.
        :param protocol: ``AWS::EC2::NetworkAclEntry.Protocol``.
        :param rule_action: ``AWS::EC2::NetworkAclEntry.RuleAction``.
        :param rule_number: ``AWS::EC2::NetworkAclEntry.RuleNumber``.
        :param cidr_block: ``AWS::EC2::NetworkAclEntry.CidrBlock``.
        :param egress: ``AWS::EC2::NetworkAclEntry.Egress``.
        :param icmp: ``AWS::EC2::NetworkAclEntry.Icmp``.
        :param ipv6_cidr_block: ``AWS::EC2::NetworkAclEntry.Ipv6CidrBlock``.
        :param port_range: ``AWS::EC2::NetworkAclEntry.PortRange``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "network_acl_id": network_acl_id,
            "protocol": protocol,
            "rule_action": rule_action,
            "rule_number": rule_number,
        }
        if cidr_block is not None:
            self._values["cidr_block"] = cidr_block
        if egress is not None:
            self._values["egress"] = egress
        if icmp is not None:
            self._values["icmp"] = icmp
        if ipv6_cidr_block is not None:
            self._values["ipv6_cidr_block"] = ipv6_cidr_block
        if port_range is not None:
            self._values["port_range"] = port_range

    @builtins.property
    def network_acl_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkAclEntry.NetworkAclId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-networkaclid
        '''
        result = self._values.get("network_acl_id")
        assert result is not None, "Required property 'network_acl_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def protocol(self) -> jsii.Number:
        '''``AWS::EC2::NetworkAclEntry.Protocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-protocol
        '''
        result = self._values.get("protocol")
        assert result is not None, "Required property 'protocol' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def rule_action(self) -> builtins.str:
        '''``AWS::EC2::NetworkAclEntry.RuleAction``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ruleaction
        '''
        result = self._values.get("rule_action")
        assert result is not None, "Required property 'rule_action' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def rule_number(self) -> jsii.Number:
        '''``AWS::EC2::NetworkAclEntry.RuleNumber``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-rulenumber
        '''
        result = self._values.get("rule_number")
        assert result is not None, "Required property 'rule_number' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkAclEntry.CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-cidrblock
        '''
        result = self._values.get("cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def egress(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::NetworkAclEntry.Egress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-egress
        '''
        result = self._values.get("egress")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def icmp(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnNetworkAclEntry.IcmpProperty]]:
        '''``AWS::EC2::NetworkAclEntry.Icmp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-icmp
        '''
        result = self._values.get("icmp")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnNetworkAclEntry.IcmpProperty]], result)

    @builtins.property
    def ipv6_cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkAclEntry.Ipv6CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ipv6cidrblock
        '''
        result = self._values.get("ipv6_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def port_range(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnNetworkAclEntry.PortRangeProperty]]:
        '''``AWS::EC2::NetworkAclEntry.PortRange``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-portrange
        '''
        result = self._values.get("port_range")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnNetworkAclEntry.PortRangeProperty]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnNetworkAclEntryProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkAclProps",
    jsii_struct_bases=[],
    name_mapping={"vpc_id": "vpcId", "tags": "tags"},
)
class CfnNetworkAclProps:
    def __init__(
        self,
        *,
        vpc_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::NetworkAcl``.

        :param vpc_id: ``AWS::EC2::NetworkAcl.VpcId``.
        :param tags: ``AWS::EC2::NetworkAcl.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "vpc_id": vpc_id,
        }
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkAcl.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::NetworkAcl.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnNetworkAclProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnNetworkInsightsAnalysis(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis",
):
    '''A CloudFormation ``AWS::EC2::NetworkInsightsAnalysis``.

    :cloudformationResource: AWS::EC2::NetworkInsightsAnalysis
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightsanalysis.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        network_insights_path_id: builtins.str,
        filter_in_arns: typing.Optional[typing.List[builtins.str]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::NetworkInsightsAnalysis``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param network_insights_path_id: ``AWS::EC2::NetworkInsightsAnalysis.NetworkInsightsPathId``.
        :param filter_in_arns: ``AWS::EC2::NetworkInsightsAnalysis.FilterInArns``.
        :param tags: ``AWS::EC2::NetworkInsightsAnalysis.Tags``.
        '''
        props = CfnNetworkInsightsAnalysisProps(
            network_insights_path_id=network_insights_path_id,
            filter_in_arns=filter_in_arns,
            tags=tags,
        )

        jsii.create(CfnNetworkInsightsAnalysis, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAlternatePathHints")
    def attr_alternate_path_hints(self) -> aws_cdk.core.IResolvable:
        '''
        :cloudformationAttribute: AlternatePathHints
        '''
        return typing.cast(aws_cdk.core.IResolvable, jsii.get(self, "attrAlternatePathHints"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrExplanations")
    def attr_explanations(self) -> aws_cdk.core.IResolvable:
        '''
        :cloudformationAttribute: Explanations
        '''
        return typing.cast(aws_cdk.core.IResolvable, jsii.get(self, "attrExplanations"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrForwardPathComponents")
    def attr_forward_path_components(self) -> aws_cdk.core.IResolvable:
        '''
        :cloudformationAttribute: ForwardPathComponents
        '''
        return typing.cast(aws_cdk.core.IResolvable, jsii.get(self, "attrForwardPathComponents"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrNetworkInsightsAnalysisArn")
    def attr_network_insights_analysis_arn(self) -> builtins.str:
        '''
        :cloudformationAttribute: NetworkInsightsAnalysisArn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrNetworkInsightsAnalysisArn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrNetworkInsightsAnalysisId")
    def attr_network_insights_analysis_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: NetworkInsightsAnalysisId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrNetworkInsightsAnalysisId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrNetworkPathFound")
    def attr_network_path_found(self) -> aws_cdk.core.IResolvable:
        '''
        :cloudformationAttribute: NetworkPathFound
        '''
        return typing.cast(aws_cdk.core.IResolvable, jsii.get(self, "attrNetworkPathFound"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrReturnPathComponents")
    def attr_return_path_components(self) -> aws_cdk.core.IResolvable:
        '''
        :cloudformationAttribute: ReturnPathComponents
        '''
        return typing.cast(aws_cdk.core.IResolvable, jsii.get(self, "attrReturnPathComponents"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrStartDate")
    def attr_start_date(self) -> builtins.str:
        '''
        :cloudformationAttribute: StartDate
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrStartDate"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrStatus")
    def attr_status(self) -> builtins.str:
        '''
        :cloudformationAttribute: Status
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrStatus"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrStatusMessage")
    def attr_status_message(self) -> builtins.str:
        '''
        :cloudformationAttribute: StatusMessage
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrStatusMessage"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::NetworkInsightsAnalysis.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightsanalysis.html#cfn-ec2-networkinsightsanalysis-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkInsightsPathId")
    def network_insights_path_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInsightsAnalysis.NetworkInsightsPathId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightsanalysis.html#cfn-ec2-networkinsightsanalysis-networkinsightspathid
        '''
        return typing.cast(builtins.str, jsii.get(self, "networkInsightsPathId"))

    @network_insights_path_id.setter
    def network_insights_path_id(self, value: builtins.str) -> None:
        jsii.set(self, "networkInsightsPathId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="filterInArns")
    def filter_in_arns(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::NetworkInsightsAnalysis.FilterInArns``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightsanalysis.html#cfn-ec2-networkinsightsanalysis-filterinarns
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "filterInArns"))

    @filter_in_arns.setter
    def filter_in_arns(self, value: typing.Optional[typing.List[builtins.str]]) -> None:
        jsii.set(self, "filterInArns", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis.AlternatePathHintProperty",
        jsii_struct_bases=[],
        name_mapping={"component_arn": "componentArn", "component_id": "componentId"},
    )
    class AlternatePathHintProperty:
        def __init__(
            self,
            *,
            component_arn: typing.Optional[builtins.str] = None,
            component_id: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param component_arn: ``CfnNetworkInsightsAnalysis.AlternatePathHintProperty.ComponentArn``.
            :param component_id: ``CfnNetworkInsightsAnalysis.AlternatePathHintProperty.ComponentId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-alternatepathhint.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if component_arn is not None:
                self._values["component_arn"] = component_arn
            if component_id is not None:
                self._values["component_id"] = component_id

        @builtins.property
        def component_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AlternatePathHintProperty.ComponentArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-alternatepathhint.html#cfn-ec2-networkinsightsanalysis-alternatepathhint-componentarn
            '''
            result = self._values.get("component_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def component_id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AlternatePathHintProperty.ComponentId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-alternatepathhint.html#cfn-ec2-networkinsightsanalysis-alternatepathhint-componentid
            '''
            result = self._values.get("component_id")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AlternatePathHintProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty",
        jsii_struct_bases=[],
        name_mapping={
            "cidr": "cidr",
            "egress": "egress",
            "port_range": "portRange",
            "protocol": "protocol",
            "rule_action": "ruleAction",
            "rule_number": "ruleNumber",
        },
    )
    class AnalysisAclRuleProperty:
        def __init__(
            self,
            *,
            cidr: typing.Optional[builtins.str] = None,
            egress: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            port_range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]] = None,
            protocol: typing.Optional[builtins.str] = None,
            rule_action: typing.Optional[builtins.str] = None,
            rule_number: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param cidr: ``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.Cidr``.
            :param egress: ``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.Egress``.
            :param port_range: ``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.PortRange``.
            :param protocol: ``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.Protocol``.
            :param rule_action: ``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.RuleAction``.
            :param rule_number: ``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.RuleNumber``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisaclrule.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if cidr is not None:
                self._values["cidr"] = cidr
            if egress is not None:
                self._values["egress"] = egress
            if port_range is not None:
                self._values["port_range"] = port_range
            if protocol is not None:
                self._values["protocol"] = protocol
            if rule_action is not None:
                self._values["rule_action"] = rule_action
            if rule_number is not None:
                self._values["rule_number"] = rule_number

        @builtins.property
        def cidr(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.Cidr``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisaclrule.html#cfn-ec2-networkinsightsanalysis-analysisaclrule-cidr
            '''
            result = self._values.get("cidr")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def egress(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.Egress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisaclrule.html#cfn-ec2-networkinsightsanalysis-analysisaclrule-egress
            '''
            result = self._values.get("egress")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def port_range(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]]:
            '''``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.PortRange``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisaclrule.html#cfn-ec2-networkinsightsanalysis-analysisaclrule-portrange
            '''
            result = self._values.get("port_range")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]], result)

        @builtins.property
        def protocol(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.Protocol``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisaclrule.html#cfn-ec2-networkinsightsanalysis-analysisaclrule-protocol
            '''
            result = self._values.get("protocol")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def rule_action(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.RuleAction``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisaclrule.html#cfn-ec2-networkinsightsanalysis-analysisaclrule-ruleaction
            '''
            result = self._values.get("rule_action")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def rule_number(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty.RuleNumber``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisaclrule.html#cfn-ec2-networkinsightsanalysis-analysisaclrule-rulenumber
            '''
            result = self._values.get("rule_number")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AnalysisAclRuleProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis.AnalysisComponentProperty",
        jsii_struct_bases=[],
        name_mapping={"arn": "arn", "id": "id"},
    )
    class AnalysisComponentProperty:
        def __init__(
            self,
            *,
            arn: typing.Optional[builtins.str] = None,
            id: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param arn: ``CfnNetworkInsightsAnalysis.AnalysisComponentProperty.Arn``.
            :param id: ``CfnNetworkInsightsAnalysis.AnalysisComponentProperty.Id``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysiscomponent.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if arn is not None:
                self._values["arn"] = arn
            if id is not None:
                self._values["id"] = id

        @builtins.property
        def arn(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisComponentProperty.Arn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysiscomponent.html#cfn-ec2-networkinsightsanalysis-analysiscomponent-arn
            '''
            result = self._values.get("arn")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisComponentProperty.Id``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysiscomponent.html#cfn-ec2-networkinsightsanalysis-analysiscomponent-id
            '''
            result = self._values.get("id")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AnalysisComponentProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis.AnalysisLoadBalancerListenerProperty",
        jsii_struct_bases=[],
        name_mapping={
            "instance_port": "instancePort",
            "load_balancer_port": "loadBalancerPort",
        },
    )
    class AnalysisLoadBalancerListenerProperty:
        def __init__(
            self,
            *,
            instance_port: typing.Optional[jsii.Number] = None,
            load_balancer_port: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param instance_port: ``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerListenerProperty.InstancePort``.
            :param load_balancer_port: ``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerListenerProperty.LoadBalancerPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisloadbalancerlistener.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if instance_port is not None:
                self._values["instance_port"] = instance_port
            if load_balancer_port is not None:
                self._values["load_balancer_port"] = load_balancer_port

        @builtins.property
        def instance_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerListenerProperty.InstancePort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisloadbalancerlistener.html#cfn-ec2-networkinsightsanalysis-analysisloadbalancerlistener-instanceport
            '''
            result = self._values.get("instance_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def load_balancer_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerListenerProperty.LoadBalancerPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisloadbalancerlistener.html#cfn-ec2-networkinsightsanalysis-analysisloadbalancerlistener-loadbalancerport
            '''
            result = self._values.get("load_balancer_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AnalysisLoadBalancerListenerProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty",
        jsii_struct_bases=[],
        name_mapping={
            "address": "address",
            "availability_zone": "availabilityZone",
            "instance": "instance",
            "port": "port",
        },
    )
    class AnalysisLoadBalancerTargetProperty:
        def __init__(
            self,
            *,
            address: typing.Optional[builtins.str] = None,
            availability_zone: typing.Optional[builtins.str] = None,
            instance: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            port: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param address: ``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty.Address``.
            :param availability_zone: ``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty.AvailabilityZone``.
            :param instance: ``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty.Instance``.
            :param port: ``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisloadbalancertarget.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if address is not None:
                self._values["address"] = address
            if availability_zone is not None:
                self._values["availability_zone"] = availability_zone
            if instance is not None:
                self._values["instance"] = instance
            if port is not None:
                self._values["port"] = port

        @builtins.property
        def address(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty.Address``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisloadbalancertarget.html#cfn-ec2-networkinsightsanalysis-analysisloadbalancertarget-address
            '''
            result = self._values.get("address")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def availability_zone(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty.AvailabilityZone``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisloadbalancertarget.html#cfn-ec2-networkinsightsanalysis-analysisloadbalancertarget-availabilityzone
            '''
            result = self._values.get("availability_zone")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def instance(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty.Instance``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisloadbalancertarget.html#cfn-ec2-networkinsightsanalysis-analysisloadbalancertarget-instance
            '''
            result = self._values.get("instance")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def port(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisloadbalancertarget.html#cfn-ec2-networkinsightsanalysis-analysisloadbalancertarget-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AnalysisLoadBalancerTargetProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty",
        jsii_struct_bases=[],
        name_mapping={
            "destination_addresses": "destinationAddresses",
            "destination_port_ranges": "destinationPortRanges",
            "protocol": "protocol",
            "source_addresses": "sourceAddresses",
            "source_port_ranges": "sourcePortRanges",
        },
    )
    class AnalysisPacketHeaderProperty:
        def __init__(
            self,
            *,
            destination_addresses: typing.Optional[typing.List[builtins.str]] = None,
            destination_port_ranges: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]]]] = None,
            protocol: typing.Optional[builtins.str] = None,
            source_addresses: typing.Optional[typing.List[builtins.str]] = None,
            source_port_ranges: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]]]] = None,
        ) -> None:
            '''
            :param destination_addresses: ``CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty.DestinationAddresses``.
            :param destination_port_ranges: ``CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty.DestinationPortRanges``.
            :param protocol: ``CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty.Protocol``.
            :param source_addresses: ``CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty.SourceAddresses``.
            :param source_port_ranges: ``CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty.SourcePortRanges``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysispacketheader.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if destination_addresses is not None:
                self._values["destination_addresses"] = destination_addresses
            if destination_port_ranges is not None:
                self._values["destination_port_ranges"] = destination_port_ranges
            if protocol is not None:
                self._values["protocol"] = protocol
            if source_addresses is not None:
                self._values["source_addresses"] = source_addresses
            if source_port_ranges is not None:
                self._values["source_port_ranges"] = source_port_ranges

        @builtins.property
        def destination_addresses(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty.DestinationAddresses``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysispacketheader.html#cfn-ec2-networkinsightsanalysis-analysispacketheader-destinationaddresses
            '''
            result = self._values.get("destination_addresses")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def destination_port_ranges(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]]]]:
            '''``CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty.DestinationPortRanges``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysispacketheader.html#cfn-ec2-networkinsightsanalysis-analysispacketheader-destinationportranges
            '''
            result = self._values.get("destination_port_ranges")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]]]], result)

        @builtins.property
        def protocol(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty.Protocol``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysispacketheader.html#cfn-ec2-networkinsightsanalysis-analysispacketheader-protocol
            '''
            result = self._values.get("protocol")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def source_addresses(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty.SourceAddresses``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysispacketheader.html#cfn-ec2-networkinsightsanalysis-analysispacketheader-sourceaddresses
            '''
            result = self._values.get("source_addresses")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def source_port_ranges(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]]]]:
            '''``CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty.SourcePortRanges``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysispacketheader.html#cfn-ec2-networkinsightsanalysis-analysispacketheader-sourceportranges
            '''
            result = self._values.get("source_port_ranges")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AnalysisPacketHeaderProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty",
        jsii_struct_bases=[],
        name_mapping={
            "destination_cidr": "destinationCidr",
            "destination_prefix_list_id": "destinationPrefixListId",
            "egress_only_internet_gateway_id": "egressOnlyInternetGatewayId",
            "gateway_id": "gatewayId",
            "instance_id": "instanceId",
            "nat_gateway_id": "natGatewayId",
            "network_interface_id": "networkInterfaceId",
            "origin": "origin",
            "transit_gateway_id": "transitGatewayId",
            "vpc_peering_connection_id": "vpcPeeringConnectionId",
        },
    )
    class AnalysisRouteTableRouteProperty:
        def __init__(
            self,
            *,
            destination_cidr: typing.Optional[builtins.str] = None,
            destination_prefix_list_id: typing.Optional[builtins.str] = None,
            egress_only_internet_gateway_id: typing.Optional[builtins.str] = None,
            gateway_id: typing.Optional[builtins.str] = None,
            instance_id: typing.Optional[builtins.str] = None,
            nat_gateway_id: typing.Optional[builtins.str] = None,
            network_interface_id: typing.Optional[builtins.str] = None,
            origin: typing.Optional[builtins.str] = None,
            transit_gateway_id: typing.Optional[builtins.str] = None,
            vpc_peering_connection_id: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param destination_cidr: ``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.destinationCidr``.
            :param destination_prefix_list_id: ``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.destinationPrefixListId``.
            :param egress_only_internet_gateway_id: ``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.egressOnlyInternetGatewayId``.
            :param gateway_id: ``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.gatewayId``.
            :param instance_id: ``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.instanceId``.
            :param nat_gateway_id: ``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.NatGatewayId``.
            :param network_interface_id: ``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.NetworkInterfaceId``.
            :param origin: ``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.Origin``.
            :param transit_gateway_id: ``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.TransitGatewayId``.
            :param vpc_peering_connection_id: ``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.VpcPeeringConnectionId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisroutetableroute.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if destination_cidr is not None:
                self._values["destination_cidr"] = destination_cidr
            if destination_prefix_list_id is not None:
                self._values["destination_prefix_list_id"] = destination_prefix_list_id
            if egress_only_internet_gateway_id is not None:
                self._values["egress_only_internet_gateway_id"] = egress_only_internet_gateway_id
            if gateway_id is not None:
                self._values["gateway_id"] = gateway_id
            if instance_id is not None:
                self._values["instance_id"] = instance_id
            if nat_gateway_id is not None:
                self._values["nat_gateway_id"] = nat_gateway_id
            if network_interface_id is not None:
                self._values["network_interface_id"] = network_interface_id
            if origin is not None:
                self._values["origin"] = origin
            if transit_gateway_id is not None:
                self._values["transit_gateway_id"] = transit_gateway_id
            if vpc_peering_connection_id is not None:
                self._values["vpc_peering_connection_id"] = vpc_peering_connection_id

        @builtins.property
        def destination_cidr(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.destinationCidr``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisroutetableroute.html#cfn-ec2-networkinsightsanalysis-analysisroutetableroute-destinationcidr
            '''
            result = self._values.get("destination_cidr")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def destination_prefix_list_id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.destinationPrefixListId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisroutetableroute.html#cfn-ec2-networkinsightsanalysis-analysisroutetableroute-destinationprefixlistid
            '''
            result = self._values.get("destination_prefix_list_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def egress_only_internet_gateway_id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.egressOnlyInternetGatewayId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisroutetableroute.html#cfn-ec2-networkinsightsanalysis-analysisroutetableroute-egressonlyinternetgatewayid
            '''
            result = self._values.get("egress_only_internet_gateway_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def gateway_id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.gatewayId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisroutetableroute.html#cfn-ec2-networkinsightsanalysis-analysisroutetableroute-gatewayid
            '''
            result = self._values.get("gateway_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def instance_id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.instanceId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisroutetableroute.html#cfn-ec2-networkinsightsanalysis-analysisroutetableroute-instanceid
            '''
            result = self._values.get("instance_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def nat_gateway_id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.NatGatewayId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisroutetableroute.html#cfn-ec2-networkinsightsanalysis-analysisroutetableroute-natgatewayid
            '''
            result = self._values.get("nat_gateway_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def network_interface_id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.NetworkInterfaceId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisroutetableroute.html#cfn-ec2-networkinsightsanalysis-analysisroutetableroute-networkinterfaceid
            '''
            result = self._values.get("network_interface_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def origin(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.Origin``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisroutetableroute.html#cfn-ec2-networkinsightsanalysis-analysisroutetableroute-origin
            '''
            result = self._values.get("origin")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def transit_gateway_id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.TransitGatewayId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisroutetableroute.html#cfn-ec2-networkinsightsanalysis-analysisroutetableroute-transitgatewayid
            '''
            result = self._values.get("transit_gateway_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def vpc_peering_connection_id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty.VpcPeeringConnectionId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysisroutetableroute.html#cfn-ec2-networkinsightsanalysis-analysisroutetableroute-vpcpeeringconnectionid
            '''
            result = self._values.get("vpc_peering_connection_id")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AnalysisRouteTableRouteProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty",
        jsii_struct_bases=[],
        name_mapping={
            "cidr": "cidr",
            "direction": "direction",
            "port_range": "portRange",
            "prefix_list_id": "prefixListId",
            "protocol": "protocol",
            "security_group_id": "securityGroupId",
        },
    )
    class AnalysisSecurityGroupRuleProperty:
        def __init__(
            self,
            *,
            cidr: typing.Optional[builtins.str] = None,
            direction: typing.Optional[builtins.str] = None,
            port_range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]] = None,
            prefix_list_id: typing.Optional[builtins.str] = None,
            protocol: typing.Optional[builtins.str] = None,
            security_group_id: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param cidr: ``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.Cidr``.
            :param direction: ``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.Direction``.
            :param port_range: ``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.PortRange``.
            :param prefix_list_id: ``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.PrefixListId``.
            :param protocol: ``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.Protocol``.
            :param security_group_id: ``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.SecurityGroupId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysissecuritygrouprule.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if cidr is not None:
                self._values["cidr"] = cidr
            if direction is not None:
                self._values["direction"] = direction
            if port_range is not None:
                self._values["port_range"] = port_range
            if prefix_list_id is not None:
                self._values["prefix_list_id"] = prefix_list_id
            if protocol is not None:
                self._values["protocol"] = protocol
            if security_group_id is not None:
                self._values["security_group_id"] = security_group_id

        @builtins.property
        def cidr(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.Cidr``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysissecuritygrouprule.html#cfn-ec2-networkinsightsanalysis-analysissecuritygrouprule-cidr
            '''
            result = self._values.get("cidr")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def direction(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.Direction``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysissecuritygrouprule.html#cfn-ec2-networkinsightsanalysis-analysissecuritygrouprule-direction
            '''
            result = self._values.get("direction")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def port_range(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]]:
            '''``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.PortRange``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysissecuritygrouprule.html#cfn-ec2-networkinsightsanalysis-analysissecuritygrouprule-portrange
            '''
            result = self._values.get("port_range")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]], result)

        @builtins.property
        def prefix_list_id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.PrefixListId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysissecuritygrouprule.html#cfn-ec2-networkinsightsanalysis-analysissecuritygrouprule-prefixlistid
            '''
            result = self._values.get("prefix_list_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def protocol(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.Protocol``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysissecuritygrouprule.html#cfn-ec2-networkinsightsanalysis-analysissecuritygrouprule-protocol
            '''
            result = self._values.get("protocol")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def security_group_id(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty.SecurityGroupId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-analysissecuritygrouprule.html#cfn-ec2-networkinsightsanalysis-analysissecuritygrouprule-securitygroupid
            '''
            result = self._values.get("security_group_id")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "AnalysisSecurityGroupRuleProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis.ExplanationProperty",
        jsii_struct_bases=[],
        name_mapping={
            "acl": "acl",
            "acl_rule": "aclRule",
            "address": "address",
            "addresses": "addresses",
            "attached_to": "attachedTo",
            "availability_zones": "availabilityZones",
            "cidrs": "cidrs",
            "classic_load_balancer_listener": "classicLoadBalancerListener",
            "component": "component",
            "customer_gateway": "customerGateway",
            "destination": "destination",
            "destination_vpc": "destinationVpc",
            "direction": "direction",
            "elastic_load_balancer_listener": "elasticLoadBalancerListener",
            "explanation_code": "explanationCode",
            "ingress_route_table": "ingressRouteTable",
            "internet_gateway": "internetGateway",
            "load_balancer_arn": "loadBalancerArn",
            "load_balancer_listener_port": "loadBalancerListenerPort",
            "load_balancer_target": "loadBalancerTarget",
            "load_balancer_target_group": "loadBalancerTargetGroup",
            "load_balancer_target_groups": "loadBalancerTargetGroups",
            "load_balancer_target_port": "loadBalancerTargetPort",
            "missing_component": "missingComponent",
            "nat_gateway": "natGateway",
            "network_interface": "networkInterface",
            "packet_field": "packetField",
            "port": "port",
            "port_ranges": "portRanges",
            "prefix_list": "prefixList",
            "protocols": "protocols",
            "route_table": "routeTable",
            "route_table_route": "routeTableRoute",
            "security_group": "securityGroup",
            "security_group_rule": "securityGroupRule",
            "security_groups": "securityGroups",
            "source_vpc": "sourceVpc",
            "state": "state",
            "subnet": "subnet",
            "subnet_route_table": "subnetRouteTable",
            "vpc": "vpc",
            "vpc_endpoint": "vpcEndpoint",
            "vpc_peering_connection": "vpcPeeringConnection",
            "vpn_connection": "vpnConnection",
            "vpn_gateway": "vpnGateway",
        },
    )
    class ExplanationProperty:
        def __init__(
            self,
            *,
            acl: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            acl_rule: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty"]] = None,
            address: typing.Optional[builtins.str] = None,
            addresses: typing.Optional[typing.List[builtins.str]] = None,
            attached_to: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            availability_zones: typing.Optional[typing.List[builtins.str]] = None,
            cidrs: typing.Optional[typing.List[builtins.str]] = None,
            classic_load_balancer_listener: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisLoadBalancerListenerProperty"]] = None,
            component: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            customer_gateway: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            destination: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            destination_vpc: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            direction: typing.Optional[builtins.str] = None,
            elastic_load_balancer_listener: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            explanation_code: typing.Optional[builtins.str] = None,
            ingress_route_table: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            internet_gateway: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            load_balancer_arn: typing.Optional[builtins.str] = None,
            load_balancer_listener_port: typing.Optional[jsii.Number] = None,
            load_balancer_target: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty"]] = None,
            load_balancer_target_group: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            load_balancer_target_groups: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]]] = None,
            load_balancer_target_port: typing.Optional[jsii.Number] = None,
            missing_component: typing.Optional[builtins.str] = None,
            nat_gateway: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            network_interface: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            packet_field: typing.Optional[builtins.str] = None,
            port: typing.Optional[jsii.Number] = None,
            port_ranges: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]]]] = None,
            prefix_list: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            protocols: typing.Optional[typing.List[builtins.str]] = None,
            route_table: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            route_table_route: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty"]] = None,
            security_group: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            security_group_rule: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty"]] = None,
            security_groups: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]]] = None,
            source_vpc: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            state: typing.Optional[builtins.str] = None,
            subnet: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            subnet_route_table: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            vpc: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            vpc_endpoint: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            vpc_peering_connection: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            vpn_connection: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            vpn_gateway: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
        ) -> None:
            '''
            :param acl: ``CfnNetworkInsightsAnalysis.ExplanationProperty.Acl``.
            :param acl_rule: ``CfnNetworkInsightsAnalysis.ExplanationProperty.AclRule``.
            :param address: ``CfnNetworkInsightsAnalysis.ExplanationProperty.Address``.
            :param addresses: ``CfnNetworkInsightsAnalysis.ExplanationProperty.Addresses``.
            :param attached_to: ``CfnNetworkInsightsAnalysis.ExplanationProperty.AttachedTo``.
            :param availability_zones: ``CfnNetworkInsightsAnalysis.ExplanationProperty.AvailabilityZones``.
            :param cidrs: ``CfnNetworkInsightsAnalysis.ExplanationProperty.Cidrs``.
            :param classic_load_balancer_listener: ``CfnNetworkInsightsAnalysis.ExplanationProperty.ClassicLoadBalancerListener``.
            :param component: ``CfnNetworkInsightsAnalysis.ExplanationProperty.Component``.
            :param customer_gateway: ``CfnNetworkInsightsAnalysis.ExplanationProperty.CustomerGateway``.
            :param destination: ``CfnNetworkInsightsAnalysis.ExplanationProperty.Destination``.
            :param destination_vpc: ``CfnNetworkInsightsAnalysis.ExplanationProperty.DestinationVpc``.
            :param direction: ``CfnNetworkInsightsAnalysis.ExplanationProperty.Direction``.
            :param elastic_load_balancer_listener: ``CfnNetworkInsightsAnalysis.ExplanationProperty.ElasticLoadBalancerListener``.
            :param explanation_code: ``CfnNetworkInsightsAnalysis.ExplanationProperty.ExplanationCode``.
            :param ingress_route_table: ``CfnNetworkInsightsAnalysis.ExplanationProperty.IngressRouteTable``.
            :param internet_gateway: ``CfnNetworkInsightsAnalysis.ExplanationProperty.InternetGateway``.
            :param load_balancer_arn: ``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerArn``.
            :param load_balancer_listener_port: ``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerListenerPort``.
            :param load_balancer_target: ``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerTarget``.
            :param load_balancer_target_group: ``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerTargetGroup``.
            :param load_balancer_target_groups: ``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerTargetGroups``.
            :param load_balancer_target_port: ``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerTargetPort``.
            :param missing_component: ``CfnNetworkInsightsAnalysis.ExplanationProperty.MissingComponent``.
            :param nat_gateway: ``CfnNetworkInsightsAnalysis.ExplanationProperty.NatGateway``.
            :param network_interface: ``CfnNetworkInsightsAnalysis.ExplanationProperty.NetworkInterface``.
            :param packet_field: ``CfnNetworkInsightsAnalysis.ExplanationProperty.PacketField``.
            :param port: ``CfnNetworkInsightsAnalysis.ExplanationProperty.Port``.
            :param port_ranges: ``CfnNetworkInsightsAnalysis.ExplanationProperty.PortRanges``.
            :param prefix_list: ``CfnNetworkInsightsAnalysis.ExplanationProperty.PrefixList``.
            :param protocols: ``CfnNetworkInsightsAnalysis.ExplanationProperty.Protocols``.
            :param route_table: ``CfnNetworkInsightsAnalysis.ExplanationProperty.RouteTable``.
            :param route_table_route: ``CfnNetworkInsightsAnalysis.ExplanationProperty.RouteTableRoute``.
            :param security_group: ``CfnNetworkInsightsAnalysis.ExplanationProperty.SecurityGroup``.
            :param security_group_rule: ``CfnNetworkInsightsAnalysis.ExplanationProperty.SecurityGroupRule``.
            :param security_groups: ``CfnNetworkInsightsAnalysis.ExplanationProperty.SecurityGroups``.
            :param source_vpc: ``CfnNetworkInsightsAnalysis.ExplanationProperty.SourceVpc``.
            :param state: ``CfnNetworkInsightsAnalysis.ExplanationProperty.State``.
            :param subnet: ``CfnNetworkInsightsAnalysis.ExplanationProperty.Subnet``.
            :param subnet_route_table: ``CfnNetworkInsightsAnalysis.ExplanationProperty.SubnetRouteTable``.
            :param vpc: ``CfnNetworkInsightsAnalysis.ExplanationProperty.Vpc``.
            :param vpc_endpoint: ``CfnNetworkInsightsAnalysis.ExplanationProperty.vpcEndpoint``.
            :param vpc_peering_connection: ``CfnNetworkInsightsAnalysis.ExplanationProperty.VpcPeeringConnection``.
            :param vpn_connection: ``CfnNetworkInsightsAnalysis.ExplanationProperty.VpnConnection``.
            :param vpn_gateway: ``CfnNetworkInsightsAnalysis.ExplanationProperty.VpnGateway``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if acl is not None:
                self._values["acl"] = acl
            if acl_rule is not None:
                self._values["acl_rule"] = acl_rule
            if address is not None:
                self._values["address"] = address
            if addresses is not None:
                self._values["addresses"] = addresses
            if attached_to is not None:
                self._values["attached_to"] = attached_to
            if availability_zones is not None:
                self._values["availability_zones"] = availability_zones
            if cidrs is not None:
                self._values["cidrs"] = cidrs
            if classic_load_balancer_listener is not None:
                self._values["classic_load_balancer_listener"] = classic_load_balancer_listener
            if component is not None:
                self._values["component"] = component
            if customer_gateway is not None:
                self._values["customer_gateway"] = customer_gateway
            if destination is not None:
                self._values["destination"] = destination
            if destination_vpc is not None:
                self._values["destination_vpc"] = destination_vpc
            if direction is not None:
                self._values["direction"] = direction
            if elastic_load_balancer_listener is not None:
                self._values["elastic_load_balancer_listener"] = elastic_load_balancer_listener
            if explanation_code is not None:
                self._values["explanation_code"] = explanation_code
            if ingress_route_table is not None:
                self._values["ingress_route_table"] = ingress_route_table
            if internet_gateway is not None:
                self._values["internet_gateway"] = internet_gateway
            if load_balancer_arn is not None:
                self._values["load_balancer_arn"] = load_balancer_arn
            if load_balancer_listener_port is not None:
                self._values["load_balancer_listener_port"] = load_balancer_listener_port
            if load_balancer_target is not None:
                self._values["load_balancer_target"] = load_balancer_target
            if load_balancer_target_group is not None:
                self._values["load_balancer_target_group"] = load_balancer_target_group
            if load_balancer_target_groups is not None:
                self._values["load_balancer_target_groups"] = load_balancer_target_groups
            if load_balancer_target_port is not None:
                self._values["load_balancer_target_port"] = load_balancer_target_port
            if missing_component is not None:
                self._values["missing_component"] = missing_component
            if nat_gateway is not None:
                self._values["nat_gateway"] = nat_gateway
            if network_interface is not None:
                self._values["network_interface"] = network_interface
            if packet_field is not None:
                self._values["packet_field"] = packet_field
            if port is not None:
                self._values["port"] = port
            if port_ranges is not None:
                self._values["port_ranges"] = port_ranges
            if prefix_list is not None:
                self._values["prefix_list"] = prefix_list
            if protocols is not None:
                self._values["protocols"] = protocols
            if route_table is not None:
                self._values["route_table"] = route_table
            if route_table_route is not None:
                self._values["route_table_route"] = route_table_route
            if security_group is not None:
                self._values["security_group"] = security_group
            if security_group_rule is not None:
                self._values["security_group_rule"] = security_group_rule
            if security_groups is not None:
                self._values["security_groups"] = security_groups
            if source_vpc is not None:
                self._values["source_vpc"] = source_vpc
            if state is not None:
                self._values["state"] = state
            if subnet is not None:
                self._values["subnet"] = subnet
            if subnet_route_table is not None:
                self._values["subnet_route_table"] = subnet_route_table
            if vpc is not None:
                self._values["vpc"] = vpc
            if vpc_endpoint is not None:
                self._values["vpc_endpoint"] = vpc_endpoint
            if vpc_peering_connection is not None:
                self._values["vpc_peering_connection"] = vpc_peering_connection
            if vpn_connection is not None:
                self._values["vpn_connection"] = vpn_connection
            if vpn_gateway is not None:
                self._values["vpn_gateway"] = vpn_gateway

        @builtins.property
        def acl(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.Acl``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-acl
            '''
            result = self._values.get("acl")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def acl_rule(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.AclRule``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-aclrule
            '''
            result = self._values.get("acl_rule")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty"]], result)

        @builtins.property
        def address(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.Address``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-address
            '''
            result = self._values.get("address")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def addresses(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.Addresses``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-addresses
            '''
            result = self._values.get("addresses")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def attached_to(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.AttachedTo``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-attachedto
            '''
            result = self._values.get("attached_to")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def availability_zones(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.AvailabilityZones``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-availabilityzones
            '''
            result = self._values.get("availability_zones")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def cidrs(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.Cidrs``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-cidrs
            '''
            result = self._values.get("cidrs")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def classic_load_balancer_listener(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisLoadBalancerListenerProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.ClassicLoadBalancerListener``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-classicloadbalancerlistener
            '''
            result = self._values.get("classic_load_balancer_listener")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisLoadBalancerListenerProperty"]], result)

        @builtins.property
        def component(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.Component``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-component
            '''
            result = self._values.get("component")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def customer_gateway(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.CustomerGateway``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-customergateway
            '''
            result = self._values.get("customer_gateway")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def destination(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.Destination``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-destination
            '''
            result = self._values.get("destination")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def destination_vpc(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.DestinationVpc``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-destinationvpc
            '''
            result = self._values.get("destination_vpc")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def direction(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.Direction``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-direction
            '''
            result = self._values.get("direction")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def elastic_load_balancer_listener(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.ElasticLoadBalancerListener``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-elasticloadbalancerlistener
            '''
            result = self._values.get("elastic_load_balancer_listener")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def explanation_code(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.ExplanationCode``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-explanationcode
            '''
            result = self._values.get("explanation_code")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def ingress_route_table(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.IngressRouteTable``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-ingressroutetable
            '''
            result = self._values.get("ingress_route_table")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def internet_gateway(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.InternetGateway``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-internetgateway
            '''
            result = self._values.get("internet_gateway")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def load_balancer_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-loadbalancerarn
            '''
            result = self._values.get("load_balancer_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def load_balancer_listener_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerListenerPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-loadbalancerlistenerport
            '''
            result = self._values.get("load_balancer_listener_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def load_balancer_target(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerTarget``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-loadbalancertarget
            '''
            result = self._values.get("load_balancer_target")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisLoadBalancerTargetProperty"]], result)

        @builtins.property
        def load_balancer_target_group(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerTargetGroup``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-loadbalancertargetgroup
            '''
            result = self._values.get("load_balancer_target_group")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def load_balancer_target_groups(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerTargetGroups``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-loadbalancertargetgroups
            '''
            result = self._values.get("load_balancer_target_groups")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]]], result)

        @builtins.property
        def load_balancer_target_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.LoadBalancerTargetPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-loadbalancertargetport
            '''
            result = self._values.get("load_balancer_target_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def missing_component(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.MissingComponent``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-missingcomponent
            '''
            result = self._values.get("missing_component")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def nat_gateway(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.NatGateway``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-natgateway
            '''
            result = self._values.get("nat_gateway")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def network_interface(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.NetworkInterface``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-networkinterface
            '''
            result = self._values.get("network_interface")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def packet_field(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.PacketField``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-packetfield
            '''
            result = self._values.get("packet_field")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def port(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.Port``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-port
            '''
            result = self._values.get("port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def port_ranges(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]]]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.PortRanges``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-portranges
            '''
            result = self._values.get("port_ranges")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.PortRangeProperty"]]]], result)

        @builtins.property
        def prefix_list(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.PrefixList``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-prefixlist
            '''
            result = self._values.get("prefix_list")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def protocols(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.Protocols``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-protocols
            '''
            result = self._values.get("protocols")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def route_table(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.RouteTable``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-routetable
            '''
            result = self._values.get("route_table")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def route_table_route(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.RouteTableRoute``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-routetableroute
            '''
            result = self._values.get("route_table_route")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty"]], result)

        @builtins.property
        def security_group(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.SecurityGroup``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-securitygroup
            '''
            result = self._values.get("security_group")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def security_group_rule(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.SecurityGroupRule``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-securitygrouprule
            '''
            result = self._values.get("security_group_rule")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty"]], result)

        @builtins.property
        def security_groups(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.SecurityGroups``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-securitygroups
            '''
            result = self._values.get("security_groups")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]]], result)

        @builtins.property
        def source_vpc(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.SourceVpc``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-sourcevpc
            '''
            result = self._values.get("source_vpc")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def state(self) -> typing.Optional[builtins.str]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.State``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-state
            '''
            result = self._values.get("state")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def subnet(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.Subnet``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-subnet
            '''
            result = self._values.get("subnet")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def subnet_route_table(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.SubnetRouteTable``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-subnetroutetable
            '''
            result = self._values.get("subnet_route_table")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def vpc(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.Vpc``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-vpc
            '''
            result = self._values.get("vpc")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def vpc_endpoint(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.vpcEndpoint``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-vpcendpoint
            '''
            result = self._values.get("vpc_endpoint")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def vpc_peering_connection(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.VpcPeeringConnection``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-vpcpeeringconnection
            '''
            result = self._values.get("vpc_peering_connection")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def vpn_connection(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.VpnConnection``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-vpnconnection
            '''
            result = self._values.get("vpn_connection")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def vpn_gateway(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.ExplanationProperty.VpnGateway``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-explanation.html#cfn-ec2-networkinsightsanalysis-explanation-vpngateway
            '''
            result = self._values.get("vpn_gateway")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ExplanationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis.PathComponentProperty",
        jsii_struct_bases=[],
        name_mapping={
            "acl_rule": "aclRule",
            "component": "component",
            "destination_vpc": "destinationVpc",
            "inbound_header": "inboundHeader",
            "outbound_header": "outboundHeader",
            "route_table_route": "routeTableRoute",
            "security_group_rule": "securityGroupRule",
            "sequence_number": "sequenceNumber",
            "source_vpc": "sourceVpc",
            "subnet": "subnet",
            "vpc": "vpc",
        },
    )
    class PathComponentProperty:
        def __init__(
            self,
            *,
            acl_rule: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty"]] = None,
            component: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            destination_vpc: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            inbound_header: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty"]] = None,
            outbound_header: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty"]] = None,
            route_table_route: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty"]] = None,
            security_group_rule: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty"]] = None,
            sequence_number: typing.Optional[jsii.Number] = None,
            source_vpc: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            subnet: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
            vpc: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]] = None,
        ) -> None:
            '''
            :param acl_rule: ``CfnNetworkInsightsAnalysis.PathComponentProperty.AclRule``.
            :param component: ``CfnNetworkInsightsAnalysis.PathComponentProperty.Component``.
            :param destination_vpc: ``CfnNetworkInsightsAnalysis.PathComponentProperty.DestinationVpc``.
            :param inbound_header: ``CfnNetworkInsightsAnalysis.PathComponentProperty.InboundHeader``.
            :param outbound_header: ``CfnNetworkInsightsAnalysis.PathComponentProperty.OutboundHeader``.
            :param route_table_route: ``CfnNetworkInsightsAnalysis.PathComponentProperty.RouteTableRoute``.
            :param security_group_rule: ``CfnNetworkInsightsAnalysis.PathComponentProperty.SecurityGroupRule``.
            :param sequence_number: ``CfnNetworkInsightsAnalysis.PathComponentProperty.SequenceNumber``.
            :param source_vpc: ``CfnNetworkInsightsAnalysis.PathComponentProperty.SourceVpc``.
            :param subnet: ``CfnNetworkInsightsAnalysis.PathComponentProperty.Subnet``.
            :param vpc: ``CfnNetworkInsightsAnalysis.PathComponentProperty.Vpc``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if acl_rule is not None:
                self._values["acl_rule"] = acl_rule
            if component is not None:
                self._values["component"] = component
            if destination_vpc is not None:
                self._values["destination_vpc"] = destination_vpc
            if inbound_header is not None:
                self._values["inbound_header"] = inbound_header
            if outbound_header is not None:
                self._values["outbound_header"] = outbound_header
            if route_table_route is not None:
                self._values["route_table_route"] = route_table_route
            if security_group_rule is not None:
                self._values["security_group_rule"] = security_group_rule
            if sequence_number is not None:
                self._values["sequence_number"] = sequence_number
            if source_vpc is not None:
                self._values["source_vpc"] = source_vpc
            if subnet is not None:
                self._values["subnet"] = subnet
            if vpc is not None:
                self._values["vpc"] = vpc

        @builtins.property
        def acl_rule(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty"]]:
            '''``CfnNetworkInsightsAnalysis.PathComponentProperty.AclRule``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html#cfn-ec2-networkinsightsanalysis-pathcomponent-aclrule
            '''
            result = self._values.get("acl_rule")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisAclRuleProperty"]], result)

        @builtins.property
        def component(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.PathComponentProperty.Component``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html#cfn-ec2-networkinsightsanalysis-pathcomponent-component
            '''
            result = self._values.get("component")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def destination_vpc(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.PathComponentProperty.DestinationVpc``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html#cfn-ec2-networkinsightsanalysis-pathcomponent-destinationvpc
            '''
            result = self._values.get("destination_vpc")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def inbound_header(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty"]]:
            '''``CfnNetworkInsightsAnalysis.PathComponentProperty.InboundHeader``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html#cfn-ec2-networkinsightsanalysis-pathcomponent-inboundheader
            '''
            result = self._values.get("inbound_header")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty"]], result)

        @builtins.property
        def outbound_header(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty"]]:
            '''``CfnNetworkInsightsAnalysis.PathComponentProperty.OutboundHeader``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html#cfn-ec2-networkinsightsanalysis-pathcomponent-outboundheader
            '''
            result = self._values.get("outbound_header")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisPacketHeaderProperty"]], result)

        @builtins.property
        def route_table_route(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty"]]:
            '''``CfnNetworkInsightsAnalysis.PathComponentProperty.RouteTableRoute``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html#cfn-ec2-networkinsightsanalysis-pathcomponent-routetableroute
            '''
            result = self._values.get("route_table_route")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisRouteTableRouteProperty"]], result)

        @builtins.property
        def security_group_rule(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty"]]:
            '''``CfnNetworkInsightsAnalysis.PathComponentProperty.SecurityGroupRule``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html#cfn-ec2-networkinsightsanalysis-pathcomponent-securitygrouprule
            '''
            result = self._values.get("security_group_rule")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisSecurityGroupRuleProperty"]], result)

        @builtins.property
        def sequence_number(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkInsightsAnalysis.PathComponentProperty.SequenceNumber``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html#cfn-ec2-networkinsightsanalysis-pathcomponent-sequencenumber
            '''
            result = self._values.get("sequence_number")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def source_vpc(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.PathComponentProperty.SourceVpc``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html#cfn-ec2-networkinsightsanalysis-pathcomponent-sourcevpc
            '''
            result = self._values.get("source_vpc")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def subnet(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.PathComponentProperty.Subnet``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html#cfn-ec2-networkinsightsanalysis-pathcomponent-subnet
            '''
            result = self._values.get("subnet")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        @builtins.property
        def vpc(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]]:
            '''``CfnNetworkInsightsAnalysis.PathComponentProperty.Vpc``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-pathcomponent.html#cfn-ec2-networkinsightsanalysis-pathcomponent-vpc
            '''
            result = self._values.get("vpc")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInsightsAnalysis.AnalysisComponentProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PathComponentProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysis.PortRangeProperty",
        jsii_struct_bases=[],
        name_mapping={"from_": "from", "to": "to"},
    )
    class PortRangeProperty:
        def __init__(
            self,
            *,
            from_: typing.Optional[jsii.Number] = None,
            to: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param from_: ``CfnNetworkInsightsAnalysis.PortRangeProperty.From``.
            :param to: ``CfnNetworkInsightsAnalysis.PortRangeProperty.To``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-portrange.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if from_ is not None:
                self._values["from_"] = from_
            if to is not None:
                self._values["to"] = to

        @builtins.property
        def from_(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkInsightsAnalysis.PortRangeProperty.From``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-portrange.html#cfn-ec2-networkinsightsanalysis-portrange-from
            '''
            result = self._values.get("from_")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def to(self) -> typing.Optional[jsii.Number]:
            '''``CfnNetworkInsightsAnalysis.PortRangeProperty.To``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinsightsanalysis-portrange.html#cfn-ec2-networkinsightsanalysis-portrange-to
            '''
            result = self._values.get("to")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PortRangeProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsAnalysisProps",
    jsii_struct_bases=[],
    name_mapping={
        "network_insights_path_id": "networkInsightsPathId",
        "filter_in_arns": "filterInArns",
        "tags": "tags",
    },
)
class CfnNetworkInsightsAnalysisProps:
    def __init__(
        self,
        *,
        network_insights_path_id: builtins.str,
        filter_in_arns: typing.Optional[typing.List[builtins.str]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::NetworkInsightsAnalysis``.

        :param network_insights_path_id: ``AWS::EC2::NetworkInsightsAnalysis.NetworkInsightsPathId``.
        :param filter_in_arns: ``AWS::EC2::NetworkInsightsAnalysis.FilterInArns``.
        :param tags: ``AWS::EC2::NetworkInsightsAnalysis.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightsanalysis.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "network_insights_path_id": network_insights_path_id,
        }
        if filter_in_arns is not None:
            self._values["filter_in_arns"] = filter_in_arns
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def network_insights_path_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInsightsAnalysis.NetworkInsightsPathId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightsanalysis.html#cfn-ec2-networkinsightsanalysis-networkinsightspathid
        '''
        result = self._values.get("network_insights_path_id")
        assert result is not None, "Required property 'network_insights_path_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def filter_in_arns(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::NetworkInsightsAnalysis.FilterInArns``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightsanalysis.html#cfn-ec2-networkinsightsanalysis-filterinarns
        '''
        result = self._values.get("filter_in_arns")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::NetworkInsightsAnalysis.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightsanalysis.html#cfn-ec2-networkinsightsanalysis-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnNetworkInsightsAnalysisProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnNetworkInsightsPath(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsPath",
):
    '''A CloudFormation ``AWS::EC2::NetworkInsightsPath``.

    :cloudformationResource: AWS::EC2::NetworkInsightsPath
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        destination: builtins.str,
        protocol: builtins.str,
        source: builtins.str,
        destination_ip: typing.Optional[builtins.str] = None,
        destination_port: typing.Optional[jsii.Number] = None,
        source_ip: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::NetworkInsightsPath``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param destination: ``AWS::EC2::NetworkInsightsPath.Destination``.
        :param protocol: ``AWS::EC2::NetworkInsightsPath.Protocol``.
        :param source: ``AWS::EC2::NetworkInsightsPath.Source``.
        :param destination_ip: ``AWS::EC2::NetworkInsightsPath.DestinationIp``.
        :param destination_port: ``AWS::EC2::NetworkInsightsPath.DestinationPort``.
        :param source_ip: ``AWS::EC2::NetworkInsightsPath.SourceIp``.
        :param tags: ``AWS::EC2::NetworkInsightsPath.Tags``.
        '''
        props = CfnNetworkInsightsPathProps(
            destination=destination,
            protocol=protocol,
            source=source,
            destination_ip=destination_ip,
            destination_port=destination_port,
            source_ip=source_ip,
            tags=tags,
        )

        jsii.create(CfnNetworkInsightsPath, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrCreatedDate")
    def attr_created_date(self) -> builtins.str:
        '''
        :cloudformationAttribute: CreatedDate
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrCreatedDate"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrNetworkInsightsPathArn")
    def attr_network_insights_path_arn(self) -> builtins.str:
        '''
        :cloudformationAttribute: NetworkInsightsPathArn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrNetworkInsightsPathArn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrNetworkInsightsPathId")
    def attr_network_insights_path_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: NetworkInsightsPathId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrNetworkInsightsPathId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::NetworkInsightsPath.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destination")
    def destination(self) -> builtins.str:
        '''``AWS::EC2::NetworkInsightsPath.Destination``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-destination
        '''
        return typing.cast(builtins.str, jsii.get(self, "destination"))

    @destination.setter
    def destination(self, value: builtins.str) -> None:
        jsii.set(self, "destination", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="protocol")
    def protocol(self) -> builtins.str:
        '''``AWS::EC2::NetworkInsightsPath.Protocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-protocol
        '''
        return typing.cast(builtins.str, jsii.get(self, "protocol"))

    @protocol.setter
    def protocol(self, value: builtins.str) -> None:
        jsii.set(self, "protocol", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="source")
    def source(self) -> builtins.str:
        '''``AWS::EC2::NetworkInsightsPath.Source``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-source
        '''
        return typing.cast(builtins.str, jsii.get(self, "source"))

    @source.setter
    def source(self, value: builtins.str) -> None:
        jsii.set(self, "source", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationIp")
    def destination_ip(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkInsightsPath.DestinationIp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-destinationip
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "destinationIp"))

    @destination_ip.setter
    def destination_ip(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "destinationIp", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationPort")
    def destination_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::NetworkInsightsPath.DestinationPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-destinationport
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "destinationPort"))

    @destination_port.setter
    def destination_port(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "destinationPort", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sourceIp")
    def source_ip(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkInsightsPath.SourceIp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-sourceip
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "sourceIp"))

    @source_ip.setter
    def source_ip(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "sourceIp", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkInsightsPathProps",
    jsii_struct_bases=[],
    name_mapping={
        "destination": "destination",
        "protocol": "protocol",
        "source": "source",
        "destination_ip": "destinationIp",
        "destination_port": "destinationPort",
        "source_ip": "sourceIp",
        "tags": "tags",
    },
)
class CfnNetworkInsightsPathProps:
    def __init__(
        self,
        *,
        destination: builtins.str,
        protocol: builtins.str,
        source: builtins.str,
        destination_ip: typing.Optional[builtins.str] = None,
        destination_port: typing.Optional[jsii.Number] = None,
        source_ip: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::NetworkInsightsPath``.

        :param destination: ``AWS::EC2::NetworkInsightsPath.Destination``.
        :param protocol: ``AWS::EC2::NetworkInsightsPath.Protocol``.
        :param source: ``AWS::EC2::NetworkInsightsPath.Source``.
        :param destination_ip: ``AWS::EC2::NetworkInsightsPath.DestinationIp``.
        :param destination_port: ``AWS::EC2::NetworkInsightsPath.DestinationPort``.
        :param source_ip: ``AWS::EC2::NetworkInsightsPath.SourceIp``.
        :param tags: ``AWS::EC2::NetworkInsightsPath.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "destination": destination,
            "protocol": protocol,
            "source": source,
        }
        if destination_ip is not None:
            self._values["destination_ip"] = destination_ip
        if destination_port is not None:
            self._values["destination_port"] = destination_port
        if source_ip is not None:
            self._values["source_ip"] = source_ip
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def destination(self) -> builtins.str:
        '''``AWS::EC2::NetworkInsightsPath.Destination``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-destination
        '''
        result = self._values.get("destination")
        assert result is not None, "Required property 'destination' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def protocol(self) -> builtins.str:
        '''``AWS::EC2::NetworkInsightsPath.Protocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-protocol
        '''
        result = self._values.get("protocol")
        assert result is not None, "Required property 'protocol' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def source(self) -> builtins.str:
        '''``AWS::EC2::NetworkInsightsPath.Source``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-source
        '''
        result = self._values.get("source")
        assert result is not None, "Required property 'source' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def destination_ip(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkInsightsPath.DestinationIp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-destinationip
        '''
        result = self._values.get("destination_ip")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def destination_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::NetworkInsightsPath.DestinationPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-destinationport
        '''
        result = self._values.get("destination_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def source_ip(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkInsightsPath.SourceIp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-sourceip
        '''
        result = self._values.get("source_ip")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::NetworkInsightsPath.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinsightspath.html#cfn-ec2-networkinsightspath-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnNetworkInsightsPathProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnNetworkInterface(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkInterface",
):
    '''A CloudFormation ``AWS::EC2::NetworkInterface``.

    :cloudformationResource: AWS::EC2::NetworkInterface
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        subnet_id: builtins.str,
        description: typing.Optional[builtins.str] = None,
        group_set: typing.Optional[typing.List[builtins.str]] = None,
        interface_type: typing.Optional[builtins.str] = None,
        ipv6_address_count: typing.Optional[jsii.Number] = None,
        ipv6_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInterface.InstanceIpv6AddressProperty"]]]] = None,
        private_ip_address: typing.Optional[builtins.str] = None,
        private_ip_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInterface.PrivateIpAddressSpecificationProperty"]]]] = None,
        secondary_private_ip_address_count: typing.Optional[jsii.Number] = None,
        source_dest_check: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::NetworkInterface``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param subnet_id: ``AWS::EC2::NetworkInterface.SubnetId``.
        :param description: ``AWS::EC2::NetworkInterface.Description``.
        :param group_set: ``AWS::EC2::NetworkInterface.GroupSet``.
        :param interface_type: ``AWS::EC2::NetworkInterface.InterfaceType``.
        :param ipv6_address_count: ``AWS::EC2::NetworkInterface.Ipv6AddressCount``.
        :param ipv6_addresses: ``AWS::EC2::NetworkInterface.Ipv6Addresses``.
        :param private_ip_address: ``AWS::EC2::NetworkInterface.PrivateIpAddress``.
        :param private_ip_addresses: ``AWS::EC2::NetworkInterface.PrivateIpAddresses``.
        :param secondary_private_ip_address_count: ``AWS::EC2::NetworkInterface.SecondaryPrivateIpAddressCount``.
        :param source_dest_check: ``AWS::EC2::NetworkInterface.SourceDestCheck``.
        :param tags: ``AWS::EC2::NetworkInterface.Tags``.
        '''
        props = CfnNetworkInterfaceProps(
            subnet_id=subnet_id,
            description=description,
            group_set=group_set,
            interface_type=interface_type,
            ipv6_address_count=ipv6_address_count,
            ipv6_addresses=ipv6_addresses,
            private_ip_address=private_ip_address,
            private_ip_addresses=private_ip_addresses,
            secondary_private_ip_address_count=secondary_private_ip_address_count,
            source_dest_check=source_dest_check,
            tags=tags,
        )

        jsii.create(CfnNetworkInterface, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrPrimaryPrivateIpAddress")
    def attr_primary_private_ip_address(self) -> builtins.str:
        '''
        :cloudformationAttribute: PrimaryPrivateIpAddress
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrPrimaryPrivateIpAddress"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrSecondaryPrivateIpAddresses")
    def attr_secondary_private_ip_addresses(self) -> typing.List[builtins.str]:
        '''
        :cloudformationAttribute: SecondaryPrivateIpAddresses
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "attrSecondaryPrivateIpAddresses"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::NetworkInterface.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetId")
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterface.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-subnetid
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetId"))

    @subnet_id.setter
    def subnet_id(self, value: builtins.str) -> None:
        jsii.set(self, "subnetId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkInterface.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-description
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "description"))

    @description.setter
    def description(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="groupSet")
    def group_set(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::NetworkInterface.GroupSet``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-groupset
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "groupSet"))

    @group_set.setter
    def group_set(self, value: typing.Optional[typing.List[builtins.str]]) -> None:
        jsii.set(self, "groupSet", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="interfaceType")
    def interface_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkInterface.InterfaceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-interfacetype
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "interfaceType"))

    @interface_type.setter
    def interface_type(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "interfaceType", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipv6AddressCount")
    def ipv6_address_count(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::NetworkInterface.Ipv6AddressCount``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresscount
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "ipv6AddressCount"))

    @ipv6_address_count.setter
    def ipv6_address_count(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "ipv6AddressCount", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipv6Addresses")
    def ipv6_addresses(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInterface.InstanceIpv6AddressProperty"]]]]:
        '''``AWS::EC2::NetworkInterface.Ipv6Addresses``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresses
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInterface.InstanceIpv6AddressProperty"]]]], jsii.get(self, "ipv6Addresses"))

    @ipv6_addresses.setter
    def ipv6_addresses(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInterface.InstanceIpv6AddressProperty"]]]],
    ) -> None:
        jsii.set(self, "ipv6Addresses", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateIpAddress")
    def private_ip_address(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkInterface.PrivateIpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddress
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "privateIpAddress"))

    @private_ip_address.setter
    def private_ip_address(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "privateIpAddress", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateIpAddresses")
    def private_ip_addresses(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInterface.PrivateIpAddressSpecificationProperty"]]]]:
        '''``AWS::EC2::NetworkInterface.PrivateIpAddresses``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddresses
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInterface.PrivateIpAddressSpecificationProperty"]]]], jsii.get(self, "privateIpAddresses"))

    @private_ip_addresses.setter
    def private_ip_addresses(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnNetworkInterface.PrivateIpAddressSpecificationProperty"]]]],
    ) -> None:
        jsii.set(self, "privateIpAddresses", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="secondaryPrivateIpAddressCount")
    def secondary_private_ip_address_count(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::NetworkInterface.SecondaryPrivateIpAddressCount``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-secondaryprivateipcount
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "secondaryPrivateIpAddressCount"))

    @secondary_private_ip_address_count.setter
    def secondary_private_ip_address_count(
        self,
        value: typing.Optional[jsii.Number],
    ) -> None:
        jsii.set(self, "secondaryPrivateIpAddressCount", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sourceDestCheck")
    def source_dest_check(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::NetworkInterface.SourceDestCheck``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-sourcedestcheck
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "sourceDestCheck"))

    @source_dest_check.setter
    def source_dest_check(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "sourceDestCheck", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInterface.InstanceIpv6AddressProperty",
        jsii_struct_bases=[],
        name_mapping={"ipv6_address": "ipv6Address"},
    )
    class InstanceIpv6AddressProperty:
        def __init__(self, *, ipv6_address: builtins.str) -> None:
            '''
            :param ipv6_address: ``CfnNetworkInterface.InstanceIpv6AddressProperty.Ipv6Address``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-instanceipv6address.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "ipv6_address": ipv6_address,
            }

        @builtins.property
        def ipv6_address(self) -> builtins.str:
            '''``CfnNetworkInterface.InstanceIpv6AddressProperty.Ipv6Address``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-instanceipv6address.html#cfn-ec2-networkinterface-instanceipv6address-ipv6address
            '''
            result = self._values.get("ipv6_address")
            assert result is not None, "Required property 'ipv6_address' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "InstanceIpv6AddressProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnNetworkInterface.PrivateIpAddressSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"primary": "primary", "private_ip_address": "privateIpAddress"},
    )
    class PrivateIpAddressSpecificationProperty:
        def __init__(
            self,
            *,
            primary: typing.Union[builtins.bool, aws_cdk.core.IResolvable],
            private_ip_address: builtins.str,
        ) -> None:
            '''
            :param primary: ``CfnNetworkInterface.PrivateIpAddressSpecificationProperty.Primary``.
            :param private_ip_address: ``CfnNetworkInterface.PrivateIpAddressSpecificationProperty.PrivateIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "primary": primary,
                "private_ip_address": private_ip_address,
            }

        @builtins.property
        def primary(self) -> typing.Union[builtins.bool, aws_cdk.core.IResolvable]:
            '''``CfnNetworkInterface.PrivateIpAddressSpecificationProperty.Primary``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-primary
            '''
            result = self._values.get("primary")
            assert result is not None, "Required property 'primary' is missing"
            return typing.cast(typing.Union[builtins.bool, aws_cdk.core.IResolvable], result)

        @builtins.property
        def private_ip_address(self) -> builtins.str:
            '''``CfnNetworkInterface.PrivateIpAddressSpecificationProperty.PrivateIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-privateipaddress
            '''
            result = self._values.get("private_ip_address")
            assert result is not None, "Required property 'private_ip_address' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PrivateIpAddressSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnNetworkInterfaceAttachment(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkInterfaceAttachment",
):
    '''A CloudFormation ``AWS::EC2::NetworkInterfaceAttachment``.

    :cloudformationResource: AWS::EC2::NetworkInterfaceAttachment
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        device_index: builtins.str,
        instance_id: builtins.str,
        network_interface_id: builtins.str,
        delete_on_termination: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::NetworkInterfaceAttachment``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param device_index: ``AWS::EC2::NetworkInterfaceAttachment.DeviceIndex``.
        :param instance_id: ``AWS::EC2::NetworkInterfaceAttachment.InstanceId``.
        :param network_interface_id: ``AWS::EC2::NetworkInterfaceAttachment.NetworkInterfaceId``.
        :param delete_on_termination: ``AWS::EC2::NetworkInterfaceAttachment.DeleteOnTermination``.
        '''
        props = CfnNetworkInterfaceAttachmentProps(
            device_index=device_index,
            instance_id=instance_id,
            network_interface_id=network_interface_id,
            delete_on_termination=delete_on_termination,
        )

        jsii.create(CfnNetworkInterfaceAttachment, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="deviceIndex")
    def device_index(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfaceAttachment.DeviceIndex``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html#cfn-ec2-network-interface-attachment-deviceindex
        '''
        return typing.cast(builtins.str, jsii.get(self, "deviceIndex"))

    @device_index.setter
    def device_index(self, value: builtins.str) -> None:
        jsii.set(self, "deviceIndex", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceId")
    def instance_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfaceAttachment.InstanceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html#cfn-ec2-network-interface-attachment-instanceid
        '''
        return typing.cast(builtins.str, jsii.get(self, "instanceId"))

    @instance_id.setter
    def instance_id(self, value: builtins.str) -> None:
        jsii.set(self, "instanceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkInterfaceId")
    def network_interface_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfaceAttachment.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html#cfn-ec2-network-interface-attachment-networkinterfaceid
        '''
        return typing.cast(builtins.str, jsii.get(self, "networkInterfaceId"))

    @network_interface_id.setter
    def network_interface_id(self, value: builtins.str) -> None:
        jsii.set(self, "networkInterfaceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="deleteOnTermination")
    def delete_on_termination(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::NetworkInterfaceAttachment.DeleteOnTermination``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html#cfn-ec2-network-interface-attachment-deleteonterm
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "deleteOnTermination"))

    @delete_on_termination.setter
    def delete_on_termination(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "deleteOnTermination", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkInterfaceAttachmentProps",
    jsii_struct_bases=[],
    name_mapping={
        "device_index": "deviceIndex",
        "instance_id": "instanceId",
        "network_interface_id": "networkInterfaceId",
        "delete_on_termination": "deleteOnTermination",
    },
)
class CfnNetworkInterfaceAttachmentProps:
    def __init__(
        self,
        *,
        device_index: builtins.str,
        instance_id: builtins.str,
        network_interface_id: builtins.str,
        delete_on_termination: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::NetworkInterfaceAttachment``.

        :param device_index: ``AWS::EC2::NetworkInterfaceAttachment.DeviceIndex``.
        :param instance_id: ``AWS::EC2::NetworkInterfaceAttachment.InstanceId``.
        :param network_interface_id: ``AWS::EC2::NetworkInterfaceAttachment.NetworkInterfaceId``.
        :param delete_on_termination: ``AWS::EC2::NetworkInterfaceAttachment.DeleteOnTermination``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "device_index": device_index,
            "instance_id": instance_id,
            "network_interface_id": network_interface_id,
        }
        if delete_on_termination is not None:
            self._values["delete_on_termination"] = delete_on_termination

    @builtins.property
    def device_index(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfaceAttachment.DeviceIndex``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html#cfn-ec2-network-interface-attachment-deviceindex
        '''
        result = self._values.get("device_index")
        assert result is not None, "Required property 'device_index' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def instance_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfaceAttachment.InstanceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html#cfn-ec2-network-interface-attachment-instanceid
        '''
        result = self._values.get("instance_id")
        assert result is not None, "Required property 'instance_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def network_interface_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfaceAttachment.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html#cfn-ec2-network-interface-attachment-networkinterfaceid
        '''
        result = self._values.get("network_interface_id")
        assert result is not None, "Required property 'network_interface_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def delete_on_termination(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::NetworkInterfaceAttachment.DeleteOnTermination``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface-attachment.html#cfn-ec2-network-interface-attachment-deleteonterm
        '''
        result = self._values.get("delete_on_termination")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnNetworkInterfaceAttachmentProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnNetworkInterfacePermission(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkInterfacePermission",
):
    '''A CloudFormation ``AWS::EC2::NetworkInterfacePermission``.

    :cloudformationResource: AWS::EC2::NetworkInterfacePermission
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterfacepermission.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        aws_account_id: builtins.str,
        network_interface_id: builtins.str,
        permission: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::NetworkInterfacePermission``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param aws_account_id: ``AWS::EC2::NetworkInterfacePermission.AwsAccountId``.
        :param network_interface_id: ``AWS::EC2::NetworkInterfacePermission.NetworkInterfaceId``.
        :param permission: ``AWS::EC2::NetworkInterfacePermission.Permission``.
        '''
        props = CfnNetworkInterfacePermissionProps(
            aws_account_id=aws_account_id,
            network_interface_id=network_interface_id,
            permission=permission,
        )

        jsii.create(CfnNetworkInterfacePermission, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="awsAccountId")
    def aws_account_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfacePermission.AwsAccountId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterfacepermission.html#cfn-ec2-networkinterfacepermission-awsaccountid
        '''
        return typing.cast(builtins.str, jsii.get(self, "awsAccountId"))

    @aws_account_id.setter
    def aws_account_id(self, value: builtins.str) -> None:
        jsii.set(self, "awsAccountId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkInterfaceId")
    def network_interface_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfacePermission.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterfacepermission.html#cfn-ec2-networkinterfacepermission-networkinterfaceid
        '''
        return typing.cast(builtins.str, jsii.get(self, "networkInterfaceId"))

    @network_interface_id.setter
    def network_interface_id(self, value: builtins.str) -> None:
        jsii.set(self, "networkInterfaceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="permission")
    def permission(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfacePermission.Permission``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterfacepermission.html#cfn-ec2-networkinterfacepermission-permission
        '''
        return typing.cast(builtins.str, jsii.get(self, "permission"))

    @permission.setter
    def permission(self, value: builtins.str) -> None:
        jsii.set(self, "permission", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkInterfacePermissionProps",
    jsii_struct_bases=[],
    name_mapping={
        "aws_account_id": "awsAccountId",
        "network_interface_id": "networkInterfaceId",
        "permission": "permission",
    },
)
class CfnNetworkInterfacePermissionProps:
    def __init__(
        self,
        *,
        aws_account_id: builtins.str,
        network_interface_id: builtins.str,
        permission: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::NetworkInterfacePermission``.

        :param aws_account_id: ``AWS::EC2::NetworkInterfacePermission.AwsAccountId``.
        :param network_interface_id: ``AWS::EC2::NetworkInterfacePermission.NetworkInterfaceId``.
        :param permission: ``AWS::EC2::NetworkInterfacePermission.Permission``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterfacepermission.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "aws_account_id": aws_account_id,
            "network_interface_id": network_interface_id,
            "permission": permission,
        }

    @builtins.property
    def aws_account_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfacePermission.AwsAccountId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterfacepermission.html#cfn-ec2-networkinterfacepermission-awsaccountid
        '''
        result = self._values.get("aws_account_id")
        assert result is not None, "Required property 'aws_account_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def network_interface_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfacePermission.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterfacepermission.html#cfn-ec2-networkinterfacepermission-networkinterfaceid
        '''
        result = self._values.get("network_interface_id")
        assert result is not None, "Required property 'network_interface_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def permission(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterfacePermission.Permission``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterfacepermission.html#cfn-ec2-networkinterfacepermission-permission
        '''
        result = self._values.get("permission")
        assert result is not None, "Required property 'permission' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnNetworkInterfacePermissionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnNetworkInterfaceProps",
    jsii_struct_bases=[],
    name_mapping={
        "subnet_id": "subnetId",
        "description": "description",
        "group_set": "groupSet",
        "interface_type": "interfaceType",
        "ipv6_address_count": "ipv6AddressCount",
        "ipv6_addresses": "ipv6Addresses",
        "private_ip_address": "privateIpAddress",
        "private_ip_addresses": "privateIpAddresses",
        "secondary_private_ip_address_count": "secondaryPrivateIpAddressCount",
        "source_dest_check": "sourceDestCheck",
        "tags": "tags",
    },
)
class CfnNetworkInterfaceProps:
    def __init__(
        self,
        *,
        subnet_id: builtins.str,
        description: typing.Optional[builtins.str] = None,
        group_set: typing.Optional[typing.List[builtins.str]] = None,
        interface_type: typing.Optional[builtins.str] = None,
        ipv6_address_count: typing.Optional[jsii.Number] = None,
        ipv6_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnNetworkInterface.InstanceIpv6AddressProperty]]]] = None,
        private_ip_address: typing.Optional[builtins.str] = None,
        private_ip_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnNetworkInterface.PrivateIpAddressSpecificationProperty]]]] = None,
        secondary_private_ip_address_count: typing.Optional[jsii.Number] = None,
        source_dest_check: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::NetworkInterface``.

        :param subnet_id: ``AWS::EC2::NetworkInterface.SubnetId``.
        :param description: ``AWS::EC2::NetworkInterface.Description``.
        :param group_set: ``AWS::EC2::NetworkInterface.GroupSet``.
        :param interface_type: ``AWS::EC2::NetworkInterface.InterfaceType``.
        :param ipv6_address_count: ``AWS::EC2::NetworkInterface.Ipv6AddressCount``.
        :param ipv6_addresses: ``AWS::EC2::NetworkInterface.Ipv6Addresses``.
        :param private_ip_address: ``AWS::EC2::NetworkInterface.PrivateIpAddress``.
        :param private_ip_addresses: ``AWS::EC2::NetworkInterface.PrivateIpAddresses``.
        :param secondary_private_ip_address_count: ``AWS::EC2::NetworkInterface.SecondaryPrivateIpAddressCount``.
        :param source_dest_check: ``AWS::EC2::NetworkInterface.SourceDestCheck``.
        :param tags: ``AWS::EC2::NetworkInterface.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "subnet_id": subnet_id,
        }
        if description is not None:
            self._values["description"] = description
        if group_set is not None:
            self._values["group_set"] = group_set
        if interface_type is not None:
            self._values["interface_type"] = interface_type
        if ipv6_address_count is not None:
            self._values["ipv6_address_count"] = ipv6_address_count
        if ipv6_addresses is not None:
            self._values["ipv6_addresses"] = ipv6_addresses
        if private_ip_address is not None:
            self._values["private_ip_address"] = private_ip_address
        if private_ip_addresses is not None:
            self._values["private_ip_addresses"] = private_ip_addresses
        if secondary_private_ip_address_count is not None:
            self._values["secondary_private_ip_address_count"] = secondary_private_ip_address_count
        if source_dest_check is not None:
            self._values["source_dest_check"] = source_dest_check
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::NetworkInterface.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-subnetid
        '''
        result = self._values.get("subnet_id")
        assert result is not None, "Required property 'subnet_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkInterface.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def group_set(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::NetworkInterface.GroupSet``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-groupset
        '''
        result = self._values.get("group_set")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def interface_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkInterface.InterfaceType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-interfacetype
        '''
        result = self._values.get("interface_type")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ipv6_address_count(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::NetworkInterface.Ipv6AddressCount``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresscount
        '''
        result = self._values.get("ipv6_address_count")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def ipv6_addresses(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnNetworkInterface.InstanceIpv6AddressProperty]]]]:
        '''``AWS::EC2::NetworkInterface.Ipv6Addresses``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresses
        '''
        result = self._values.get("ipv6_addresses")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnNetworkInterface.InstanceIpv6AddressProperty]]]], result)

    @builtins.property
    def private_ip_address(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::NetworkInterface.PrivateIpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddress
        '''
        result = self._values.get("private_ip_address")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def private_ip_addresses(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnNetworkInterface.PrivateIpAddressSpecificationProperty]]]]:
        '''``AWS::EC2::NetworkInterface.PrivateIpAddresses``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddresses
        '''
        result = self._values.get("private_ip_addresses")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnNetworkInterface.PrivateIpAddressSpecificationProperty]]]], result)

    @builtins.property
    def secondary_private_ip_address_count(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::NetworkInterface.SecondaryPrivateIpAddressCount``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-secondaryprivateipcount
        '''
        result = self._values.get("secondary_private_ip_address_count")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def source_dest_check(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::NetworkInterface.SourceDestCheck``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-sourcedestcheck
        '''
        result = self._values.get("source_dest_check")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::NetworkInterface.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnNetworkInterfaceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnPlacementGroup(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnPlacementGroup",
):
    '''A CloudFormation ``AWS::EC2::PlacementGroup``.

    :cloudformationResource: AWS::EC2::PlacementGroup
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-placementgroup.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        strategy: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::PlacementGroup``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param strategy: ``AWS::EC2::PlacementGroup.Strategy``.
        '''
        props = CfnPlacementGroupProps(strategy=strategy)

        jsii.create(CfnPlacementGroup, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="strategy")
    def strategy(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::PlacementGroup.Strategy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-placementgroup.html#cfn-ec2-placementgroup-strategy
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "strategy"))

    @strategy.setter
    def strategy(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "strategy", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnPlacementGroupProps",
    jsii_struct_bases=[],
    name_mapping={"strategy": "strategy"},
)
class CfnPlacementGroupProps:
    def __init__(self, *, strategy: typing.Optional[builtins.str] = None) -> None:
        '''Properties for defining a ``AWS::EC2::PlacementGroup``.

        :param strategy: ``AWS::EC2::PlacementGroup.Strategy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-placementgroup.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if strategy is not None:
            self._values["strategy"] = strategy

    @builtins.property
    def strategy(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::PlacementGroup.Strategy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-placementgroup.html#cfn-ec2-placementgroup-strategy
        '''
        result = self._values.get("strategy")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnPlacementGroupProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnPrefixList(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnPrefixList",
):
    '''A CloudFormation ``AWS::EC2::PrefixList``.

    :cloudformationResource: AWS::EC2::PrefixList
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        address_family: builtins.str,
        max_entries: jsii.Number,
        prefix_list_name: builtins.str,
        entries: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnPrefixList.EntryProperty"]]]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::PrefixList``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param address_family: ``AWS::EC2::PrefixList.AddressFamily``.
        :param max_entries: ``AWS::EC2::PrefixList.MaxEntries``.
        :param prefix_list_name: ``AWS::EC2::PrefixList.PrefixListName``.
        :param entries: ``AWS::EC2::PrefixList.Entries``.
        :param tags: ``AWS::EC2::PrefixList.Tags``.
        '''
        props = CfnPrefixListProps(
            address_family=address_family,
            max_entries=max_entries,
            prefix_list_name=prefix_list_name,
            entries=entries,
            tags=tags,
        )

        jsii.create(CfnPrefixList, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrArn")
    def attr_arn(self) -> builtins.str:
        '''
        :cloudformationAttribute: Arn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrArn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrOwnerId")
    def attr_owner_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: OwnerId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrOwnerId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrPrefixListId")
    def attr_prefix_list_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: PrefixListId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrPrefixListId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrVersion")
    def attr_version(self) -> jsii.Number:
        '''
        :cloudformationAttribute: Version
        '''
        return typing.cast(jsii.Number, jsii.get(self, "attrVersion"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::PrefixList.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="addressFamily")
    def address_family(self) -> builtins.str:
        '''``AWS::EC2::PrefixList.AddressFamily``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-addressfamily
        '''
        return typing.cast(builtins.str, jsii.get(self, "addressFamily"))

    @address_family.setter
    def address_family(self, value: builtins.str) -> None:
        jsii.set(self, "addressFamily", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="maxEntries")
    def max_entries(self) -> jsii.Number:
        '''``AWS::EC2::PrefixList.MaxEntries``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-maxentries
        '''
        return typing.cast(jsii.Number, jsii.get(self, "maxEntries"))

    @max_entries.setter
    def max_entries(self, value: jsii.Number) -> None:
        jsii.set(self, "maxEntries", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="prefixListName")
    def prefix_list_name(self) -> builtins.str:
        '''``AWS::EC2::PrefixList.PrefixListName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-prefixlistname
        '''
        return typing.cast(builtins.str, jsii.get(self, "prefixListName"))

    @prefix_list_name.setter
    def prefix_list_name(self, value: builtins.str) -> None:
        jsii.set(self, "prefixListName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="entries")
    def entries(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnPrefixList.EntryProperty"]]]]:
        '''``AWS::EC2::PrefixList.Entries``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-entries
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnPrefixList.EntryProperty"]]]], jsii.get(self, "entries"))

    @entries.setter
    def entries(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnPrefixList.EntryProperty"]]]],
    ) -> None:
        jsii.set(self, "entries", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnPrefixList.EntryProperty",
        jsii_struct_bases=[],
        name_mapping={"cidr": "cidr", "description": "description"},
    )
    class EntryProperty:
        def __init__(
            self,
            *,
            cidr: builtins.str,
            description: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param cidr: ``CfnPrefixList.EntryProperty.Cidr``.
            :param description: ``CfnPrefixList.EntryProperty.Description``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-prefixlist-entry.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "cidr": cidr,
            }
            if description is not None:
                self._values["description"] = description

        @builtins.property
        def cidr(self) -> builtins.str:
            '''``CfnPrefixList.EntryProperty.Cidr``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-prefixlist-entry.html#cfn-ec2-prefixlist-entry-cidr
            '''
            result = self._values.get("cidr")
            assert result is not None, "Required property 'cidr' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def description(self) -> typing.Optional[builtins.str]:
            '''``CfnPrefixList.EntryProperty.Description``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-prefixlist-entry.html#cfn-ec2-prefixlist-entry-description
            '''
            result = self._values.get("description")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "EntryProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnPrefixListProps",
    jsii_struct_bases=[],
    name_mapping={
        "address_family": "addressFamily",
        "max_entries": "maxEntries",
        "prefix_list_name": "prefixListName",
        "entries": "entries",
        "tags": "tags",
    },
)
class CfnPrefixListProps:
    def __init__(
        self,
        *,
        address_family: builtins.str,
        max_entries: jsii.Number,
        prefix_list_name: builtins.str,
        entries: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnPrefixList.EntryProperty]]]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::PrefixList``.

        :param address_family: ``AWS::EC2::PrefixList.AddressFamily``.
        :param max_entries: ``AWS::EC2::PrefixList.MaxEntries``.
        :param prefix_list_name: ``AWS::EC2::PrefixList.PrefixListName``.
        :param entries: ``AWS::EC2::PrefixList.Entries``.
        :param tags: ``AWS::EC2::PrefixList.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "address_family": address_family,
            "max_entries": max_entries,
            "prefix_list_name": prefix_list_name,
        }
        if entries is not None:
            self._values["entries"] = entries
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def address_family(self) -> builtins.str:
        '''``AWS::EC2::PrefixList.AddressFamily``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-addressfamily
        '''
        result = self._values.get("address_family")
        assert result is not None, "Required property 'address_family' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def max_entries(self) -> jsii.Number:
        '''``AWS::EC2::PrefixList.MaxEntries``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-maxentries
        '''
        result = self._values.get("max_entries")
        assert result is not None, "Required property 'max_entries' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def prefix_list_name(self) -> builtins.str:
        '''``AWS::EC2::PrefixList.PrefixListName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-prefixlistname
        '''
        result = self._values.get("prefix_list_name")
        assert result is not None, "Required property 'prefix_list_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def entries(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnPrefixList.EntryProperty]]]]:
        '''``AWS::EC2::PrefixList.Entries``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-entries
        '''
        result = self._values.get("entries")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnPrefixList.EntryProperty]]]], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::PrefixList.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnPrefixListProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnRoute(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnRoute",
):
    '''A CloudFormation ``AWS::EC2::Route``.

    :cloudformationResource: AWS::EC2::Route
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        route_table_id: builtins.str,
        carrier_gateway_id: typing.Optional[builtins.str] = None,
        destination_cidr_block: typing.Optional[builtins.str] = None,
        destination_ipv6_cidr_block: typing.Optional[builtins.str] = None,
        egress_only_internet_gateway_id: typing.Optional[builtins.str] = None,
        gateway_id: typing.Optional[builtins.str] = None,
        instance_id: typing.Optional[builtins.str] = None,
        local_gateway_id: typing.Optional[builtins.str] = None,
        nat_gateway_id: typing.Optional[builtins.str] = None,
        network_interface_id: typing.Optional[builtins.str] = None,
        transit_gateway_id: typing.Optional[builtins.str] = None,
        vpc_endpoint_id: typing.Optional[builtins.str] = None,
        vpc_peering_connection_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::Route``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param route_table_id: ``AWS::EC2::Route.RouteTableId``.
        :param carrier_gateway_id: ``AWS::EC2::Route.CarrierGatewayId``.
        :param destination_cidr_block: ``AWS::EC2::Route.DestinationCidrBlock``.
        :param destination_ipv6_cidr_block: ``AWS::EC2::Route.DestinationIpv6CidrBlock``.
        :param egress_only_internet_gateway_id: ``AWS::EC2::Route.EgressOnlyInternetGatewayId``.
        :param gateway_id: ``AWS::EC2::Route.GatewayId``.
        :param instance_id: ``AWS::EC2::Route.InstanceId``.
        :param local_gateway_id: ``AWS::EC2::Route.LocalGatewayId``.
        :param nat_gateway_id: ``AWS::EC2::Route.NatGatewayId``.
        :param network_interface_id: ``AWS::EC2::Route.NetworkInterfaceId``.
        :param transit_gateway_id: ``AWS::EC2::Route.TransitGatewayId``.
        :param vpc_endpoint_id: ``AWS::EC2::Route.VpcEndpointId``.
        :param vpc_peering_connection_id: ``AWS::EC2::Route.VpcPeeringConnectionId``.
        '''
        props = CfnRouteProps(
            route_table_id=route_table_id,
            carrier_gateway_id=carrier_gateway_id,
            destination_cidr_block=destination_cidr_block,
            destination_ipv6_cidr_block=destination_ipv6_cidr_block,
            egress_only_internet_gateway_id=egress_only_internet_gateway_id,
            gateway_id=gateway_id,
            instance_id=instance_id,
            local_gateway_id=local_gateway_id,
            nat_gateway_id=nat_gateway_id,
            network_interface_id=network_interface_id,
            transit_gateway_id=transit_gateway_id,
            vpc_endpoint_id=vpc_endpoint_id,
            vpc_peering_connection_id=vpc_peering_connection_id,
        )

        jsii.create(CfnRoute, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="routeTableId")
    def route_table_id(self) -> builtins.str:
        '''``AWS::EC2::Route.RouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-routetableid
        '''
        return typing.cast(builtins.str, jsii.get(self, "routeTableId"))

    @route_table_id.setter
    def route_table_id(self, value: builtins.str) -> None:
        jsii.set(self, "routeTableId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="carrierGatewayId")
    def carrier_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.CarrierGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-carriergatewayid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "carrierGatewayId"))

    @carrier_gateway_id.setter
    def carrier_gateway_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "carrierGatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationCidrBlock")
    def destination_cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-destinationcidrblock
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "destinationCidrBlock"))

    @destination_cidr_block.setter
    def destination_cidr_block(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "destinationCidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationIpv6CidrBlock")
    def destination_ipv6_cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.DestinationIpv6CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-destinationipv6cidrblock
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "destinationIpv6CidrBlock"))

    @destination_ipv6_cidr_block.setter
    def destination_ipv6_cidr_block(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "destinationIpv6CidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="egressOnlyInternetGatewayId")
    def egress_only_internet_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.EgressOnlyInternetGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-egressonlyinternetgatewayid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "egressOnlyInternetGatewayId"))

    @egress_only_internet_gateway_id.setter
    def egress_only_internet_gateway_id(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "egressOnlyInternetGatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="gatewayId")
    def gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.GatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-gatewayid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "gatewayId"))

    @gateway_id.setter
    def gateway_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "gatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceId")
    def instance_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.InstanceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-instanceid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "instanceId"))

    @instance_id.setter
    def instance_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "instanceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="localGatewayId")
    def local_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.LocalGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-localgatewayid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "localGatewayId"))

    @local_gateway_id.setter
    def local_gateway_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "localGatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="natGatewayId")
    def nat_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.NatGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-natgatewayid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "natGatewayId"))

    @nat_gateway_id.setter
    def nat_gateway_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "natGatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkInterfaceId")
    def network_interface_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-networkinterfaceid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "networkInterfaceId"))

    @network_interface_id.setter
    def network_interface_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "networkInterfaceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayId")
    def transit_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.TransitGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-transitgatewayid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "transitGatewayId"))

    @transit_gateway_id.setter
    def transit_gateway_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "transitGatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointId")
    def vpc_endpoint_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.VpcEndpointId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-vpcendpointid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "vpcEndpointId"))

    @vpc_endpoint_id.setter
    def vpc_endpoint_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "vpcEndpointId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcPeeringConnectionId")
    def vpc_peering_connection_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.VpcPeeringConnectionId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-vpcpeeringconnectionid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "vpcPeeringConnectionId"))

    @vpc_peering_connection_id.setter
    def vpc_peering_connection_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "vpcPeeringConnectionId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnRouteProps",
    jsii_struct_bases=[],
    name_mapping={
        "route_table_id": "routeTableId",
        "carrier_gateway_id": "carrierGatewayId",
        "destination_cidr_block": "destinationCidrBlock",
        "destination_ipv6_cidr_block": "destinationIpv6CidrBlock",
        "egress_only_internet_gateway_id": "egressOnlyInternetGatewayId",
        "gateway_id": "gatewayId",
        "instance_id": "instanceId",
        "local_gateway_id": "localGatewayId",
        "nat_gateway_id": "natGatewayId",
        "network_interface_id": "networkInterfaceId",
        "transit_gateway_id": "transitGatewayId",
        "vpc_endpoint_id": "vpcEndpointId",
        "vpc_peering_connection_id": "vpcPeeringConnectionId",
    },
)
class CfnRouteProps:
    def __init__(
        self,
        *,
        route_table_id: builtins.str,
        carrier_gateway_id: typing.Optional[builtins.str] = None,
        destination_cidr_block: typing.Optional[builtins.str] = None,
        destination_ipv6_cidr_block: typing.Optional[builtins.str] = None,
        egress_only_internet_gateway_id: typing.Optional[builtins.str] = None,
        gateway_id: typing.Optional[builtins.str] = None,
        instance_id: typing.Optional[builtins.str] = None,
        local_gateway_id: typing.Optional[builtins.str] = None,
        nat_gateway_id: typing.Optional[builtins.str] = None,
        network_interface_id: typing.Optional[builtins.str] = None,
        transit_gateway_id: typing.Optional[builtins.str] = None,
        vpc_endpoint_id: typing.Optional[builtins.str] = None,
        vpc_peering_connection_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::Route``.

        :param route_table_id: ``AWS::EC2::Route.RouteTableId``.
        :param carrier_gateway_id: ``AWS::EC2::Route.CarrierGatewayId``.
        :param destination_cidr_block: ``AWS::EC2::Route.DestinationCidrBlock``.
        :param destination_ipv6_cidr_block: ``AWS::EC2::Route.DestinationIpv6CidrBlock``.
        :param egress_only_internet_gateway_id: ``AWS::EC2::Route.EgressOnlyInternetGatewayId``.
        :param gateway_id: ``AWS::EC2::Route.GatewayId``.
        :param instance_id: ``AWS::EC2::Route.InstanceId``.
        :param local_gateway_id: ``AWS::EC2::Route.LocalGatewayId``.
        :param nat_gateway_id: ``AWS::EC2::Route.NatGatewayId``.
        :param network_interface_id: ``AWS::EC2::Route.NetworkInterfaceId``.
        :param transit_gateway_id: ``AWS::EC2::Route.TransitGatewayId``.
        :param vpc_endpoint_id: ``AWS::EC2::Route.VpcEndpointId``.
        :param vpc_peering_connection_id: ``AWS::EC2::Route.VpcPeeringConnectionId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "route_table_id": route_table_id,
        }
        if carrier_gateway_id is not None:
            self._values["carrier_gateway_id"] = carrier_gateway_id
        if destination_cidr_block is not None:
            self._values["destination_cidr_block"] = destination_cidr_block
        if destination_ipv6_cidr_block is not None:
            self._values["destination_ipv6_cidr_block"] = destination_ipv6_cidr_block
        if egress_only_internet_gateway_id is not None:
            self._values["egress_only_internet_gateway_id"] = egress_only_internet_gateway_id
        if gateway_id is not None:
            self._values["gateway_id"] = gateway_id
        if instance_id is not None:
            self._values["instance_id"] = instance_id
        if local_gateway_id is not None:
            self._values["local_gateway_id"] = local_gateway_id
        if nat_gateway_id is not None:
            self._values["nat_gateway_id"] = nat_gateway_id
        if network_interface_id is not None:
            self._values["network_interface_id"] = network_interface_id
        if transit_gateway_id is not None:
            self._values["transit_gateway_id"] = transit_gateway_id
        if vpc_endpoint_id is not None:
            self._values["vpc_endpoint_id"] = vpc_endpoint_id
        if vpc_peering_connection_id is not None:
            self._values["vpc_peering_connection_id"] = vpc_peering_connection_id

    @builtins.property
    def route_table_id(self) -> builtins.str:
        '''``AWS::EC2::Route.RouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-routetableid
        '''
        result = self._values.get("route_table_id")
        assert result is not None, "Required property 'route_table_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def carrier_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.CarrierGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-carriergatewayid
        '''
        result = self._values.get("carrier_gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def destination_cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-destinationcidrblock
        '''
        result = self._values.get("destination_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def destination_ipv6_cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.DestinationIpv6CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-destinationipv6cidrblock
        '''
        result = self._values.get("destination_ipv6_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def egress_only_internet_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.EgressOnlyInternetGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-egressonlyinternetgatewayid
        '''
        result = self._values.get("egress_only_internet_gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.GatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-gatewayid
        '''
        result = self._values.get("gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def instance_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.InstanceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-instanceid
        '''
        result = self._values.get("instance_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def local_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.LocalGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-localgatewayid
        '''
        result = self._values.get("local_gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def nat_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.NatGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-natgatewayid
        '''
        result = self._values.get("nat_gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def network_interface_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-networkinterfaceid
        '''
        result = self._values.get("network_interface_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def transit_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.TransitGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-transitgatewayid
        '''
        result = self._values.get("transit_gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vpc_endpoint_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.VpcEndpointId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-vpcendpointid
        '''
        result = self._values.get("vpc_endpoint_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vpc_peering_connection_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Route.VpcPeeringConnectionId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html#cfn-ec2-route-vpcpeeringconnectionid
        '''
        result = self._values.get("vpc_peering_connection_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnRouteProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnRouteTable(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnRouteTable",
):
    '''A CloudFormation ``AWS::EC2::RouteTable``.

    :cloudformationResource: AWS::EC2::RouteTable
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        vpc_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::RouteTable``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param vpc_id: ``AWS::EC2::RouteTable.VpcId``.
        :param tags: ``AWS::EC2::RouteTable.Tags``.
        '''
        props = CfnRouteTableProps(vpc_id=vpc_id, tags=tags)

        jsii.create(CfnRouteTable, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::RouteTable.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::RouteTable.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnRouteTableProps",
    jsii_struct_bases=[],
    name_mapping={"vpc_id": "vpcId", "tags": "tags"},
)
class CfnRouteTableProps:
    def __init__(
        self,
        *,
        vpc_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::RouteTable``.

        :param vpc_id: ``AWS::EC2::RouteTable.VpcId``.
        :param tags: ``AWS::EC2::RouteTable.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "vpc_id": vpc_id,
        }
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::RouteTable.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::RouteTable.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnRouteTableProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnSecurityGroup(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnSecurityGroup",
):
    '''A CloudFormation ``AWS::EC2::SecurityGroup``.

    :cloudformationResource: AWS::EC2::SecurityGroup
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        group_description: builtins.str,
        group_name: typing.Optional[builtins.str] = None,
        security_group_egress: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSecurityGroup.EgressProperty"]]]] = None,
        security_group_ingress: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSecurityGroup.IngressProperty"]]]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        vpc_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::SecurityGroup``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param group_description: ``AWS::EC2::SecurityGroup.GroupDescription``.
        :param group_name: ``AWS::EC2::SecurityGroup.GroupName``.
        :param security_group_egress: ``AWS::EC2::SecurityGroup.SecurityGroupEgress``.
        :param security_group_ingress: ``AWS::EC2::SecurityGroup.SecurityGroupIngress``.
        :param tags: ``AWS::EC2::SecurityGroup.Tags``.
        :param vpc_id: ``AWS::EC2::SecurityGroup.VpcId``.
        '''
        props = CfnSecurityGroupProps(
            group_description=group_description,
            group_name=group_name,
            security_group_egress=security_group_egress,
            security_group_ingress=security_group_ingress,
            tags=tags,
            vpc_id=vpc_id,
        )

        jsii.create(CfnSecurityGroup, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrGroupId")
    def attr_group_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: GroupId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrGroupId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrVpcId")
    def attr_vpc_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: VpcId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrVpcId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::SecurityGroup.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="groupDescription")
    def group_description(self) -> builtins.str:
        '''``AWS::EC2::SecurityGroup.GroupDescription``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-groupdescription
        '''
        return typing.cast(builtins.str, jsii.get(self, "groupDescription"))

    @group_description.setter
    def group_description(self, value: builtins.str) -> None:
        jsii.set(self, "groupDescription", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="groupName")
    def group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroup.GroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-groupname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "groupName"))

    @group_name.setter
    def group_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "groupName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroupEgress")
    def security_group_egress(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSecurityGroup.EgressProperty"]]]]:
        '''``AWS::EC2::SecurityGroup.SecurityGroupEgress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-securitygroupegress
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSecurityGroup.EgressProperty"]]]], jsii.get(self, "securityGroupEgress"))

    @security_group_egress.setter
    def security_group_egress(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSecurityGroup.EgressProperty"]]]],
    ) -> None:
        jsii.set(self, "securityGroupEgress", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroupIngress")
    def security_group_ingress(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSecurityGroup.IngressProperty"]]]]:
        '''``AWS::EC2::SecurityGroup.SecurityGroupIngress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-securitygroupingress
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSecurityGroup.IngressProperty"]]]], jsii.get(self, "securityGroupIngress"))

    @security_group_ingress.setter
    def security_group_ingress(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSecurityGroup.IngressProperty"]]]],
    ) -> None:
        jsii.set(self, "securityGroupIngress", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroup.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-vpcid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "vpcId", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSecurityGroup.EgressProperty",
        jsii_struct_bases=[],
        name_mapping={
            "ip_protocol": "ipProtocol",
            "cidr_ip": "cidrIp",
            "cidr_ipv6": "cidrIpv6",
            "description": "description",
            "destination_prefix_list_id": "destinationPrefixListId",
            "destination_security_group_id": "destinationSecurityGroupId",
            "from_port": "fromPort",
            "to_port": "toPort",
        },
    )
    class EgressProperty:
        def __init__(
            self,
            *,
            ip_protocol: builtins.str,
            cidr_ip: typing.Optional[builtins.str] = None,
            cidr_ipv6: typing.Optional[builtins.str] = None,
            description: typing.Optional[builtins.str] = None,
            destination_prefix_list_id: typing.Optional[builtins.str] = None,
            destination_security_group_id: typing.Optional[builtins.str] = None,
            from_port: typing.Optional[jsii.Number] = None,
            to_port: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param ip_protocol: ``CfnSecurityGroup.EgressProperty.IpProtocol``.
            :param cidr_ip: ``CfnSecurityGroup.EgressProperty.CidrIp``.
            :param cidr_ipv6: ``CfnSecurityGroup.EgressProperty.CidrIpv6``.
            :param description: ``CfnSecurityGroup.EgressProperty.Description``.
            :param destination_prefix_list_id: ``CfnSecurityGroup.EgressProperty.DestinationPrefixListId``.
            :param destination_security_group_id: ``CfnSecurityGroup.EgressProperty.DestinationSecurityGroupId``.
            :param from_port: ``CfnSecurityGroup.EgressProperty.FromPort``.
            :param to_port: ``CfnSecurityGroup.EgressProperty.ToPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "ip_protocol": ip_protocol,
            }
            if cidr_ip is not None:
                self._values["cidr_ip"] = cidr_ip
            if cidr_ipv6 is not None:
                self._values["cidr_ipv6"] = cidr_ipv6
            if description is not None:
                self._values["description"] = description
            if destination_prefix_list_id is not None:
                self._values["destination_prefix_list_id"] = destination_prefix_list_id
            if destination_security_group_id is not None:
                self._values["destination_security_group_id"] = destination_security_group_id
            if from_port is not None:
                self._values["from_port"] = from_port
            if to_port is not None:
                self._values["to_port"] = to_port

        @builtins.property
        def ip_protocol(self) -> builtins.str:
            '''``CfnSecurityGroup.EgressProperty.IpProtocol``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-ipprotocol
            '''
            result = self._values.get("ip_protocol")
            assert result is not None, "Required property 'ip_protocol' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def cidr_ip(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.EgressProperty.CidrIp``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-cidrip
            '''
            result = self._values.get("cidr_ip")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def cidr_ipv6(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.EgressProperty.CidrIpv6``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-cidripv6
            '''
            result = self._values.get("cidr_ipv6")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def description(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.EgressProperty.Description``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-description
            '''
            result = self._values.get("description")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def destination_prefix_list_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.EgressProperty.DestinationPrefixListId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-destinationprefixlistid
            '''
            result = self._values.get("destination_prefix_list_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def destination_security_group_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.EgressProperty.DestinationSecurityGroupId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-destsecgroupid
            '''
            result = self._values.get("destination_security_group_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def from_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnSecurityGroup.EgressProperty.FromPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-fromport
            '''
            result = self._values.get("from_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def to_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnSecurityGroup.EgressProperty.ToPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-toport
            '''
            result = self._values.get("to_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "EgressProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSecurityGroup.IngressProperty",
        jsii_struct_bases=[],
        name_mapping={
            "ip_protocol": "ipProtocol",
            "cidr_ip": "cidrIp",
            "cidr_ipv6": "cidrIpv6",
            "description": "description",
            "from_port": "fromPort",
            "source_prefix_list_id": "sourcePrefixListId",
            "source_security_group_id": "sourceSecurityGroupId",
            "source_security_group_name": "sourceSecurityGroupName",
            "source_security_group_owner_id": "sourceSecurityGroupOwnerId",
            "to_port": "toPort",
        },
    )
    class IngressProperty:
        def __init__(
            self,
            *,
            ip_protocol: builtins.str,
            cidr_ip: typing.Optional[builtins.str] = None,
            cidr_ipv6: typing.Optional[builtins.str] = None,
            description: typing.Optional[builtins.str] = None,
            from_port: typing.Optional[jsii.Number] = None,
            source_prefix_list_id: typing.Optional[builtins.str] = None,
            source_security_group_id: typing.Optional[builtins.str] = None,
            source_security_group_name: typing.Optional[builtins.str] = None,
            source_security_group_owner_id: typing.Optional[builtins.str] = None,
            to_port: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param ip_protocol: ``CfnSecurityGroup.IngressProperty.IpProtocol``.
            :param cidr_ip: ``CfnSecurityGroup.IngressProperty.CidrIp``.
            :param cidr_ipv6: ``CfnSecurityGroup.IngressProperty.CidrIpv6``.
            :param description: ``CfnSecurityGroup.IngressProperty.Description``.
            :param from_port: ``CfnSecurityGroup.IngressProperty.FromPort``.
            :param source_prefix_list_id: ``CfnSecurityGroup.IngressProperty.SourcePrefixListId``.
            :param source_security_group_id: ``CfnSecurityGroup.IngressProperty.SourceSecurityGroupId``.
            :param source_security_group_name: ``CfnSecurityGroup.IngressProperty.SourceSecurityGroupName``.
            :param source_security_group_owner_id: ``CfnSecurityGroup.IngressProperty.SourceSecurityGroupOwnerId``.
            :param to_port: ``CfnSecurityGroup.IngressProperty.ToPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "ip_protocol": ip_protocol,
            }
            if cidr_ip is not None:
                self._values["cidr_ip"] = cidr_ip
            if cidr_ipv6 is not None:
                self._values["cidr_ipv6"] = cidr_ipv6
            if description is not None:
                self._values["description"] = description
            if from_port is not None:
                self._values["from_port"] = from_port
            if source_prefix_list_id is not None:
                self._values["source_prefix_list_id"] = source_prefix_list_id
            if source_security_group_id is not None:
                self._values["source_security_group_id"] = source_security_group_id
            if source_security_group_name is not None:
                self._values["source_security_group_name"] = source_security_group_name
            if source_security_group_owner_id is not None:
                self._values["source_security_group_owner_id"] = source_security_group_owner_id
            if to_port is not None:
                self._values["to_port"] = to_port

        @builtins.property
        def ip_protocol(self) -> builtins.str:
            '''``CfnSecurityGroup.IngressProperty.IpProtocol``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-ipprotocol
            '''
            result = self._values.get("ip_protocol")
            assert result is not None, "Required property 'ip_protocol' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def cidr_ip(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.IngressProperty.CidrIp``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-cidrip
            '''
            result = self._values.get("cidr_ip")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def cidr_ipv6(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.IngressProperty.CidrIpv6``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-cidripv6
            '''
            result = self._values.get("cidr_ipv6")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def description(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.IngressProperty.Description``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-description
            '''
            result = self._values.get("description")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def from_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnSecurityGroup.IngressProperty.FromPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-fromport
            '''
            result = self._values.get("from_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def source_prefix_list_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.IngressProperty.SourcePrefixListId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-securitygroup-ingress-sourceprefixlistid
            '''
            result = self._values.get("source_prefix_list_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def source_security_group_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.IngressProperty.SourceSecurityGroupId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-sourcesecuritygroupid
            '''
            result = self._values.get("source_security_group_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def source_security_group_name(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.IngressProperty.SourceSecurityGroupName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-sourcesecuritygroupname
            '''
            result = self._values.get("source_security_group_name")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def source_security_group_owner_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSecurityGroup.IngressProperty.SourceSecurityGroupOwnerId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-sourcesecuritygroupownerid
            '''
            result = self._values.get("source_security_group_owner_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def to_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnSecurityGroup.IngressProperty.ToPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-rule.html#cfn-ec2-security-group-rule-toport
            '''
            result = self._values.get("to_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "IngressProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnSecurityGroupEgress(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnSecurityGroupEgress",
):
    '''A CloudFormation ``AWS::EC2::SecurityGroupEgress``.

    :cloudformationResource: AWS::EC2::SecurityGroupEgress
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        group_id: builtins.str,
        ip_protocol: builtins.str,
        cidr_ip: typing.Optional[builtins.str] = None,
        cidr_ipv6: typing.Optional[builtins.str] = None,
        description: typing.Optional[builtins.str] = None,
        destination_prefix_list_id: typing.Optional[builtins.str] = None,
        destination_security_group_id: typing.Optional[builtins.str] = None,
        from_port: typing.Optional[jsii.Number] = None,
        to_port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::SecurityGroupEgress``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param group_id: ``AWS::EC2::SecurityGroupEgress.GroupId``.
        :param ip_protocol: ``AWS::EC2::SecurityGroupEgress.IpProtocol``.
        :param cidr_ip: ``AWS::EC2::SecurityGroupEgress.CidrIp``.
        :param cidr_ipv6: ``AWS::EC2::SecurityGroupEgress.CidrIpv6``.
        :param description: ``AWS::EC2::SecurityGroupEgress.Description``.
        :param destination_prefix_list_id: ``AWS::EC2::SecurityGroupEgress.DestinationPrefixListId``.
        :param destination_security_group_id: ``AWS::EC2::SecurityGroupEgress.DestinationSecurityGroupId``.
        :param from_port: ``AWS::EC2::SecurityGroupEgress.FromPort``.
        :param to_port: ``AWS::EC2::SecurityGroupEgress.ToPort``.
        '''
        props = CfnSecurityGroupEgressProps(
            group_id=group_id,
            ip_protocol=ip_protocol,
            cidr_ip=cidr_ip,
            cidr_ipv6=cidr_ipv6,
            description=description,
            destination_prefix_list_id=destination_prefix_list_id,
            destination_security_group_id=destination_security_group_id,
            from_port=from_port,
            to_port=to_port,
        )

        jsii.create(CfnSecurityGroupEgress, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="groupId")
    def group_id(self) -> builtins.str:
        '''``AWS::EC2::SecurityGroupEgress.GroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-groupid
        '''
        return typing.cast(builtins.str, jsii.get(self, "groupId"))

    @group_id.setter
    def group_id(self, value: builtins.str) -> None:
        jsii.set(self, "groupId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipProtocol")
    def ip_protocol(self) -> builtins.str:
        '''``AWS::EC2::SecurityGroupEgress.IpProtocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-ipprotocol
        '''
        return typing.cast(builtins.str, jsii.get(self, "ipProtocol"))

    @ip_protocol.setter
    def ip_protocol(self, value: builtins.str) -> None:
        jsii.set(self, "ipProtocol", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cidrIp")
    def cidr_ip(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupEgress.CidrIp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-cidrip
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "cidrIp"))

    @cidr_ip.setter
    def cidr_ip(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "cidrIp", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cidrIpv6")
    def cidr_ipv6(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupEgress.CidrIpv6``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-cidripv6
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "cidrIpv6"))

    @cidr_ipv6.setter
    def cidr_ipv6(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "cidrIpv6", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupEgress.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-description
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "description"))

    @description.setter
    def description(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationPrefixListId")
    def destination_prefix_list_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupEgress.DestinationPrefixListId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-destinationprefixlistid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "destinationPrefixListId"))

    @destination_prefix_list_id.setter
    def destination_prefix_list_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "destinationPrefixListId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationSecurityGroupId")
    def destination_security_group_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupEgress.DestinationSecurityGroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-destinationsecuritygroupid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "destinationSecurityGroupId"))

    @destination_security_group_id.setter
    def destination_security_group_id(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "destinationSecurityGroupId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="fromPort")
    def from_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::SecurityGroupEgress.FromPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-fromport
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "fromPort"))

    @from_port.setter
    def from_port(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "fromPort", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="toPort")
    def to_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::SecurityGroupEgress.ToPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-toport
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "toPort"))

    @to_port.setter
    def to_port(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "toPort", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnSecurityGroupEgressProps",
    jsii_struct_bases=[],
    name_mapping={
        "group_id": "groupId",
        "ip_protocol": "ipProtocol",
        "cidr_ip": "cidrIp",
        "cidr_ipv6": "cidrIpv6",
        "description": "description",
        "destination_prefix_list_id": "destinationPrefixListId",
        "destination_security_group_id": "destinationSecurityGroupId",
        "from_port": "fromPort",
        "to_port": "toPort",
    },
)
class CfnSecurityGroupEgressProps:
    def __init__(
        self,
        *,
        group_id: builtins.str,
        ip_protocol: builtins.str,
        cidr_ip: typing.Optional[builtins.str] = None,
        cidr_ipv6: typing.Optional[builtins.str] = None,
        description: typing.Optional[builtins.str] = None,
        destination_prefix_list_id: typing.Optional[builtins.str] = None,
        destination_security_group_id: typing.Optional[builtins.str] = None,
        from_port: typing.Optional[jsii.Number] = None,
        to_port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::SecurityGroupEgress``.

        :param group_id: ``AWS::EC2::SecurityGroupEgress.GroupId``.
        :param ip_protocol: ``AWS::EC2::SecurityGroupEgress.IpProtocol``.
        :param cidr_ip: ``AWS::EC2::SecurityGroupEgress.CidrIp``.
        :param cidr_ipv6: ``AWS::EC2::SecurityGroupEgress.CidrIpv6``.
        :param description: ``AWS::EC2::SecurityGroupEgress.Description``.
        :param destination_prefix_list_id: ``AWS::EC2::SecurityGroupEgress.DestinationPrefixListId``.
        :param destination_security_group_id: ``AWS::EC2::SecurityGroupEgress.DestinationSecurityGroupId``.
        :param from_port: ``AWS::EC2::SecurityGroupEgress.FromPort``.
        :param to_port: ``AWS::EC2::SecurityGroupEgress.ToPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "group_id": group_id,
            "ip_protocol": ip_protocol,
        }
        if cidr_ip is not None:
            self._values["cidr_ip"] = cidr_ip
        if cidr_ipv6 is not None:
            self._values["cidr_ipv6"] = cidr_ipv6
        if description is not None:
            self._values["description"] = description
        if destination_prefix_list_id is not None:
            self._values["destination_prefix_list_id"] = destination_prefix_list_id
        if destination_security_group_id is not None:
            self._values["destination_security_group_id"] = destination_security_group_id
        if from_port is not None:
            self._values["from_port"] = from_port
        if to_port is not None:
            self._values["to_port"] = to_port

    @builtins.property
    def group_id(self) -> builtins.str:
        '''``AWS::EC2::SecurityGroupEgress.GroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-groupid
        '''
        result = self._values.get("group_id")
        assert result is not None, "Required property 'group_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def ip_protocol(self) -> builtins.str:
        '''``AWS::EC2::SecurityGroupEgress.IpProtocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-ipprotocol
        '''
        result = self._values.get("ip_protocol")
        assert result is not None, "Required property 'ip_protocol' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def cidr_ip(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupEgress.CidrIp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-cidrip
        '''
        result = self._values.get("cidr_ip")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def cidr_ipv6(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupEgress.CidrIpv6``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-cidripv6
        '''
        result = self._values.get("cidr_ipv6")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupEgress.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def destination_prefix_list_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupEgress.DestinationPrefixListId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-destinationprefixlistid
        '''
        result = self._values.get("destination_prefix_list_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def destination_security_group_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupEgress.DestinationSecurityGroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-destinationsecuritygroupid
        '''
        result = self._values.get("destination_security_group_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def from_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::SecurityGroupEgress.FromPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-fromport
        '''
        result = self._values.get("from_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def to_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::SecurityGroupEgress.ToPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html#cfn-ec2-securitygroupegress-toport
        '''
        result = self._values.get("to_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnSecurityGroupEgressProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnSecurityGroupIngress(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnSecurityGroupIngress",
):
    '''A CloudFormation ``AWS::EC2::SecurityGroupIngress``.

    :cloudformationResource: AWS::EC2::SecurityGroupIngress
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        ip_protocol: builtins.str,
        cidr_ip: typing.Optional[builtins.str] = None,
        cidr_ipv6: typing.Optional[builtins.str] = None,
        description: typing.Optional[builtins.str] = None,
        from_port: typing.Optional[jsii.Number] = None,
        group_id: typing.Optional[builtins.str] = None,
        group_name: typing.Optional[builtins.str] = None,
        source_prefix_list_id: typing.Optional[builtins.str] = None,
        source_security_group_id: typing.Optional[builtins.str] = None,
        source_security_group_name: typing.Optional[builtins.str] = None,
        source_security_group_owner_id: typing.Optional[builtins.str] = None,
        to_port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::SecurityGroupIngress``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param ip_protocol: ``AWS::EC2::SecurityGroupIngress.IpProtocol``.
        :param cidr_ip: ``AWS::EC2::SecurityGroupIngress.CidrIp``.
        :param cidr_ipv6: ``AWS::EC2::SecurityGroupIngress.CidrIpv6``.
        :param description: ``AWS::EC2::SecurityGroupIngress.Description``.
        :param from_port: ``AWS::EC2::SecurityGroupIngress.FromPort``.
        :param group_id: ``AWS::EC2::SecurityGroupIngress.GroupId``.
        :param group_name: ``AWS::EC2::SecurityGroupIngress.GroupName``.
        :param source_prefix_list_id: ``AWS::EC2::SecurityGroupIngress.SourcePrefixListId``.
        :param source_security_group_id: ``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupId``.
        :param source_security_group_name: ``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupName``.
        :param source_security_group_owner_id: ``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupOwnerId``.
        :param to_port: ``AWS::EC2::SecurityGroupIngress.ToPort``.
        '''
        props = CfnSecurityGroupIngressProps(
            ip_protocol=ip_protocol,
            cidr_ip=cidr_ip,
            cidr_ipv6=cidr_ipv6,
            description=description,
            from_port=from_port,
            group_id=group_id,
            group_name=group_name,
            source_prefix_list_id=source_prefix_list_id,
            source_security_group_id=source_security_group_id,
            source_security_group_name=source_security_group_name,
            source_security_group_owner_id=source_security_group_owner_id,
            to_port=to_port,
        )

        jsii.create(CfnSecurityGroupIngress, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipProtocol")
    def ip_protocol(self) -> builtins.str:
        '''``AWS::EC2::SecurityGroupIngress.IpProtocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-ipprotocol
        '''
        return typing.cast(builtins.str, jsii.get(self, "ipProtocol"))

    @ip_protocol.setter
    def ip_protocol(self, value: builtins.str) -> None:
        jsii.set(self, "ipProtocol", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cidrIp")
    def cidr_ip(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.CidrIp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-cidrip
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "cidrIp"))

    @cidr_ip.setter
    def cidr_ip(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "cidrIp", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cidrIpv6")
    def cidr_ipv6(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.CidrIpv6``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-cidripv6
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "cidrIpv6"))

    @cidr_ipv6.setter
    def cidr_ipv6(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "cidrIpv6", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-description
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "description"))

    @description.setter
    def description(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="fromPort")
    def from_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::SecurityGroupIngress.FromPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-fromport
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "fromPort"))

    @from_port.setter
    def from_port(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "fromPort", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="groupId")
    def group_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.GroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-groupid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "groupId"))

    @group_id.setter
    def group_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "groupId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="groupName")
    def group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.GroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-groupname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "groupName"))

    @group_name.setter
    def group_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "groupName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sourcePrefixListId")
    def source_prefix_list_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.SourcePrefixListId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-securitygroupingress-sourceprefixlistid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "sourcePrefixListId"))

    @source_prefix_list_id.setter
    def source_prefix_list_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "sourcePrefixListId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sourceSecurityGroupId")
    def source_security_group_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-sourcesecuritygroupid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "sourceSecurityGroupId"))

    @source_security_group_id.setter
    def source_security_group_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "sourceSecurityGroupId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sourceSecurityGroupName")
    def source_security_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-sourcesecuritygroupname
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "sourceSecurityGroupName"))

    @source_security_group_name.setter
    def source_security_group_name(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "sourceSecurityGroupName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sourceSecurityGroupOwnerId")
    def source_security_group_owner_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupOwnerId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-sourcesecuritygroupownerid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "sourceSecurityGroupOwnerId"))

    @source_security_group_owner_id.setter
    def source_security_group_owner_id(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "sourceSecurityGroupOwnerId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="toPort")
    def to_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::SecurityGroupIngress.ToPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-toport
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "toPort"))

    @to_port.setter
    def to_port(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "toPort", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnSecurityGroupIngressProps",
    jsii_struct_bases=[],
    name_mapping={
        "ip_protocol": "ipProtocol",
        "cidr_ip": "cidrIp",
        "cidr_ipv6": "cidrIpv6",
        "description": "description",
        "from_port": "fromPort",
        "group_id": "groupId",
        "group_name": "groupName",
        "source_prefix_list_id": "sourcePrefixListId",
        "source_security_group_id": "sourceSecurityGroupId",
        "source_security_group_name": "sourceSecurityGroupName",
        "source_security_group_owner_id": "sourceSecurityGroupOwnerId",
        "to_port": "toPort",
    },
)
class CfnSecurityGroupIngressProps:
    def __init__(
        self,
        *,
        ip_protocol: builtins.str,
        cidr_ip: typing.Optional[builtins.str] = None,
        cidr_ipv6: typing.Optional[builtins.str] = None,
        description: typing.Optional[builtins.str] = None,
        from_port: typing.Optional[jsii.Number] = None,
        group_id: typing.Optional[builtins.str] = None,
        group_name: typing.Optional[builtins.str] = None,
        source_prefix_list_id: typing.Optional[builtins.str] = None,
        source_security_group_id: typing.Optional[builtins.str] = None,
        source_security_group_name: typing.Optional[builtins.str] = None,
        source_security_group_owner_id: typing.Optional[builtins.str] = None,
        to_port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::SecurityGroupIngress``.

        :param ip_protocol: ``AWS::EC2::SecurityGroupIngress.IpProtocol``.
        :param cidr_ip: ``AWS::EC2::SecurityGroupIngress.CidrIp``.
        :param cidr_ipv6: ``AWS::EC2::SecurityGroupIngress.CidrIpv6``.
        :param description: ``AWS::EC2::SecurityGroupIngress.Description``.
        :param from_port: ``AWS::EC2::SecurityGroupIngress.FromPort``.
        :param group_id: ``AWS::EC2::SecurityGroupIngress.GroupId``.
        :param group_name: ``AWS::EC2::SecurityGroupIngress.GroupName``.
        :param source_prefix_list_id: ``AWS::EC2::SecurityGroupIngress.SourcePrefixListId``.
        :param source_security_group_id: ``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupId``.
        :param source_security_group_name: ``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupName``.
        :param source_security_group_owner_id: ``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupOwnerId``.
        :param to_port: ``AWS::EC2::SecurityGroupIngress.ToPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "ip_protocol": ip_protocol,
        }
        if cidr_ip is not None:
            self._values["cidr_ip"] = cidr_ip
        if cidr_ipv6 is not None:
            self._values["cidr_ipv6"] = cidr_ipv6
        if description is not None:
            self._values["description"] = description
        if from_port is not None:
            self._values["from_port"] = from_port
        if group_id is not None:
            self._values["group_id"] = group_id
        if group_name is not None:
            self._values["group_name"] = group_name
        if source_prefix_list_id is not None:
            self._values["source_prefix_list_id"] = source_prefix_list_id
        if source_security_group_id is not None:
            self._values["source_security_group_id"] = source_security_group_id
        if source_security_group_name is not None:
            self._values["source_security_group_name"] = source_security_group_name
        if source_security_group_owner_id is not None:
            self._values["source_security_group_owner_id"] = source_security_group_owner_id
        if to_port is not None:
            self._values["to_port"] = to_port

    @builtins.property
    def ip_protocol(self) -> builtins.str:
        '''``AWS::EC2::SecurityGroupIngress.IpProtocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-ipprotocol
        '''
        result = self._values.get("ip_protocol")
        assert result is not None, "Required property 'ip_protocol' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def cidr_ip(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.CidrIp``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-cidrip
        '''
        result = self._values.get("cidr_ip")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def cidr_ipv6(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.CidrIpv6``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-cidripv6
        '''
        result = self._values.get("cidr_ipv6")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def from_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::SecurityGroupIngress.FromPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-fromport
        '''
        result = self._values.get("from_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def group_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.GroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-groupid
        '''
        result = self._values.get("group_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.GroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-groupname
        '''
        result = self._values.get("group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def source_prefix_list_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.SourcePrefixListId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-securitygroupingress-sourceprefixlistid
        '''
        result = self._values.get("source_prefix_list_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def source_security_group_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-sourcesecuritygroupid
        '''
        result = self._values.get("source_security_group_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def source_security_group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-sourcesecuritygroupname
        '''
        result = self._values.get("source_security_group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def source_security_group_owner_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroupIngress.SourceSecurityGroupOwnerId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-sourcesecuritygroupownerid
        '''
        result = self._values.get("source_security_group_owner_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def to_port(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::SecurityGroupIngress.ToPort``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group-ingress.html#cfn-ec2-security-group-ingress-toport
        '''
        result = self._values.get("to_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnSecurityGroupIngressProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnSecurityGroupProps",
    jsii_struct_bases=[],
    name_mapping={
        "group_description": "groupDescription",
        "group_name": "groupName",
        "security_group_egress": "securityGroupEgress",
        "security_group_ingress": "securityGroupIngress",
        "tags": "tags",
        "vpc_id": "vpcId",
    },
)
class CfnSecurityGroupProps:
    def __init__(
        self,
        *,
        group_description: builtins.str,
        group_name: typing.Optional[builtins.str] = None,
        security_group_egress: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnSecurityGroup.EgressProperty]]]] = None,
        security_group_ingress: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnSecurityGroup.IngressProperty]]]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        vpc_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::SecurityGroup``.

        :param group_description: ``AWS::EC2::SecurityGroup.GroupDescription``.
        :param group_name: ``AWS::EC2::SecurityGroup.GroupName``.
        :param security_group_egress: ``AWS::EC2::SecurityGroup.SecurityGroupEgress``.
        :param security_group_ingress: ``AWS::EC2::SecurityGroup.SecurityGroupIngress``.
        :param tags: ``AWS::EC2::SecurityGroup.Tags``.
        :param vpc_id: ``AWS::EC2::SecurityGroup.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "group_description": group_description,
        }
        if group_name is not None:
            self._values["group_name"] = group_name
        if security_group_egress is not None:
            self._values["security_group_egress"] = security_group_egress
        if security_group_ingress is not None:
            self._values["security_group_ingress"] = security_group_ingress
        if tags is not None:
            self._values["tags"] = tags
        if vpc_id is not None:
            self._values["vpc_id"] = vpc_id

    @builtins.property
    def group_description(self) -> builtins.str:
        '''``AWS::EC2::SecurityGroup.GroupDescription``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-groupdescription
        '''
        result = self._values.get("group_description")
        assert result is not None, "Required property 'group_description' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def group_name(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroup.GroupName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-groupname
        '''
        result = self._values.get("group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def security_group_egress(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnSecurityGroup.EgressProperty]]]]:
        '''``AWS::EC2::SecurityGroup.SecurityGroupEgress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-securitygroupegress
        '''
        result = self._values.get("security_group_egress")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnSecurityGroup.EgressProperty]]]], result)

    @builtins.property
    def security_group_ingress(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnSecurityGroup.IngressProperty]]]]:
        '''``AWS::EC2::SecurityGroup.SecurityGroupIngress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-securitygroupingress
        '''
        result = self._values.get("security_group_ingress")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnSecurityGroup.IngressProperty]]]], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::SecurityGroup.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    @builtins.property
    def vpc_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::SecurityGroup.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-vpcid
        '''
        result = self._values.get("vpc_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnSecurityGroupProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnSpotFleet(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet",
):
    '''A CloudFormation ``AWS::EC2::SpotFleet``.

    :cloudformationResource: AWS::EC2::SpotFleet
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-spotfleet.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        spot_fleet_request_config_data: typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetRequestConfigDataProperty"],
    ) -> None:
        '''Create a new ``AWS::EC2::SpotFleet``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param spot_fleet_request_config_data: ``AWS::EC2::SpotFleet.SpotFleetRequestConfigData``.
        '''
        props = CfnSpotFleetProps(
            spot_fleet_request_config_data=spot_fleet_request_config_data
        )

        jsii.create(CfnSpotFleet, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="spotFleetRequestConfigData")
    def spot_fleet_request_config_data(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetRequestConfigDataProperty"]:
        '''``AWS::EC2::SpotFleet.SpotFleetRequestConfigData``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-spotfleet.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetRequestConfigDataProperty"], jsii.get(self, "spotFleetRequestConfigData"))

    @spot_fleet_request_config_data.setter
    def spot_fleet_request_config_data(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetRequestConfigDataProperty"],
    ) -> None:
        jsii.set(self, "spotFleetRequestConfigData", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.BlockDeviceMappingProperty",
        jsii_struct_bases=[],
        name_mapping={
            "device_name": "deviceName",
            "ebs": "ebs",
            "no_device": "noDevice",
            "virtual_name": "virtualName",
        },
    )
    class BlockDeviceMappingProperty:
        def __init__(
            self,
            *,
            device_name: builtins.str,
            ebs: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.EbsBlockDeviceProperty"]] = None,
            no_device: typing.Optional[builtins.str] = None,
            virtual_name: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param device_name: ``CfnSpotFleet.BlockDeviceMappingProperty.DeviceName``.
            :param ebs: ``CfnSpotFleet.BlockDeviceMappingProperty.Ebs``.
            :param no_device: ``CfnSpotFleet.BlockDeviceMappingProperty.NoDevice``.
            :param virtual_name: ``CfnSpotFleet.BlockDeviceMappingProperty.VirtualName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "device_name": device_name,
            }
            if ebs is not None:
                self._values["ebs"] = ebs
            if no_device is not None:
                self._values["no_device"] = no_device
            if virtual_name is not None:
                self._values["virtual_name"] = virtual_name

        @builtins.property
        def device_name(self) -> builtins.str:
            '''``CfnSpotFleet.BlockDeviceMappingProperty.DeviceName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings.html#cfn-ec2-spotfleet-blockdevicemapping-devicename
            '''
            result = self._values.get("device_name")
            assert result is not None, "Required property 'device_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def ebs(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.EbsBlockDeviceProperty"]]:
            '''``CfnSpotFleet.BlockDeviceMappingProperty.Ebs``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings.html#cfn-ec2-spotfleet-blockdevicemapping-ebs
            '''
            result = self._values.get("ebs")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.EbsBlockDeviceProperty"]], result)

        @builtins.property
        def no_device(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.BlockDeviceMappingProperty.NoDevice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings.html#cfn-ec2-spotfleet-blockdevicemapping-nodevice
            '''
            result = self._values.get("no_device")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def virtual_name(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.BlockDeviceMappingProperty.VirtualName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings.html#cfn-ec2-spotfleet-blockdevicemapping-virtualname
            '''
            result = self._values.get("virtual_name")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "BlockDeviceMappingProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.ClassicLoadBalancerProperty",
        jsii_struct_bases=[],
        name_mapping={"name": "name"},
    )
    class ClassicLoadBalancerProperty:
        def __init__(self, *, name: builtins.str) -> None:
            '''
            :param name: ``CfnSpotFleet.ClassicLoadBalancerProperty.Name``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-classicloadbalancer.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "name": name,
            }

        @builtins.property
        def name(self) -> builtins.str:
            '''``CfnSpotFleet.ClassicLoadBalancerProperty.Name``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-classicloadbalancer.html#cfn-ec2-spotfleet-classicloadbalancer-name
            '''
            result = self._values.get("name")
            assert result is not None, "Required property 'name' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ClassicLoadBalancerProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.ClassicLoadBalancersConfigProperty",
        jsii_struct_bases=[],
        name_mapping={"classic_load_balancers": "classicLoadBalancers"},
    )
    class ClassicLoadBalancersConfigProperty:
        def __init__(
            self,
            *,
            classic_load_balancers: typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.ClassicLoadBalancerProperty"]]],
        ) -> None:
            '''
            :param classic_load_balancers: ``CfnSpotFleet.ClassicLoadBalancersConfigProperty.ClassicLoadBalancers``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-classicloadbalancersconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "classic_load_balancers": classic_load_balancers,
            }

        @builtins.property
        def classic_load_balancers(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.ClassicLoadBalancerProperty"]]]:
            '''``CfnSpotFleet.ClassicLoadBalancersConfigProperty.ClassicLoadBalancers``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-classicloadbalancersconfig.html#cfn-ec2-spotfleet-classicloadbalancersconfig-classicloadbalancers
            '''
            result = self._values.get("classic_load_balancers")
            assert result is not None, "Required property 'classic_load_balancers' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.ClassicLoadBalancerProperty"]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ClassicLoadBalancersConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.EbsBlockDeviceProperty",
        jsii_struct_bases=[],
        name_mapping={
            "delete_on_termination": "deleteOnTermination",
            "encrypted": "encrypted",
            "iops": "iops",
            "snapshot_id": "snapshotId",
            "volume_size": "volumeSize",
            "volume_type": "volumeType",
        },
    )
    class EbsBlockDeviceProperty:
        def __init__(
            self,
            *,
            delete_on_termination: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            encrypted: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            iops: typing.Optional[jsii.Number] = None,
            snapshot_id: typing.Optional[builtins.str] = None,
            volume_size: typing.Optional[jsii.Number] = None,
            volume_type: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param delete_on_termination: ``CfnSpotFleet.EbsBlockDeviceProperty.DeleteOnTermination``.
            :param encrypted: ``CfnSpotFleet.EbsBlockDeviceProperty.Encrypted``.
            :param iops: ``CfnSpotFleet.EbsBlockDeviceProperty.Iops``.
            :param snapshot_id: ``CfnSpotFleet.EbsBlockDeviceProperty.SnapshotId``.
            :param volume_size: ``CfnSpotFleet.EbsBlockDeviceProperty.VolumeSize``.
            :param volume_type: ``CfnSpotFleet.EbsBlockDeviceProperty.VolumeType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings-ebs.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if delete_on_termination is not None:
                self._values["delete_on_termination"] = delete_on_termination
            if encrypted is not None:
                self._values["encrypted"] = encrypted
            if iops is not None:
                self._values["iops"] = iops
            if snapshot_id is not None:
                self._values["snapshot_id"] = snapshot_id
            if volume_size is not None:
                self._values["volume_size"] = volume_size
            if volume_type is not None:
                self._values["volume_type"] = volume_type

        @builtins.property
        def delete_on_termination(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnSpotFleet.EbsBlockDeviceProperty.DeleteOnTermination``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings-ebs.html#cfn-ec2-spotfleet-ebsblockdevice-deleteontermination
            '''
            result = self._values.get("delete_on_termination")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def encrypted(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnSpotFleet.EbsBlockDeviceProperty.Encrypted``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings-ebs.html#cfn-ec2-spotfleet-ebsblockdevice-encrypted
            '''
            result = self._values.get("encrypted")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def iops(self) -> typing.Optional[jsii.Number]:
            '''``CfnSpotFleet.EbsBlockDeviceProperty.Iops``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings-ebs.html#cfn-ec2-spotfleet-ebsblockdevice-iops
            '''
            result = self._values.get("iops")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def snapshot_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.EbsBlockDeviceProperty.SnapshotId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings-ebs.html#cfn-ec2-spotfleet-ebsblockdevice-snapshotid
            '''
            result = self._values.get("snapshot_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def volume_size(self) -> typing.Optional[jsii.Number]:
            '''``CfnSpotFleet.EbsBlockDeviceProperty.VolumeSize``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings-ebs.html#cfn-ec2-spotfleet-ebsblockdevice-volumesize
            '''
            result = self._values.get("volume_size")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def volume_type(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.EbsBlockDeviceProperty.VolumeType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-blockdevicemappings-ebs.html#cfn-ec2-spotfleet-ebsblockdevice-volumetype
            '''
            result = self._values.get("volume_type")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "EbsBlockDeviceProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.FleetLaunchTemplateSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={
            "version": "version",
            "launch_template_id": "launchTemplateId",
            "launch_template_name": "launchTemplateName",
        },
    )
    class FleetLaunchTemplateSpecificationProperty:
        def __init__(
            self,
            *,
            version: builtins.str,
            launch_template_id: typing.Optional[builtins.str] = None,
            launch_template_name: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param version: ``CfnSpotFleet.FleetLaunchTemplateSpecificationProperty.Version``.
            :param launch_template_id: ``CfnSpotFleet.FleetLaunchTemplateSpecificationProperty.LaunchTemplateId``.
            :param launch_template_name: ``CfnSpotFleet.FleetLaunchTemplateSpecificationProperty.LaunchTemplateName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-fleetlaunchtemplatespecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "version": version,
            }
            if launch_template_id is not None:
                self._values["launch_template_id"] = launch_template_id
            if launch_template_name is not None:
                self._values["launch_template_name"] = launch_template_name

        @builtins.property
        def version(self) -> builtins.str:
            '''``CfnSpotFleet.FleetLaunchTemplateSpecificationProperty.Version``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-fleetlaunchtemplatespecification.html#cfn-ec2-spotfleet-fleetlaunchtemplatespecification-version
            '''
            result = self._values.get("version")
            assert result is not None, "Required property 'version' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def launch_template_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.FleetLaunchTemplateSpecificationProperty.LaunchTemplateId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-fleetlaunchtemplatespecification.html#cfn-ec2-spotfleet-fleetlaunchtemplatespecification-launchtemplateid
            '''
            result = self._values.get("launch_template_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def launch_template_name(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.FleetLaunchTemplateSpecificationProperty.LaunchTemplateName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-fleetlaunchtemplatespecification.html#cfn-ec2-spotfleet-fleetlaunchtemplatespecification-launchtemplatename
            '''
            result = self._values.get("launch_template_name")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "FleetLaunchTemplateSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.GroupIdentifierProperty",
        jsii_struct_bases=[],
        name_mapping={"group_id": "groupId"},
    )
    class GroupIdentifierProperty:
        def __init__(self, *, group_id: builtins.str) -> None:
            '''
            :param group_id: ``CfnSpotFleet.GroupIdentifierProperty.GroupId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-securitygroups.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "group_id": group_id,
            }

        @builtins.property
        def group_id(self) -> builtins.str:
            '''``CfnSpotFleet.GroupIdentifierProperty.GroupId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-securitygroups.html#cfn-ec2-spotfleet-groupidentifier-groupid
            '''
            result = self._values.get("group_id")
            assert result is not None, "Required property 'group_id' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GroupIdentifierProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.IamInstanceProfileSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"arn": "arn"},
    )
    class IamInstanceProfileSpecificationProperty:
        def __init__(self, *, arn: typing.Optional[builtins.str] = None) -> None:
            '''
            :param arn: ``CfnSpotFleet.IamInstanceProfileSpecificationProperty.Arn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-iaminstanceprofile.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if arn is not None:
                self._values["arn"] = arn

        @builtins.property
        def arn(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.IamInstanceProfileSpecificationProperty.Arn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-iaminstanceprofile.html#cfn-ec2-spotfleet-iaminstanceprofilespecification-arn
            '''
            result = self._values.get("arn")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "IamInstanceProfileSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.InstanceIpv6AddressProperty",
        jsii_struct_bases=[],
        name_mapping={"ipv6_address": "ipv6Address"},
    )
    class InstanceIpv6AddressProperty:
        def __init__(self, *, ipv6_address: builtins.str) -> None:
            '''
            :param ipv6_address: ``CfnSpotFleet.InstanceIpv6AddressProperty.Ipv6Address``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instanceipv6address.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "ipv6_address": ipv6_address,
            }

        @builtins.property
        def ipv6_address(self) -> builtins.str:
            '''``CfnSpotFleet.InstanceIpv6AddressProperty.Ipv6Address``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instanceipv6address.html#cfn-ec2-spotfleet-instanceipv6address-ipv6address
            '''
            result = self._values.get("ipv6_address")
            assert result is not None, "Required property 'ipv6_address' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "InstanceIpv6AddressProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={
            "associate_public_ip_address": "associatePublicIpAddress",
            "delete_on_termination": "deleteOnTermination",
            "description": "description",
            "device_index": "deviceIndex",
            "groups": "groups",
            "ipv6_address_count": "ipv6AddressCount",
            "ipv6_addresses": "ipv6Addresses",
            "network_interface_id": "networkInterfaceId",
            "private_ip_addresses": "privateIpAddresses",
            "secondary_private_ip_address_count": "secondaryPrivateIpAddressCount",
            "subnet_id": "subnetId",
        },
    )
    class InstanceNetworkInterfaceSpecificationProperty:
        def __init__(
            self,
            *,
            associate_public_ip_address: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            delete_on_termination: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            description: typing.Optional[builtins.str] = None,
            device_index: typing.Optional[jsii.Number] = None,
            groups: typing.Optional[typing.List[builtins.str]] = None,
            ipv6_address_count: typing.Optional[jsii.Number] = None,
            ipv6_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.InstanceIpv6AddressProperty"]]]] = None,
            network_interface_id: typing.Optional[builtins.str] = None,
            private_ip_addresses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.PrivateIpAddressSpecificationProperty"]]]] = None,
            secondary_private_ip_address_count: typing.Optional[jsii.Number] = None,
            subnet_id: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param associate_public_ip_address: ``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.AssociatePublicIpAddress``.
            :param delete_on_termination: ``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.DeleteOnTermination``.
            :param description: ``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.Description``.
            :param device_index: ``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.DeviceIndex``.
            :param groups: ``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.Groups``.
            :param ipv6_address_count: ``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.Ipv6AddressCount``.
            :param ipv6_addresses: ``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.Ipv6Addresses``.
            :param network_interface_id: ``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.NetworkInterfaceId``.
            :param private_ip_addresses: ``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.PrivateIpAddresses``.
            :param secondary_private_ip_address_count: ``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.SecondaryPrivateIpAddressCount``.
            :param subnet_id: ``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.SubnetId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if associate_public_ip_address is not None:
                self._values["associate_public_ip_address"] = associate_public_ip_address
            if delete_on_termination is not None:
                self._values["delete_on_termination"] = delete_on_termination
            if description is not None:
                self._values["description"] = description
            if device_index is not None:
                self._values["device_index"] = device_index
            if groups is not None:
                self._values["groups"] = groups
            if ipv6_address_count is not None:
                self._values["ipv6_address_count"] = ipv6_address_count
            if ipv6_addresses is not None:
                self._values["ipv6_addresses"] = ipv6_addresses
            if network_interface_id is not None:
                self._values["network_interface_id"] = network_interface_id
            if private_ip_addresses is not None:
                self._values["private_ip_addresses"] = private_ip_addresses
            if secondary_private_ip_address_count is not None:
                self._values["secondary_private_ip_address_count"] = secondary_private_ip_address_count
            if subnet_id is not None:
                self._values["subnet_id"] = subnet_id

        @builtins.property
        def associate_public_ip_address(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.AssociatePublicIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html#cfn-ec2-spotfleet-instancenetworkinterfacespecification-associatepublicipaddress
            '''
            result = self._values.get("associate_public_ip_address")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def delete_on_termination(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.DeleteOnTermination``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html#cfn-ec2-spotfleet-instancenetworkinterfacespecification-deleteontermination
            '''
            result = self._values.get("delete_on_termination")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def description(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.Description``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html#cfn-ec2-spotfleet-instancenetworkinterfacespecification-description
            '''
            result = self._values.get("description")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def device_index(self) -> typing.Optional[jsii.Number]:
            '''``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.DeviceIndex``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html#cfn-ec2-spotfleet-instancenetworkinterfacespecification-deviceindex
            '''
            result = self._values.get("device_index")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def groups(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.Groups``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html#cfn-ec2-spotfleet-instancenetworkinterfacespecification-groups
            '''
            result = self._values.get("groups")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def ipv6_address_count(self) -> typing.Optional[jsii.Number]:
            '''``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.Ipv6AddressCount``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html#cfn-ec2-spotfleet-instancenetworkinterfacespecification-ipv6addresscount
            '''
            result = self._values.get("ipv6_address_count")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def ipv6_addresses(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.InstanceIpv6AddressProperty"]]]]:
            '''``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.Ipv6Addresses``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html#cfn-ec2-spotfleet-instancenetworkinterfacespecification-ipv6addresses
            '''
            result = self._values.get("ipv6_addresses")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.InstanceIpv6AddressProperty"]]]], result)

        @builtins.property
        def network_interface_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.NetworkInterfaceId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html#cfn-ec2-spotfleet-instancenetworkinterfacespecification-networkinterfaceid
            '''
            result = self._values.get("network_interface_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def private_ip_addresses(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.PrivateIpAddressSpecificationProperty"]]]]:
            '''``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.PrivateIpAddresses``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html#cfn-ec2-spotfleet-instancenetworkinterfacespecification-privateipaddresses
            '''
            result = self._values.get("private_ip_addresses")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.PrivateIpAddressSpecificationProperty"]]]], result)

        @builtins.property
        def secondary_private_ip_address_count(self) -> typing.Optional[jsii.Number]:
            '''``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.SecondaryPrivateIpAddressCount``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html#cfn-ec2-spotfleet-instancenetworkinterfacespecification-secondaryprivateipaddresscount
            '''
            result = self._values.get("secondary_private_ip_address_count")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def subnet_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty.SubnetId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces.html#cfn-ec2-spotfleet-instancenetworkinterfacespecification-subnetid
            '''
            result = self._values.get("subnet_id")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "InstanceNetworkInterfaceSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.LaunchTemplateConfigProperty",
        jsii_struct_bases=[],
        name_mapping={
            "launch_template_specification": "launchTemplateSpecification",
            "overrides": "overrides",
        },
    )
    class LaunchTemplateConfigProperty:
        def __init__(
            self,
            *,
            launch_template_specification: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.FleetLaunchTemplateSpecificationProperty"]] = None,
            overrides: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.LaunchTemplateOverridesProperty"]]]] = None,
        ) -> None:
            '''
            :param launch_template_specification: ``CfnSpotFleet.LaunchTemplateConfigProperty.LaunchTemplateSpecification``.
            :param overrides: ``CfnSpotFleet.LaunchTemplateConfigProperty.Overrides``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if launch_template_specification is not None:
                self._values["launch_template_specification"] = launch_template_specification
            if overrides is not None:
                self._values["overrides"] = overrides

        @builtins.property
        def launch_template_specification(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.FleetLaunchTemplateSpecificationProperty"]]:
            '''``CfnSpotFleet.LaunchTemplateConfigProperty.LaunchTemplateSpecification``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateconfig.html#cfn-ec2-spotfleet-launchtemplateconfig-launchtemplatespecification
            '''
            result = self._values.get("launch_template_specification")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.FleetLaunchTemplateSpecificationProperty"]], result)

        @builtins.property
        def overrides(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.LaunchTemplateOverridesProperty"]]]]:
            '''``CfnSpotFleet.LaunchTemplateConfigProperty.Overrides``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateconfig.html#cfn-ec2-spotfleet-launchtemplateconfig-overrides
            '''
            result = self._values.get("overrides")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.LaunchTemplateOverridesProperty"]]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LaunchTemplateConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.LaunchTemplateOverridesProperty",
        jsii_struct_bases=[],
        name_mapping={
            "availability_zone": "availabilityZone",
            "instance_type": "instanceType",
            "priority": "priority",
            "spot_price": "spotPrice",
            "subnet_id": "subnetId",
            "weighted_capacity": "weightedCapacity",
        },
    )
    class LaunchTemplateOverridesProperty:
        def __init__(
            self,
            *,
            availability_zone: typing.Optional[builtins.str] = None,
            instance_type: typing.Optional[builtins.str] = None,
            priority: typing.Optional[jsii.Number] = None,
            spot_price: typing.Optional[builtins.str] = None,
            subnet_id: typing.Optional[builtins.str] = None,
            weighted_capacity: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param availability_zone: ``CfnSpotFleet.LaunchTemplateOverridesProperty.AvailabilityZone``.
            :param instance_type: ``CfnSpotFleet.LaunchTemplateOverridesProperty.InstanceType``.
            :param priority: ``CfnSpotFleet.LaunchTemplateOverridesProperty.Priority``.
            :param spot_price: ``CfnSpotFleet.LaunchTemplateOverridesProperty.SpotPrice``.
            :param subnet_id: ``CfnSpotFleet.LaunchTemplateOverridesProperty.SubnetId``.
            :param weighted_capacity: ``CfnSpotFleet.LaunchTemplateOverridesProperty.WeightedCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateoverrides.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if availability_zone is not None:
                self._values["availability_zone"] = availability_zone
            if instance_type is not None:
                self._values["instance_type"] = instance_type
            if priority is not None:
                self._values["priority"] = priority
            if spot_price is not None:
                self._values["spot_price"] = spot_price
            if subnet_id is not None:
                self._values["subnet_id"] = subnet_id
            if weighted_capacity is not None:
                self._values["weighted_capacity"] = weighted_capacity

        @builtins.property
        def availability_zone(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.LaunchTemplateOverridesProperty.AvailabilityZone``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateoverrides.html#cfn-ec2-spotfleet-launchtemplateoverrides-availabilityzone
            '''
            result = self._values.get("availability_zone")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def instance_type(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.LaunchTemplateOverridesProperty.InstanceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateoverrides.html#cfn-ec2-spotfleet-launchtemplateoverrides-instancetype
            '''
            result = self._values.get("instance_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def priority(self) -> typing.Optional[jsii.Number]:
            '''``CfnSpotFleet.LaunchTemplateOverridesProperty.Priority``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateoverrides.html#cfn-ec2-spotfleet-launchtemplateoverrides-priority
            '''
            result = self._values.get("priority")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def spot_price(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.LaunchTemplateOverridesProperty.SpotPrice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateoverrides.html#cfn-ec2-spotfleet-launchtemplateoverrides-spotprice
            '''
            result = self._values.get("spot_price")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def subnet_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.LaunchTemplateOverridesProperty.SubnetId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateoverrides.html#cfn-ec2-spotfleet-launchtemplateoverrides-subnetid
            '''
            result = self._values.get("subnet_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def weighted_capacity(self) -> typing.Optional[jsii.Number]:
            '''``CfnSpotFleet.LaunchTemplateOverridesProperty.WeightedCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateoverrides.html#cfn-ec2-spotfleet-launchtemplateoverrides-weightedcapacity
            '''
            result = self._values.get("weighted_capacity")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LaunchTemplateOverridesProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.LoadBalancersConfigProperty",
        jsii_struct_bases=[],
        name_mapping={
            "classic_load_balancers_config": "classicLoadBalancersConfig",
            "target_groups_config": "targetGroupsConfig",
        },
    )
    class LoadBalancersConfigProperty:
        def __init__(
            self,
            *,
            classic_load_balancers_config: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.ClassicLoadBalancersConfigProperty"]] = None,
            target_groups_config: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.TargetGroupsConfigProperty"]] = None,
        ) -> None:
            '''
            :param classic_load_balancers_config: ``CfnSpotFleet.LoadBalancersConfigProperty.ClassicLoadBalancersConfig``.
            :param target_groups_config: ``CfnSpotFleet.LoadBalancersConfigProperty.TargetGroupsConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-loadbalancersconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if classic_load_balancers_config is not None:
                self._values["classic_load_balancers_config"] = classic_load_balancers_config
            if target_groups_config is not None:
                self._values["target_groups_config"] = target_groups_config

        @builtins.property
        def classic_load_balancers_config(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.ClassicLoadBalancersConfigProperty"]]:
            '''``CfnSpotFleet.LoadBalancersConfigProperty.ClassicLoadBalancersConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-loadbalancersconfig.html#cfn-ec2-spotfleet-loadbalancersconfig-classicloadbalancersconfig
            '''
            result = self._values.get("classic_load_balancers_config")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.ClassicLoadBalancersConfigProperty"]], result)

        @builtins.property
        def target_groups_config(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.TargetGroupsConfigProperty"]]:
            '''``CfnSpotFleet.LoadBalancersConfigProperty.TargetGroupsConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-loadbalancersconfig.html#cfn-ec2-spotfleet-loadbalancersconfig-targetgroupsconfig
            '''
            result = self._values.get("target_groups_config")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.TargetGroupsConfigProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LoadBalancersConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.PrivateIpAddressSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"private_ip_address": "privateIpAddress", "primary": "primary"},
    )
    class PrivateIpAddressSpecificationProperty:
        def __init__(
            self,
            *,
            private_ip_address: builtins.str,
            primary: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ) -> None:
            '''
            :param private_ip_address: ``CfnSpotFleet.PrivateIpAddressSpecificationProperty.PrivateIpAddress``.
            :param primary: ``CfnSpotFleet.PrivateIpAddressSpecificationProperty.Primary``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces-privateipaddresses.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "private_ip_address": private_ip_address,
            }
            if primary is not None:
                self._values["primary"] = primary

        @builtins.property
        def private_ip_address(self) -> builtins.str:
            '''``CfnSpotFleet.PrivateIpAddressSpecificationProperty.PrivateIpAddress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces-privateipaddresses.html#cfn-ec2-spotfleet-privateipaddressspecification-privateipaddress
            '''
            result = self._values.get("private_ip_address")
            assert result is not None, "Required property 'private_ip_address' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def primary(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnSpotFleet.PrivateIpAddressSpecificationProperty.Primary``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-networkinterfaces-privateipaddresses.html#cfn-ec2-spotfleet-privateipaddressspecification-primary
            '''
            result = self._values.get("primary")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PrivateIpAddressSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.SpotCapacityRebalanceProperty",
        jsii_struct_bases=[],
        name_mapping={"replacement_strategy": "replacementStrategy"},
    )
    class SpotCapacityRebalanceProperty:
        def __init__(
            self,
            *,
            replacement_strategy: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param replacement_strategy: ``CfnSpotFleet.SpotCapacityRebalanceProperty.ReplacementStrategy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotcapacityrebalance.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if replacement_strategy is not None:
                self._values["replacement_strategy"] = replacement_strategy

        @builtins.property
        def replacement_strategy(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotCapacityRebalanceProperty.ReplacementStrategy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotcapacityrebalance.html#cfn-ec2-spotfleet-spotcapacityrebalance-replacementstrategy
            '''
            result = self._values.get("replacement_strategy")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SpotCapacityRebalanceProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.SpotFleetLaunchSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={
            "image_id": "imageId",
            "instance_type": "instanceType",
            "block_device_mappings": "blockDeviceMappings",
            "ebs_optimized": "ebsOptimized",
            "iam_instance_profile": "iamInstanceProfile",
            "kernel_id": "kernelId",
            "key_name": "keyName",
            "monitoring": "monitoring",
            "network_interfaces": "networkInterfaces",
            "placement": "placement",
            "ramdisk_id": "ramdiskId",
            "security_groups": "securityGroups",
            "spot_price": "spotPrice",
            "subnet_id": "subnetId",
            "tag_specifications": "tagSpecifications",
            "user_data": "userData",
            "weighted_capacity": "weightedCapacity",
        },
    )
    class SpotFleetLaunchSpecificationProperty:
        def __init__(
            self,
            *,
            image_id: builtins.str,
            instance_type: builtins.str,
            block_device_mappings: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.BlockDeviceMappingProperty"]]]] = None,
            ebs_optimized: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            iam_instance_profile: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.IamInstanceProfileSpecificationProperty"]] = None,
            kernel_id: typing.Optional[builtins.str] = None,
            key_name: typing.Optional[builtins.str] = None,
            monitoring: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetMonitoringProperty"]] = None,
            network_interfaces: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty"]]]] = None,
            placement: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotPlacementProperty"]] = None,
            ramdisk_id: typing.Optional[builtins.str] = None,
            security_groups: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.GroupIdentifierProperty"]]]] = None,
            spot_price: typing.Optional[builtins.str] = None,
            subnet_id: typing.Optional[builtins.str] = None,
            tag_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetTagSpecificationProperty"]]]] = None,
            user_data: typing.Optional[builtins.str] = None,
            weighted_capacity: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param image_id: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.ImageId``.
            :param instance_type: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.InstanceType``.
            :param block_device_mappings: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.BlockDeviceMappings``.
            :param ebs_optimized: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.EbsOptimized``.
            :param iam_instance_profile: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.IamInstanceProfile``.
            :param kernel_id: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.KernelId``.
            :param key_name: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.KeyName``.
            :param monitoring: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.Monitoring``.
            :param network_interfaces: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.NetworkInterfaces``.
            :param placement: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.Placement``.
            :param ramdisk_id: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.RamdiskId``.
            :param security_groups: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.SecurityGroups``.
            :param spot_price: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.SpotPrice``.
            :param subnet_id: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.SubnetId``.
            :param tag_specifications: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.TagSpecifications``.
            :param user_data: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.UserData``.
            :param weighted_capacity: ``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.WeightedCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "image_id": image_id,
                "instance_type": instance_type,
            }
            if block_device_mappings is not None:
                self._values["block_device_mappings"] = block_device_mappings
            if ebs_optimized is not None:
                self._values["ebs_optimized"] = ebs_optimized
            if iam_instance_profile is not None:
                self._values["iam_instance_profile"] = iam_instance_profile
            if kernel_id is not None:
                self._values["kernel_id"] = kernel_id
            if key_name is not None:
                self._values["key_name"] = key_name
            if monitoring is not None:
                self._values["monitoring"] = monitoring
            if network_interfaces is not None:
                self._values["network_interfaces"] = network_interfaces
            if placement is not None:
                self._values["placement"] = placement
            if ramdisk_id is not None:
                self._values["ramdisk_id"] = ramdisk_id
            if security_groups is not None:
                self._values["security_groups"] = security_groups
            if spot_price is not None:
                self._values["spot_price"] = spot_price
            if subnet_id is not None:
                self._values["subnet_id"] = subnet_id
            if tag_specifications is not None:
                self._values["tag_specifications"] = tag_specifications
            if user_data is not None:
                self._values["user_data"] = user_data
            if weighted_capacity is not None:
                self._values["weighted_capacity"] = weighted_capacity

        @builtins.property
        def image_id(self) -> builtins.str:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.ImageId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-imageid
            '''
            result = self._values.get("image_id")
            assert result is not None, "Required property 'image_id' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def instance_type(self) -> builtins.str:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.InstanceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-instancetype
            '''
            result = self._values.get("instance_type")
            assert result is not None, "Required property 'instance_type' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def block_device_mappings(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.BlockDeviceMappingProperty"]]]]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.BlockDeviceMappings``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-blockdevicemappings
            '''
            result = self._values.get("block_device_mappings")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.BlockDeviceMappingProperty"]]]], result)

        @builtins.property
        def ebs_optimized(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.EbsOptimized``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-ebsoptimized
            '''
            result = self._values.get("ebs_optimized")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def iam_instance_profile(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.IamInstanceProfileSpecificationProperty"]]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.IamInstanceProfile``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-iaminstanceprofile
            '''
            result = self._values.get("iam_instance_profile")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.IamInstanceProfileSpecificationProperty"]], result)

        @builtins.property
        def kernel_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.KernelId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-kernelid
            '''
            result = self._values.get("kernel_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def key_name(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.KeyName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-keyname
            '''
            result = self._values.get("key_name")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def monitoring(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetMonitoringProperty"]]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.Monitoring``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-monitoring
            '''
            result = self._values.get("monitoring")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetMonitoringProperty"]], result)

        @builtins.property
        def network_interfaces(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty"]]]]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.NetworkInterfaces``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-networkinterfaces
            '''
            result = self._values.get("network_interfaces")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.InstanceNetworkInterfaceSpecificationProperty"]]]], result)

        @builtins.property
        def placement(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotPlacementProperty"]]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.Placement``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-placement
            '''
            result = self._values.get("placement")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotPlacementProperty"]], result)

        @builtins.property
        def ramdisk_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.RamdiskId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-ramdiskid
            '''
            result = self._values.get("ramdisk_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def security_groups(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.GroupIdentifierProperty"]]]]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.SecurityGroups``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-securitygroups
            '''
            result = self._values.get("security_groups")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.GroupIdentifierProperty"]]]], result)

        @builtins.property
        def spot_price(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.SpotPrice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-spotprice
            '''
            result = self._values.get("spot_price")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def subnet_id(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.SubnetId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-subnetid
            '''
            result = self._values.get("subnet_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def tag_specifications(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetTagSpecificationProperty"]]]]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.TagSpecifications``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-tagspecifications
            '''
            result = self._values.get("tag_specifications")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetTagSpecificationProperty"]]]], result)

        @builtins.property
        def user_data(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.UserData``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-userdata
            '''
            result = self._values.get("user_data")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def weighted_capacity(self) -> typing.Optional[jsii.Number]:
            '''``CfnSpotFleet.SpotFleetLaunchSpecificationProperty.WeightedCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-weightedcapacity
            '''
            result = self._values.get("weighted_capacity")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SpotFleetLaunchSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.SpotFleetMonitoringProperty",
        jsii_struct_bases=[],
        name_mapping={"enabled": "enabled"},
    )
    class SpotFleetMonitoringProperty:
        def __init__(
            self,
            *,
            enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ) -> None:
            '''
            :param enabled: ``CfnSpotFleet.SpotFleetMonitoringProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-monitoring.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if enabled is not None:
                self._values["enabled"] = enabled

        @builtins.property
        def enabled(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnSpotFleet.SpotFleetMonitoringProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-monitoring.html#cfn-ec2-spotfleet-spotfleetmonitoring-enabled
            '''
            result = self._values.get("enabled")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SpotFleetMonitoringProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.SpotFleetRequestConfigDataProperty",
        jsii_struct_bases=[],
        name_mapping={
            "iam_fleet_role": "iamFleetRole",
            "target_capacity": "targetCapacity",
            "allocation_strategy": "allocationStrategy",
            "excess_capacity_termination_policy": "excessCapacityTerminationPolicy",
            "instance_interruption_behavior": "instanceInterruptionBehavior",
            "instance_pools_to_use_count": "instancePoolsToUseCount",
            "launch_specifications": "launchSpecifications",
            "launch_template_configs": "launchTemplateConfigs",
            "load_balancers_config": "loadBalancersConfig",
            "on_demand_allocation_strategy": "onDemandAllocationStrategy",
            "on_demand_max_total_price": "onDemandMaxTotalPrice",
            "on_demand_target_capacity": "onDemandTargetCapacity",
            "replace_unhealthy_instances": "replaceUnhealthyInstances",
            "spot_maintenance_strategies": "spotMaintenanceStrategies",
            "spot_max_total_price": "spotMaxTotalPrice",
            "spot_price": "spotPrice",
            "terminate_instances_with_expiration": "terminateInstancesWithExpiration",
            "type": "type",
            "valid_from": "validFrom",
            "valid_until": "validUntil",
        },
    )
    class SpotFleetRequestConfigDataProperty:
        def __init__(
            self,
            *,
            iam_fleet_role: builtins.str,
            target_capacity: jsii.Number,
            allocation_strategy: typing.Optional[builtins.str] = None,
            excess_capacity_termination_policy: typing.Optional[builtins.str] = None,
            instance_interruption_behavior: typing.Optional[builtins.str] = None,
            instance_pools_to_use_count: typing.Optional[jsii.Number] = None,
            launch_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetLaunchSpecificationProperty"]]]] = None,
            launch_template_configs: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.LaunchTemplateConfigProperty"]]]] = None,
            load_balancers_config: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.LoadBalancersConfigProperty"]] = None,
            on_demand_allocation_strategy: typing.Optional[builtins.str] = None,
            on_demand_max_total_price: typing.Optional[builtins.str] = None,
            on_demand_target_capacity: typing.Optional[jsii.Number] = None,
            replace_unhealthy_instances: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            spot_maintenance_strategies: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotMaintenanceStrategiesProperty"]] = None,
            spot_max_total_price: typing.Optional[builtins.str] = None,
            spot_price: typing.Optional[builtins.str] = None,
            terminate_instances_with_expiration: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            type: typing.Optional[builtins.str] = None,
            valid_from: typing.Optional[builtins.str] = None,
            valid_until: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param iam_fleet_role: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.IamFleetRole``.
            :param target_capacity: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.TargetCapacity``.
            :param allocation_strategy: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.AllocationStrategy``.
            :param excess_capacity_termination_policy: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.ExcessCapacityTerminationPolicy``.
            :param instance_interruption_behavior: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.InstanceInterruptionBehavior``.
            :param instance_pools_to_use_count: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.InstancePoolsToUseCount``.
            :param launch_specifications: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.LaunchSpecifications``.
            :param launch_template_configs: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.LaunchTemplateConfigs``.
            :param load_balancers_config: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.LoadBalancersConfig``.
            :param on_demand_allocation_strategy: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.OnDemandAllocationStrategy``.
            :param on_demand_max_total_price: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.OnDemandMaxTotalPrice``.
            :param on_demand_target_capacity: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.OnDemandTargetCapacity``.
            :param replace_unhealthy_instances: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.ReplaceUnhealthyInstances``.
            :param spot_maintenance_strategies: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.SpotMaintenanceStrategies``.
            :param spot_max_total_price: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.SpotMaxTotalPrice``.
            :param spot_price: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.SpotPrice``.
            :param terminate_instances_with_expiration: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.TerminateInstancesWithExpiration``.
            :param type: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.Type``.
            :param valid_from: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.ValidFrom``.
            :param valid_until: ``CfnSpotFleet.SpotFleetRequestConfigDataProperty.ValidUntil``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "iam_fleet_role": iam_fleet_role,
                "target_capacity": target_capacity,
            }
            if allocation_strategy is not None:
                self._values["allocation_strategy"] = allocation_strategy
            if excess_capacity_termination_policy is not None:
                self._values["excess_capacity_termination_policy"] = excess_capacity_termination_policy
            if instance_interruption_behavior is not None:
                self._values["instance_interruption_behavior"] = instance_interruption_behavior
            if instance_pools_to_use_count is not None:
                self._values["instance_pools_to_use_count"] = instance_pools_to_use_count
            if launch_specifications is not None:
                self._values["launch_specifications"] = launch_specifications
            if launch_template_configs is not None:
                self._values["launch_template_configs"] = launch_template_configs
            if load_balancers_config is not None:
                self._values["load_balancers_config"] = load_balancers_config
            if on_demand_allocation_strategy is not None:
                self._values["on_demand_allocation_strategy"] = on_demand_allocation_strategy
            if on_demand_max_total_price is not None:
                self._values["on_demand_max_total_price"] = on_demand_max_total_price
            if on_demand_target_capacity is not None:
                self._values["on_demand_target_capacity"] = on_demand_target_capacity
            if replace_unhealthy_instances is not None:
                self._values["replace_unhealthy_instances"] = replace_unhealthy_instances
            if spot_maintenance_strategies is not None:
                self._values["spot_maintenance_strategies"] = spot_maintenance_strategies
            if spot_max_total_price is not None:
                self._values["spot_max_total_price"] = spot_max_total_price
            if spot_price is not None:
                self._values["spot_price"] = spot_price
            if terminate_instances_with_expiration is not None:
                self._values["terminate_instances_with_expiration"] = terminate_instances_with_expiration
            if type is not None:
                self._values["type"] = type
            if valid_from is not None:
                self._values["valid_from"] = valid_from
            if valid_until is not None:
                self._values["valid_until"] = valid_until

        @builtins.property
        def iam_fleet_role(self) -> builtins.str:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.IamFleetRole``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-iamfleetrole
            '''
            result = self._values.get("iam_fleet_role")
            assert result is not None, "Required property 'iam_fleet_role' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def target_capacity(self) -> jsii.Number:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.TargetCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-targetcapacity
            '''
            result = self._values.get("target_capacity")
            assert result is not None, "Required property 'target_capacity' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def allocation_strategy(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.AllocationStrategy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-allocationstrategy
            '''
            result = self._values.get("allocation_strategy")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def excess_capacity_termination_policy(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.ExcessCapacityTerminationPolicy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-excesscapacityterminationpolicy
            '''
            result = self._values.get("excess_capacity_termination_policy")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def instance_interruption_behavior(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.InstanceInterruptionBehavior``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-instanceinterruptionbehavior
            '''
            result = self._values.get("instance_interruption_behavior")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def instance_pools_to_use_count(self) -> typing.Optional[jsii.Number]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.InstancePoolsToUseCount``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-instancepoolstousecount
            '''
            result = self._values.get("instance_pools_to_use_count")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def launch_specifications(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetLaunchSpecificationProperty"]]]]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.LaunchSpecifications``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications
            '''
            result = self._values.get("launch_specifications")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotFleetLaunchSpecificationProperty"]]]], result)

        @builtins.property
        def launch_template_configs(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.LaunchTemplateConfigProperty"]]]]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.LaunchTemplateConfigs``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-launchtemplateconfigs
            '''
            result = self._values.get("launch_template_configs")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.LaunchTemplateConfigProperty"]]]], result)

        @builtins.property
        def load_balancers_config(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.LoadBalancersConfigProperty"]]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.LoadBalancersConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-loadbalancersconfig
            '''
            result = self._values.get("load_balancers_config")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.LoadBalancersConfigProperty"]], result)

        @builtins.property
        def on_demand_allocation_strategy(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.OnDemandAllocationStrategy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-ondemandallocationstrategy
            '''
            result = self._values.get("on_demand_allocation_strategy")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def on_demand_max_total_price(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.OnDemandMaxTotalPrice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-ondemandmaxtotalprice
            '''
            result = self._values.get("on_demand_max_total_price")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def on_demand_target_capacity(self) -> typing.Optional[jsii.Number]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.OnDemandTargetCapacity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-ondemandtargetcapacity
            '''
            result = self._values.get("on_demand_target_capacity")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def replace_unhealthy_instances(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.ReplaceUnhealthyInstances``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-replaceunhealthyinstances
            '''
            result = self._values.get("replace_unhealthy_instances")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def spot_maintenance_strategies(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotMaintenanceStrategiesProperty"]]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.SpotMaintenanceStrategies``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-spotmaintenancestrategies
            '''
            result = self._values.get("spot_maintenance_strategies")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotMaintenanceStrategiesProperty"]], result)

        @builtins.property
        def spot_max_total_price(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.SpotMaxTotalPrice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-spotmaxtotalprice
            '''
            result = self._values.get("spot_max_total_price")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def spot_price(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.SpotPrice``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-spotprice
            '''
            result = self._values.get("spot_price")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def terminate_instances_with_expiration(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.TerminateInstancesWithExpiration``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-terminateinstanceswithexpiration
            '''
            result = self._values.get("terminate_instances_with_expiration")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def type(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.Type``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-type
            '''
            result = self._values.get("type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def valid_from(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.ValidFrom``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-validfrom
            '''
            result = self._values.get("valid_from")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def valid_until(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetRequestConfigDataProperty.ValidUntil``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-validuntil
            '''
            result = self._values.get("valid_until")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SpotFleetRequestConfigDataProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.SpotFleetTagSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={"resource_type": "resourceType", "tags": "tags"},
    )
    class SpotFleetTagSpecificationProperty:
        def __init__(
            self,
            *,
            resource_type: typing.Optional[builtins.str] = None,
            tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        ) -> None:
            '''
            :param resource_type: ``CfnSpotFleet.SpotFleetTagSpecificationProperty.ResourceType``.
            :param tags: ``CfnSpotFleet.SpotFleetTagSpecificationProperty.Tags``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-tagspecifications.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if resource_type is not None:
                self._values["resource_type"] = resource_type
            if tags is not None:
                self._values["tags"] = tags

        @builtins.property
        def resource_type(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotFleetTagSpecificationProperty.ResourceType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-tagspecifications.html#cfn-ec2-spotfleet-spotfleettagspecification-resourcetype
            '''
            result = self._values.get("resource_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
            '''``CfnSpotFleet.SpotFleetTagSpecificationProperty.Tags``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-tagspecifications.html#cfn-ec2-spotfleet-tags
            '''
            result = self._values.get("tags")
            return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SpotFleetTagSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.SpotMaintenanceStrategiesProperty",
        jsii_struct_bases=[],
        name_mapping={"capacity_rebalance": "capacityRebalance"},
    )
    class SpotMaintenanceStrategiesProperty:
        def __init__(
            self,
            *,
            capacity_rebalance: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotCapacityRebalanceProperty"]] = None,
        ) -> None:
            '''
            :param capacity_rebalance: ``CfnSpotFleet.SpotMaintenanceStrategiesProperty.CapacityRebalance``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotmaintenancestrategies.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if capacity_rebalance is not None:
                self._values["capacity_rebalance"] = capacity_rebalance

        @builtins.property
        def capacity_rebalance(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotCapacityRebalanceProperty"]]:
            '''``CfnSpotFleet.SpotMaintenanceStrategiesProperty.CapacityRebalance``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotmaintenancestrategies.html#cfn-ec2-spotfleet-spotmaintenancestrategies-capacityrebalance
            '''
            result = self._values.get("capacity_rebalance")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.SpotCapacityRebalanceProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SpotMaintenanceStrategiesProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.SpotPlacementProperty",
        jsii_struct_bases=[],
        name_mapping={
            "availability_zone": "availabilityZone",
            "group_name": "groupName",
            "tenancy": "tenancy",
        },
    )
    class SpotPlacementProperty:
        def __init__(
            self,
            *,
            availability_zone: typing.Optional[builtins.str] = None,
            group_name: typing.Optional[builtins.str] = None,
            tenancy: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param availability_zone: ``CfnSpotFleet.SpotPlacementProperty.AvailabilityZone``.
            :param group_name: ``CfnSpotFleet.SpotPlacementProperty.GroupName``.
            :param tenancy: ``CfnSpotFleet.SpotPlacementProperty.Tenancy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-placement.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if availability_zone is not None:
                self._values["availability_zone"] = availability_zone
            if group_name is not None:
                self._values["group_name"] = group_name
            if tenancy is not None:
                self._values["tenancy"] = tenancy

        @builtins.property
        def availability_zone(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotPlacementProperty.AvailabilityZone``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-placement.html#cfn-ec2-spotfleet-spotplacement-availabilityzone
            '''
            result = self._values.get("availability_zone")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def group_name(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotPlacementProperty.GroupName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-placement.html#cfn-ec2-spotfleet-spotplacement-groupname
            '''
            result = self._values.get("group_name")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def tenancy(self) -> typing.Optional[builtins.str]:
            '''``CfnSpotFleet.SpotPlacementProperty.Tenancy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata-launchspecifications-placement.html#cfn-ec2-spotfleet-spotplacement-tenancy
            '''
            result = self._values.get("tenancy")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "SpotPlacementProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.TargetGroupProperty",
        jsii_struct_bases=[],
        name_mapping={"arn": "arn"},
    )
    class TargetGroupProperty:
        def __init__(self, *, arn: builtins.str) -> None:
            '''
            :param arn: ``CfnSpotFleet.TargetGroupProperty.Arn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-targetgroup.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "arn": arn,
            }

        @builtins.property
        def arn(self) -> builtins.str:
            '''``CfnSpotFleet.TargetGroupProperty.Arn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-targetgroup.html#cfn-ec2-spotfleet-targetgroup-arn
            '''
            result = self._values.get("arn")
            assert result is not None, "Required property 'arn' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TargetGroupProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnSpotFleet.TargetGroupsConfigProperty",
        jsii_struct_bases=[],
        name_mapping={"target_groups": "targetGroups"},
    )
    class TargetGroupsConfigProperty:
        def __init__(
            self,
            *,
            target_groups: typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.TargetGroupProperty"]]],
        ) -> None:
            '''
            :param target_groups: ``CfnSpotFleet.TargetGroupsConfigProperty.TargetGroups``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-targetgroupsconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "target_groups": target_groups,
            }

        @builtins.property
        def target_groups(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.TargetGroupProperty"]]]:
            '''``CfnSpotFleet.TargetGroupsConfigProperty.TargetGroups``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-targetgroupsconfig.html#cfn-ec2-spotfleet-targetgroupsconfig-targetgroups
            '''
            result = self._values.get("target_groups")
            assert result is not None, "Required property 'target_groups' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnSpotFleet.TargetGroupProperty"]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TargetGroupsConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnSpotFleetProps",
    jsii_struct_bases=[],
    name_mapping={"spot_fleet_request_config_data": "spotFleetRequestConfigData"},
)
class CfnSpotFleetProps:
    def __init__(
        self,
        *,
        spot_fleet_request_config_data: typing.Union[aws_cdk.core.IResolvable, CfnSpotFleet.SpotFleetRequestConfigDataProperty],
    ) -> None:
        '''Properties for defining a ``AWS::EC2::SpotFleet``.

        :param spot_fleet_request_config_data: ``AWS::EC2::SpotFleet.SpotFleetRequestConfigData``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-spotfleet.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "spot_fleet_request_config_data": spot_fleet_request_config_data,
        }

    @builtins.property
    def spot_fleet_request_config_data(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnSpotFleet.SpotFleetRequestConfigDataProperty]:
        '''``AWS::EC2::SpotFleet.SpotFleetRequestConfigData``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-spotfleet.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata
        '''
        result = self._values.get("spot_fleet_request_config_data")
        assert result is not None, "Required property 'spot_fleet_request_config_data' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnSpotFleet.SpotFleetRequestConfigDataProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnSpotFleetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnSubnet(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnSubnet",
):
    '''A CloudFormation ``AWS::EC2::Subnet``.

    :cloudformationResource: AWS::EC2::Subnet
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        cidr_block: builtins.str,
        vpc_id: builtins.str,
        assign_ipv6_address_on_creation: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        availability_zone: typing.Optional[builtins.str] = None,
        ipv6_cidr_block: typing.Optional[builtins.str] = None,
        map_public_ip_on_launch: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        outpost_arn: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::Subnet``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param cidr_block: ``AWS::EC2::Subnet.CidrBlock``.
        :param vpc_id: ``AWS::EC2::Subnet.VpcId``.
        :param assign_ipv6_address_on_creation: ``AWS::EC2::Subnet.AssignIpv6AddressOnCreation``.
        :param availability_zone: ``AWS::EC2::Subnet.AvailabilityZone``.
        :param ipv6_cidr_block: ``AWS::EC2::Subnet.Ipv6CidrBlock``.
        :param map_public_ip_on_launch: ``AWS::EC2::Subnet.MapPublicIpOnLaunch``.
        :param outpost_arn: ``AWS::EC2::Subnet.OutpostArn``.
        :param tags: ``AWS::EC2::Subnet.Tags``.
        '''
        props = CfnSubnetProps(
            cidr_block=cidr_block,
            vpc_id=vpc_id,
            assign_ipv6_address_on_creation=assign_ipv6_address_on_creation,
            availability_zone=availability_zone,
            ipv6_cidr_block=ipv6_cidr_block,
            map_public_ip_on_launch=map_public_ip_on_launch,
            outpost_arn=outpost_arn,
            tags=tags,
        )

        jsii.create(CfnSubnet, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAvailabilityZone")
    def attr_availability_zone(self) -> builtins.str:
        '''
        :cloudformationAttribute: AvailabilityZone
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrAvailabilityZone"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrIpv6CidrBlocks")
    def attr_ipv6_cidr_blocks(self) -> typing.List[builtins.str]:
        '''
        :cloudformationAttribute: Ipv6CidrBlocks
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "attrIpv6CidrBlocks"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrNetworkAclAssociationId")
    def attr_network_acl_association_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: NetworkAclAssociationId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrNetworkAclAssociationId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrOutpostArn")
    def attr_outpost_arn(self) -> builtins.str:
        '''
        :cloudformationAttribute: OutpostArn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrOutpostArn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrVpcId")
    def attr_vpc_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: VpcId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrVpcId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::Subnet.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cidrBlock")
    def cidr_block(self) -> builtins.str:
        '''``AWS::EC2::Subnet.CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-cidrblock
        '''
        return typing.cast(builtins.str, jsii.get(self, "cidrBlock"))

    @cidr_block.setter
    def cidr_block(self, value: builtins.str) -> None:
        jsii.set(self, "cidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::Subnet.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-awsec2subnet-prop-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="assignIpv6AddressOnCreation")
    def assign_ipv6_address_on_creation(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Subnet.AssignIpv6AddressOnCreation``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-assignipv6addressoncreation
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "assignIpv6AddressOnCreation"))

    @assign_ipv6_address_on_creation.setter
    def assign_ipv6_address_on_creation(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "assignIpv6AddressOnCreation", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Subnet.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-availabilityzone
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "availabilityZone"))

    @availability_zone.setter
    def availability_zone(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "availabilityZone", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipv6CidrBlock")
    def ipv6_cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Subnet.Ipv6CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-ipv6cidrblock
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "ipv6CidrBlock"))

    @ipv6_cidr_block.setter
    def ipv6_cidr_block(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "ipv6CidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="mapPublicIpOnLaunch")
    def map_public_ip_on_launch(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Subnet.MapPublicIpOnLaunch``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-mappubliciponlaunch
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "mapPublicIpOnLaunch"))

    @map_public_ip_on_launch.setter
    def map_public_ip_on_launch(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "mapPublicIpOnLaunch", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="outpostArn")
    def outpost_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Subnet.OutpostArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-outpostarn
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "outpostArn"))

    @outpost_arn.setter
    def outpost_arn(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "outpostArn", value)


@jsii.implements(aws_cdk.core.IInspectable)
class CfnSubnetCidrBlock(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnSubnetCidrBlock",
):
    '''A CloudFormation ``AWS::EC2::SubnetCidrBlock``.

    :cloudformationResource: AWS::EC2::SubnetCidrBlock
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnetcidrblock.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        ipv6_cidr_block: builtins.str,
        subnet_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::SubnetCidrBlock``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param ipv6_cidr_block: ``AWS::EC2::SubnetCidrBlock.Ipv6CidrBlock``.
        :param subnet_id: ``AWS::EC2::SubnetCidrBlock.SubnetId``.
        '''
        props = CfnSubnetCidrBlockProps(
            ipv6_cidr_block=ipv6_cidr_block, subnet_id=subnet_id
        )

        jsii.create(CfnSubnetCidrBlock, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipv6CidrBlock")
    def ipv6_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::SubnetCidrBlock.Ipv6CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnetcidrblock.html#cfn-ec2-subnetcidrblock-ipv6cidrblock
        '''
        return typing.cast(builtins.str, jsii.get(self, "ipv6CidrBlock"))

    @ipv6_cidr_block.setter
    def ipv6_cidr_block(self, value: builtins.str) -> None:
        jsii.set(self, "ipv6CidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetId")
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::SubnetCidrBlock.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnetcidrblock.html#cfn-ec2-subnetcidrblock-subnetid
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetId"))

    @subnet_id.setter
    def subnet_id(self, value: builtins.str) -> None:
        jsii.set(self, "subnetId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnSubnetCidrBlockProps",
    jsii_struct_bases=[],
    name_mapping={"ipv6_cidr_block": "ipv6CidrBlock", "subnet_id": "subnetId"},
)
class CfnSubnetCidrBlockProps:
    def __init__(
        self,
        *,
        ipv6_cidr_block: builtins.str,
        subnet_id: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::SubnetCidrBlock``.

        :param ipv6_cidr_block: ``AWS::EC2::SubnetCidrBlock.Ipv6CidrBlock``.
        :param subnet_id: ``AWS::EC2::SubnetCidrBlock.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnetcidrblock.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "ipv6_cidr_block": ipv6_cidr_block,
            "subnet_id": subnet_id,
        }

    @builtins.property
    def ipv6_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::SubnetCidrBlock.Ipv6CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnetcidrblock.html#cfn-ec2-subnetcidrblock-ipv6cidrblock
        '''
        result = self._values.get("ipv6_cidr_block")
        assert result is not None, "Required property 'ipv6_cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::SubnetCidrBlock.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnetcidrblock.html#cfn-ec2-subnetcidrblock-subnetid
        '''
        result = self._values.get("subnet_id")
        assert result is not None, "Required property 'subnet_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnSubnetCidrBlockProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnSubnetNetworkAclAssociation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnSubnetNetworkAclAssociation",
):
    '''A CloudFormation ``AWS::EC2::SubnetNetworkAclAssociation``.

    :cloudformationResource: AWS::EC2::SubnetNetworkAclAssociation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-network-acl-assoc.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        network_acl_id: builtins.str,
        subnet_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::SubnetNetworkAclAssociation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param network_acl_id: ``AWS::EC2::SubnetNetworkAclAssociation.NetworkAclId``.
        :param subnet_id: ``AWS::EC2::SubnetNetworkAclAssociation.SubnetId``.
        '''
        props = CfnSubnetNetworkAclAssociationProps(
            network_acl_id=network_acl_id, subnet_id=subnet_id
        )

        jsii.create(CfnSubnetNetworkAclAssociation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrAssociationId")
    def attr_association_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: AssociationId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrAssociationId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkAclId")
    def network_acl_id(self) -> builtins.str:
        '''``AWS::EC2::SubnetNetworkAclAssociation.NetworkAclId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-network-acl-assoc.html#cfn-ec2-subnetnetworkaclassociation-networkaclid
        '''
        return typing.cast(builtins.str, jsii.get(self, "networkAclId"))

    @network_acl_id.setter
    def network_acl_id(self, value: builtins.str) -> None:
        jsii.set(self, "networkAclId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetId")
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::SubnetNetworkAclAssociation.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-network-acl-assoc.html#cfn-ec2-subnetnetworkaclassociation-associationid
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetId"))

    @subnet_id.setter
    def subnet_id(self, value: builtins.str) -> None:
        jsii.set(self, "subnetId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnSubnetNetworkAclAssociationProps",
    jsii_struct_bases=[],
    name_mapping={"network_acl_id": "networkAclId", "subnet_id": "subnetId"},
)
class CfnSubnetNetworkAclAssociationProps:
    def __init__(
        self,
        *,
        network_acl_id: builtins.str,
        subnet_id: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::SubnetNetworkAclAssociation``.

        :param network_acl_id: ``AWS::EC2::SubnetNetworkAclAssociation.NetworkAclId``.
        :param subnet_id: ``AWS::EC2::SubnetNetworkAclAssociation.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-network-acl-assoc.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "network_acl_id": network_acl_id,
            "subnet_id": subnet_id,
        }

    @builtins.property
    def network_acl_id(self) -> builtins.str:
        '''``AWS::EC2::SubnetNetworkAclAssociation.NetworkAclId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-network-acl-assoc.html#cfn-ec2-subnetnetworkaclassociation-networkaclid
        '''
        result = self._values.get("network_acl_id")
        assert result is not None, "Required property 'network_acl_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::SubnetNetworkAclAssociation.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-network-acl-assoc.html#cfn-ec2-subnetnetworkaclassociation-associationid
        '''
        result = self._values.get("subnet_id")
        assert result is not None, "Required property 'subnet_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnSubnetNetworkAclAssociationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnSubnetProps",
    jsii_struct_bases=[],
    name_mapping={
        "cidr_block": "cidrBlock",
        "vpc_id": "vpcId",
        "assign_ipv6_address_on_creation": "assignIpv6AddressOnCreation",
        "availability_zone": "availabilityZone",
        "ipv6_cidr_block": "ipv6CidrBlock",
        "map_public_ip_on_launch": "mapPublicIpOnLaunch",
        "outpost_arn": "outpostArn",
        "tags": "tags",
    },
)
class CfnSubnetProps:
    def __init__(
        self,
        *,
        cidr_block: builtins.str,
        vpc_id: builtins.str,
        assign_ipv6_address_on_creation: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        availability_zone: typing.Optional[builtins.str] = None,
        ipv6_cidr_block: typing.Optional[builtins.str] = None,
        map_public_ip_on_launch: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        outpost_arn: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::Subnet``.

        :param cidr_block: ``AWS::EC2::Subnet.CidrBlock``.
        :param vpc_id: ``AWS::EC2::Subnet.VpcId``.
        :param assign_ipv6_address_on_creation: ``AWS::EC2::Subnet.AssignIpv6AddressOnCreation``.
        :param availability_zone: ``AWS::EC2::Subnet.AvailabilityZone``.
        :param ipv6_cidr_block: ``AWS::EC2::Subnet.Ipv6CidrBlock``.
        :param map_public_ip_on_launch: ``AWS::EC2::Subnet.MapPublicIpOnLaunch``.
        :param outpost_arn: ``AWS::EC2::Subnet.OutpostArn``.
        :param tags: ``AWS::EC2::Subnet.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cidr_block": cidr_block,
            "vpc_id": vpc_id,
        }
        if assign_ipv6_address_on_creation is not None:
            self._values["assign_ipv6_address_on_creation"] = assign_ipv6_address_on_creation
        if availability_zone is not None:
            self._values["availability_zone"] = availability_zone
        if ipv6_cidr_block is not None:
            self._values["ipv6_cidr_block"] = ipv6_cidr_block
        if map_public_ip_on_launch is not None:
            self._values["map_public_ip_on_launch"] = map_public_ip_on_launch
        if outpost_arn is not None:
            self._values["outpost_arn"] = outpost_arn
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def cidr_block(self) -> builtins.str:
        '''``AWS::EC2::Subnet.CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-cidrblock
        '''
        result = self._values.get("cidr_block")
        assert result is not None, "Required property 'cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::Subnet.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-awsec2subnet-prop-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def assign_ipv6_address_on_creation(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Subnet.AssignIpv6AddressOnCreation``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-assignipv6addressoncreation
        '''
        result = self._values.get("assign_ipv6_address_on_creation")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def availability_zone(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Subnet.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-availabilityzone
        '''
        result = self._values.get("availability_zone")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ipv6_cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Subnet.Ipv6CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-ipv6cidrblock
        '''
        result = self._values.get("ipv6_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def map_public_ip_on_launch(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Subnet.MapPublicIpOnLaunch``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-mappubliciponlaunch
        '''
        result = self._values.get("map_public_ip_on_launch")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def outpost_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Subnet.OutpostArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-outpostarn
        '''
        result = self._values.get("outpost_arn")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::Subnet.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html#cfn-ec2-subnet-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnSubnetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnSubnetRouteTableAssociation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociation",
):
    '''A CloudFormation ``AWS::EC2::SubnetRouteTableAssociation``.

    :cloudformationResource: AWS::EC2::SubnetRouteTableAssociation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        route_table_id: builtins.str,
        subnet_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::SubnetRouteTableAssociation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param route_table_id: ``AWS::EC2::SubnetRouteTableAssociation.RouteTableId``.
        :param subnet_id: ``AWS::EC2::SubnetRouteTableAssociation.SubnetId``.
        '''
        props = CfnSubnetRouteTableAssociationProps(
            route_table_id=route_table_id, subnet_id=subnet_id
        )

        jsii.create(CfnSubnetRouteTableAssociation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="routeTableId")
    def route_table_id(self) -> builtins.str:
        '''``AWS::EC2::SubnetRouteTableAssociation.RouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html#cfn-ec2-subnetroutetableassociation-routetableid
        '''
        return typing.cast(builtins.str, jsii.get(self, "routeTableId"))

    @route_table_id.setter
    def route_table_id(self, value: builtins.str) -> None:
        jsii.set(self, "routeTableId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetId")
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::SubnetRouteTableAssociation.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html#cfn-ec2-subnetroutetableassociation-subnetid
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetId"))

    @subnet_id.setter
    def subnet_id(self, value: builtins.str) -> None:
        jsii.set(self, "subnetId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnSubnetRouteTableAssociationProps",
    jsii_struct_bases=[],
    name_mapping={"route_table_id": "routeTableId", "subnet_id": "subnetId"},
)
class CfnSubnetRouteTableAssociationProps:
    def __init__(
        self,
        *,
        route_table_id: builtins.str,
        subnet_id: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::SubnetRouteTableAssociation``.

        :param route_table_id: ``AWS::EC2::SubnetRouteTableAssociation.RouteTableId``.
        :param subnet_id: ``AWS::EC2::SubnetRouteTableAssociation.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "route_table_id": route_table_id,
            "subnet_id": subnet_id,
        }

    @builtins.property
    def route_table_id(self) -> builtins.str:
        '''``AWS::EC2::SubnetRouteTableAssociation.RouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html#cfn-ec2-subnetroutetableassociation-routetableid
        '''
        result = self._values.get("route_table_id")
        assert result is not None, "Required property 'route_table_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def subnet_id(self) -> builtins.str:
        '''``AWS::EC2::SubnetRouteTableAssociation.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html#cfn-ec2-subnetroutetableassociation-subnetid
        '''
        result = self._values.get("subnet_id")
        assert result is not None, "Required property 'subnet_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnSubnetRouteTableAssociationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTrafficMirrorFilter(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTrafficMirrorFilter",
):
    '''A CloudFormation ``AWS::EC2::TrafficMirrorFilter``.

    :cloudformationResource: AWS::EC2::TrafficMirrorFilter
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilter.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        description: typing.Optional[builtins.str] = None,
        network_services: typing.Optional[typing.List[builtins.str]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TrafficMirrorFilter``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param description: ``AWS::EC2::TrafficMirrorFilter.Description``.
        :param network_services: ``AWS::EC2::TrafficMirrorFilter.NetworkServices``.
        :param tags: ``AWS::EC2::TrafficMirrorFilter.Tags``.
        '''
        props = CfnTrafficMirrorFilterProps(
            description=description, network_services=network_services, tags=tags
        )

        jsii.create(CfnTrafficMirrorFilter, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::TrafficMirrorFilter.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilter.html#cfn-ec2-trafficmirrorfilter-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorFilter.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilter.html#cfn-ec2-trafficmirrorfilter-description
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "description"))

    @description.setter
    def description(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkServices")
    def network_services(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::TrafficMirrorFilter.NetworkServices``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilter.html#cfn-ec2-trafficmirrorfilter-networkservices
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "networkServices"))

    @network_services.setter
    def network_services(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "networkServices", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTrafficMirrorFilterProps",
    jsii_struct_bases=[],
    name_mapping={
        "description": "description",
        "network_services": "networkServices",
        "tags": "tags",
    },
)
class CfnTrafficMirrorFilterProps:
    def __init__(
        self,
        *,
        description: typing.Optional[builtins.str] = None,
        network_services: typing.Optional[typing.List[builtins.str]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TrafficMirrorFilter``.

        :param description: ``AWS::EC2::TrafficMirrorFilter.Description``.
        :param network_services: ``AWS::EC2::TrafficMirrorFilter.NetworkServices``.
        :param tags: ``AWS::EC2::TrafficMirrorFilter.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilter.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if description is not None:
            self._values["description"] = description
        if network_services is not None:
            self._values["network_services"] = network_services
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorFilter.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilter.html#cfn-ec2-trafficmirrorfilter-description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def network_services(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::TrafficMirrorFilter.NetworkServices``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilter.html#cfn-ec2-trafficmirrorfilter-networkservices
        '''
        result = self._values.get("network_services")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::TrafficMirrorFilter.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilter.html#cfn-ec2-trafficmirrorfilter-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTrafficMirrorFilterProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTrafficMirrorFilterRule(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTrafficMirrorFilterRule",
):
    '''A CloudFormation ``AWS::EC2::TrafficMirrorFilterRule``.

    :cloudformationResource: AWS::EC2::TrafficMirrorFilterRule
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        destination_cidr_block: builtins.str,
        rule_action: builtins.str,
        rule_number: jsii.Number,
        source_cidr_block: builtins.str,
        traffic_direction: builtins.str,
        traffic_mirror_filter_id: builtins.str,
        description: typing.Optional[builtins.str] = None,
        destination_port_range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty"]] = None,
        protocol: typing.Optional[jsii.Number] = None,
        source_port_range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty"]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TrafficMirrorFilterRule``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param destination_cidr_block: ``AWS::EC2::TrafficMirrorFilterRule.DestinationCidrBlock``.
        :param rule_action: ``AWS::EC2::TrafficMirrorFilterRule.RuleAction``.
        :param rule_number: ``AWS::EC2::TrafficMirrorFilterRule.RuleNumber``.
        :param source_cidr_block: ``AWS::EC2::TrafficMirrorFilterRule.SourceCidrBlock``.
        :param traffic_direction: ``AWS::EC2::TrafficMirrorFilterRule.TrafficDirection``.
        :param traffic_mirror_filter_id: ``AWS::EC2::TrafficMirrorFilterRule.TrafficMirrorFilterId``.
        :param description: ``AWS::EC2::TrafficMirrorFilterRule.Description``.
        :param destination_port_range: ``AWS::EC2::TrafficMirrorFilterRule.DestinationPortRange``.
        :param protocol: ``AWS::EC2::TrafficMirrorFilterRule.Protocol``.
        :param source_port_range: ``AWS::EC2::TrafficMirrorFilterRule.SourcePortRange``.
        '''
        props = CfnTrafficMirrorFilterRuleProps(
            destination_cidr_block=destination_cidr_block,
            rule_action=rule_action,
            rule_number=rule_number,
            source_cidr_block=source_cidr_block,
            traffic_direction=traffic_direction,
            traffic_mirror_filter_id=traffic_mirror_filter_id,
            description=description,
            destination_port_range=destination_port_range,
            protocol=protocol,
            source_port_range=source_port_range,
        )

        jsii.create(CfnTrafficMirrorFilterRule, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationCidrBlock")
    def destination_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorFilterRule.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-destinationcidrblock
        '''
        return typing.cast(builtins.str, jsii.get(self, "destinationCidrBlock"))

    @destination_cidr_block.setter
    def destination_cidr_block(self, value: builtins.str) -> None:
        jsii.set(self, "destinationCidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ruleAction")
    def rule_action(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorFilterRule.RuleAction``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-ruleaction
        '''
        return typing.cast(builtins.str, jsii.get(self, "ruleAction"))

    @rule_action.setter
    def rule_action(self, value: builtins.str) -> None:
        jsii.set(self, "ruleAction", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ruleNumber")
    def rule_number(self) -> jsii.Number:
        '''``AWS::EC2::TrafficMirrorFilterRule.RuleNumber``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-rulenumber
        '''
        return typing.cast(jsii.Number, jsii.get(self, "ruleNumber"))

    @rule_number.setter
    def rule_number(self, value: jsii.Number) -> None:
        jsii.set(self, "ruleNumber", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sourceCidrBlock")
    def source_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorFilterRule.SourceCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-sourcecidrblock
        '''
        return typing.cast(builtins.str, jsii.get(self, "sourceCidrBlock"))

    @source_cidr_block.setter
    def source_cidr_block(self, value: builtins.str) -> None:
        jsii.set(self, "sourceCidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="trafficDirection")
    def traffic_direction(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorFilterRule.TrafficDirection``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-trafficdirection
        '''
        return typing.cast(builtins.str, jsii.get(self, "trafficDirection"))

    @traffic_direction.setter
    def traffic_direction(self, value: builtins.str) -> None:
        jsii.set(self, "trafficDirection", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="trafficMirrorFilterId")
    def traffic_mirror_filter_id(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorFilterRule.TrafficMirrorFilterId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-trafficmirrorfilterid
        '''
        return typing.cast(builtins.str, jsii.get(self, "trafficMirrorFilterId"))

    @traffic_mirror_filter_id.setter
    def traffic_mirror_filter_id(self, value: builtins.str) -> None:
        jsii.set(self, "trafficMirrorFilterId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorFilterRule.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-description
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "description"))

    @description.setter
    def description(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationPortRange")
    def destination_port_range(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty"]]:
        '''``AWS::EC2::TrafficMirrorFilterRule.DestinationPortRange``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-destinationportrange
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty"]], jsii.get(self, "destinationPortRange"))

    @destination_port_range.setter
    def destination_port_range(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty"]],
    ) -> None:
        jsii.set(self, "destinationPortRange", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="protocol")
    def protocol(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::TrafficMirrorFilterRule.Protocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-protocol
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "protocol"))

    @protocol.setter
    def protocol(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "protocol", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sourcePortRange")
    def source_port_range(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty"]]:
        '''``AWS::EC2::TrafficMirrorFilterRule.SourcePortRange``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-sourceportrange
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty"]], jsii.get(self, "sourcePortRange"))

    @source_port_range.setter
    def source_port_range(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty"]],
    ) -> None:
        jsii.set(self, "sourcePortRange", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty",
        jsii_struct_bases=[],
        name_mapping={"from_port": "fromPort", "to_port": "toPort"},
    )
    class TrafficMirrorPortRangeProperty:
        def __init__(self, *, from_port: jsii.Number, to_port: jsii.Number) -> None:
            '''
            :param from_port: ``CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty.FromPort``.
            :param to_port: ``CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty.ToPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-trafficmirrorfilterrule-trafficmirrorportrange.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "from_port": from_port,
                "to_port": to_port,
            }

        @builtins.property
        def from_port(self) -> jsii.Number:
            '''``CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty.FromPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-trafficmirrorfilterrule-trafficmirrorportrange.html#cfn-ec2-trafficmirrorfilterrule-trafficmirrorportrange-fromport
            '''
            result = self._values.get("from_port")
            assert result is not None, "Required property 'from_port' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def to_port(self) -> jsii.Number:
            '''``CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty.ToPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-trafficmirrorfilterrule-trafficmirrorportrange.html#cfn-ec2-trafficmirrorfilterrule-trafficmirrorportrange-toport
            '''
            result = self._values.get("to_port")
            assert result is not None, "Required property 'to_port' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TrafficMirrorPortRangeProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTrafficMirrorFilterRuleProps",
    jsii_struct_bases=[],
    name_mapping={
        "destination_cidr_block": "destinationCidrBlock",
        "rule_action": "ruleAction",
        "rule_number": "ruleNumber",
        "source_cidr_block": "sourceCidrBlock",
        "traffic_direction": "trafficDirection",
        "traffic_mirror_filter_id": "trafficMirrorFilterId",
        "description": "description",
        "destination_port_range": "destinationPortRange",
        "protocol": "protocol",
        "source_port_range": "sourcePortRange",
    },
)
class CfnTrafficMirrorFilterRuleProps:
    def __init__(
        self,
        *,
        destination_cidr_block: builtins.str,
        rule_action: builtins.str,
        rule_number: jsii.Number,
        source_cidr_block: builtins.str,
        traffic_direction: builtins.str,
        traffic_mirror_filter_id: builtins.str,
        description: typing.Optional[builtins.str] = None,
        destination_port_range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty]] = None,
        protocol: typing.Optional[jsii.Number] = None,
        source_port_range: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TrafficMirrorFilterRule``.

        :param destination_cidr_block: ``AWS::EC2::TrafficMirrorFilterRule.DestinationCidrBlock``.
        :param rule_action: ``AWS::EC2::TrafficMirrorFilterRule.RuleAction``.
        :param rule_number: ``AWS::EC2::TrafficMirrorFilterRule.RuleNumber``.
        :param source_cidr_block: ``AWS::EC2::TrafficMirrorFilterRule.SourceCidrBlock``.
        :param traffic_direction: ``AWS::EC2::TrafficMirrorFilterRule.TrafficDirection``.
        :param traffic_mirror_filter_id: ``AWS::EC2::TrafficMirrorFilterRule.TrafficMirrorFilterId``.
        :param description: ``AWS::EC2::TrafficMirrorFilterRule.Description``.
        :param destination_port_range: ``AWS::EC2::TrafficMirrorFilterRule.DestinationPortRange``.
        :param protocol: ``AWS::EC2::TrafficMirrorFilterRule.Protocol``.
        :param source_port_range: ``AWS::EC2::TrafficMirrorFilterRule.SourcePortRange``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "destination_cidr_block": destination_cidr_block,
            "rule_action": rule_action,
            "rule_number": rule_number,
            "source_cidr_block": source_cidr_block,
            "traffic_direction": traffic_direction,
            "traffic_mirror_filter_id": traffic_mirror_filter_id,
        }
        if description is not None:
            self._values["description"] = description
        if destination_port_range is not None:
            self._values["destination_port_range"] = destination_port_range
        if protocol is not None:
            self._values["protocol"] = protocol
        if source_port_range is not None:
            self._values["source_port_range"] = source_port_range

    @builtins.property
    def destination_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorFilterRule.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-destinationcidrblock
        '''
        result = self._values.get("destination_cidr_block")
        assert result is not None, "Required property 'destination_cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def rule_action(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorFilterRule.RuleAction``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-ruleaction
        '''
        result = self._values.get("rule_action")
        assert result is not None, "Required property 'rule_action' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def rule_number(self) -> jsii.Number:
        '''``AWS::EC2::TrafficMirrorFilterRule.RuleNumber``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-rulenumber
        '''
        result = self._values.get("rule_number")
        assert result is not None, "Required property 'rule_number' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def source_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorFilterRule.SourceCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-sourcecidrblock
        '''
        result = self._values.get("source_cidr_block")
        assert result is not None, "Required property 'source_cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def traffic_direction(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorFilterRule.TrafficDirection``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-trafficdirection
        '''
        result = self._values.get("traffic_direction")
        assert result is not None, "Required property 'traffic_direction' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def traffic_mirror_filter_id(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorFilterRule.TrafficMirrorFilterId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-trafficmirrorfilterid
        '''
        result = self._values.get("traffic_mirror_filter_id")
        assert result is not None, "Required property 'traffic_mirror_filter_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorFilterRule.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def destination_port_range(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty]]:
        '''``AWS::EC2::TrafficMirrorFilterRule.DestinationPortRange``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-destinationportrange
        '''
        result = self._values.get("destination_port_range")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty]], result)

    @builtins.property
    def protocol(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::TrafficMirrorFilterRule.Protocol``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-protocol
        '''
        result = self._values.get("protocol")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def source_port_range(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty]]:
        '''``AWS::EC2::TrafficMirrorFilterRule.SourcePortRange``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorfilterrule.html#cfn-ec2-trafficmirrorfilterrule-sourceportrange
        '''
        result = self._values.get("source_port_range")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnTrafficMirrorFilterRule.TrafficMirrorPortRangeProperty]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTrafficMirrorFilterRuleProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTrafficMirrorSession(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTrafficMirrorSession",
):
    '''A CloudFormation ``AWS::EC2::TrafficMirrorSession``.

    :cloudformationResource: AWS::EC2::TrafficMirrorSession
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        network_interface_id: builtins.str,
        session_number: jsii.Number,
        traffic_mirror_filter_id: builtins.str,
        traffic_mirror_target_id: builtins.str,
        description: typing.Optional[builtins.str] = None,
        packet_length: typing.Optional[jsii.Number] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        virtual_network_id: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TrafficMirrorSession``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param network_interface_id: ``AWS::EC2::TrafficMirrorSession.NetworkInterfaceId``.
        :param session_number: ``AWS::EC2::TrafficMirrorSession.SessionNumber``.
        :param traffic_mirror_filter_id: ``AWS::EC2::TrafficMirrorSession.TrafficMirrorFilterId``.
        :param traffic_mirror_target_id: ``AWS::EC2::TrafficMirrorSession.TrafficMirrorTargetId``.
        :param description: ``AWS::EC2::TrafficMirrorSession.Description``.
        :param packet_length: ``AWS::EC2::TrafficMirrorSession.PacketLength``.
        :param tags: ``AWS::EC2::TrafficMirrorSession.Tags``.
        :param virtual_network_id: ``AWS::EC2::TrafficMirrorSession.VirtualNetworkId``.
        '''
        props = CfnTrafficMirrorSessionProps(
            network_interface_id=network_interface_id,
            session_number=session_number,
            traffic_mirror_filter_id=traffic_mirror_filter_id,
            traffic_mirror_target_id=traffic_mirror_target_id,
            description=description,
            packet_length=packet_length,
            tags=tags,
            virtual_network_id=virtual_network_id,
        )

        jsii.create(CfnTrafficMirrorSession, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::TrafficMirrorSession.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkInterfaceId")
    def network_interface_id(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorSession.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-networkinterfaceid
        '''
        return typing.cast(builtins.str, jsii.get(self, "networkInterfaceId"))

    @network_interface_id.setter
    def network_interface_id(self, value: builtins.str) -> None:
        jsii.set(self, "networkInterfaceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="sessionNumber")
    def session_number(self) -> jsii.Number:
        '''``AWS::EC2::TrafficMirrorSession.SessionNumber``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-sessionnumber
        '''
        return typing.cast(jsii.Number, jsii.get(self, "sessionNumber"))

    @session_number.setter
    def session_number(self, value: jsii.Number) -> None:
        jsii.set(self, "sessionNumber", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="trafficMirrorFilterId")
    def traffic_mirror_filter_id(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorSession.TrafficMirrorFilterId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-trafficmirrorfilterid
        '''
        return typing.cast(builtins.str, jsii.get(self, "trafficMirrorFilterId"))

    @traffic_mirror_filter_id.setter
    def traffic_mirror_filter_id(self, value: builtins.str) -> None:
        jsii.set(self, "trafficMirrorFilterId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="trafficMirrorTargetId")
    def traffic_mirror_target_id(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorSession.TrafficMirrorTargetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-trafficmirrortargetid
        '''
        return typing.cast(builtins.str, jsii.get(self, "trafficMirrorTargetId"))

    @traffic_mirror_target_id.setter
    def traffic_mirror_target_id(self, value: builtins.str) -> None:
        jsii.set(self, "trafficMirrorTargetId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorSession.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-description
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "description"))

    @description.setter
    def description(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="packetLength")
    def packet_length(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::TrafficMirrorSession.PacketLength``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-packetlength
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "packetLength"))

    @packet_length.setter
    def packet_length(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "packetLength", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="virtualNetworkId")
    def virtual_network_id(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::TrafficMirrorSession.VirtualNetworkId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-virtualnetworkid
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "virtualNetworkId"))

    @virtual_network_id.setter
    def virtual_network_id(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "virtualNetworkId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTrafficMirrorSessionProps",
    jsii_struct_bases=[],
    name_mapping={
        "network_interface_id": "networkInterfaceId",
        "session_number": "sessionNumber",
        "traffic_mirror_filter_id": "trafficMirrorFilterId",
        "traffic_mirror_target_id": "trafficMirrorTargetId",
        "description": "description",
        "packet_length": "packetLength",
        "tags": "tags",
        "virtual_network_id": "virtualNetworkId",
    },
)
class CfnTrafficMirrorSessionProps:
    def __init__(
        self,
        *,
        network_interface_id: builtins.str,
        session_number: jsii.Number,
        traffic_mirror_filter_id: builtins.str,
        traffic_mirror_target_id: builtins.str,
        description: typing.Optional[builtins.str] = None,
        packet_length: typing.Optional[jsii.Number] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        virtual_network_id: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TrafficMirrorSession``.

        :param network_interface_id: ``AWS::EC2::TrafficMirrorSession.NetworkInterfaceId``.
        :param session_number: ``AWS::EC2::TrafficMirrorSession.SessionNumber``.
        :param traffic_mirror_filter_id: ``AWS::EC2::TrafficMirrorSession.TrafficMirrorFilterId``.
        :param traffic_mirror_target_id: ``AWS::EC2::TrafficMirrorSession.TrafficMirrorTargetId``.
        :param description: ``AWS::EC2::TrafficMirrorSession.Description``.
        :param packet_length: ``AWS::EC2::TrafficMirrorSession.PacketLength``.
        :param tags: ``AWS::EC2::TrafficMirrorSession.Tags``.
        :param virtual_network_id: ``AWS::EC2::TrafficMirrorSession.VirtualNetworkId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "network_interface_id": network_interface_id,
            "session_number": session_number,
            "traffic_mirror_filter_id": traffic_mirror_filter_id,
            "traffic_mirror_target_id": traffic_mirror_target_id,
        }
        if description is not None:
            self._values["description"] = description
        if packet_length is not None:
            self._values["packet_length"] = packet_length
        if tags is not None:
            self._values["tags"] = tags
        if virtual_network_id is not None:
            self._values["virtual_network_id"] = virtual_network_id

    @builtins.property
    def network_interface_id(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorSession.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-networkinterfaceid
        '''
        result = self._values.get("network_interface_id")
        assert result is not None, "Required property 'network_interface_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def session_number(self) -> jsii.Number:
        '''``AWS::EC2::TrafficMirrorSession.SessionNumber``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-sessionnumber
        '''
        result = self._values.get("session_number")
        assert result is not None, "Required property 'session_number' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def traffic_mirror_filter_id(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorSession.TrafficMirrorFilterId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-trafficmirrorfilterid
        '''
        result = self._values.get("traffic_mirror_filter_id")
        assert result is not None, "Required property 'traffic_mirror_filter_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def traffic_mirror_target_id(self) -> builtins.str:
        '''``AWS::EC2::TrafficMirrorSession.TrafficMirrorTargetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-trafficmirrortargetid
        '''
        result = self._values.get("traffic_mirror_target_id")
        assert result is not None, "Required property 'traffic_mirror_target_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorSession.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def packet_length(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::TrafficMirrorSession.PacketLength``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-packetlength
        '''
        result = self._values.get("packet_length")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::TrafficMirrorSession.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    @builtins.property
    def virtual_network_id(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::TrafficMirrorSession.VirtualNetworkId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrorsession.html#cfn-ec2-trafficmirrorsession-virtualnetworkid
        '''
        result = self._values.get("virtual_network_id")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTrafficMirrorSessionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTrafficMirrorTarget(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTrafficMirrorTarget",
):
    '''A CloudFormation ``AWS::EC2::TrafficMirrorTarget``.

    :cloudformationResource: AWS::EC2::TrafficMirrorTarget
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrortarget.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        description: typing.Optional[builtins.str] = None,
        network_interface_id: typing.Optional[builtins.str] = None,
        network_load_balancer_arn: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TrafficMirrorTarget``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param description: ``AWS::EC2::TrafficMirrorTarget.Description``.
        :param network_interface_id: ``AWS::EC2::TrafficMirrorTarget.NetworkInterfaceId``.
        :param network_load_balancer_arn: ``AWS::EC2::TrafficMirrorTarget.NetworkLoadBalancerArn``.
        :param tags: ``AWS::EC2::TrafficMirrorTarget.Tags``.
        '''
        props = CfnTrafficMirrorTargetProps(
            description=description,
            network_interface_id=network_interface_id,
            network_load_balancer_arn=network_load_balancer_arn,
            tags=tags,
        )

        jsii.create(CfnTrafficMirrorTarget, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::TrafficMirrorTarget.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrortarget.html#cfn-ec2-trafficmirrortarget-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorTarget.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrortarget.html#cfn-ec2-trafficmirrortarget-description
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "description"))

    @description.setter
    def description(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkInterfaceId")
    def network_interface_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorTarget.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrortarget.html#cfn-ec2-trafficmirrortarget-networkinterfaceid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "networkInterfaceId"))

    @network_interface_id.setter
    def network_interface_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "networkInterfaceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkLoadBalancerArn")
    def network_load_balancer_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorTarget.NetworkLoadBalancerArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrortarget.html#cfn-ec2-trafficmirrortarget-networkloadbalancerarn
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "networkLoadBalancerArn"))

    @network_load_balancer_arn.setter
    def network_load_balancer_arn(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "networkLoadBalancerArn", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTrafficMirrorTargetProps",
    jsii_struct_bases=[],
    name_mapping={
        "description": "description",
        "network_interface_id": "networkInterfaceId",
        "network_load_balancer_arn": "networkLoadBalancerArn",
        "tags": "tags",
    },
)
class CfnTrafficMirrorTargetProps:
    def __init__(
        self,
        *,
        description: typing.Optional[builtins.str] = None,
        network_interface_id: typing.Optional[builtins.str] = None,
        network_load_balancer_arn: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TrafficMirrorTarget``.

        :param description: ``AWS::EC2::TrafficMirrorTarget.Description``.
        :param network_interface_id: ``AWS::EC2::TrafficMirrorTarget.NetworkInterfaceId``.
        :param network_load_balancer_arn: ``AWS::EC2::TrafficMirrorTarget.NetworkLoadBalancerArn``.
        :param tags: ``AWS::EC2::TrafficMirrorTarget.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrortarget.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if description is not None:
            self._values["description"] = description
        if network_interface_id is not None:
            self._values["network_interface_id"] = network_interface_id
        if network_load_balancer_arn is not None:
            self._values["network_load_balancer_arn"] = network_load_balancer_arn
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorTarget.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrortarget.html#cfn-ec2-trafficmirrortarget-description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def network_interface_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorTarget.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrortarget.html#cfn-ec2-trafficmirrortarget-networkinterfaceid
        '''
        result = self._values.get("network_interface_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def network_load_balancer_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TrafficMirrorTarget.NetworkLoadBalancerArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrortarget.html#cfn-ec2-trafficmirrortarget-networkloadbalancerarn
        '''
        result = self._values.get("network_load_balancer_arn")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::TrafficMirrorTarget.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-trafficmirrortarget.html#cfn-ec2-trafficmirrortarget-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTrafficMirrorTargetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTransitGateway(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGateway",
):
    '''A CloudFormation ``AWS::EC2::TransitGateway``.

    :cloudformationResource: AWS::EC2::TransitGateway
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        amazon_side_asn: typing.Optional[jsii.Number] = None,
        auto_accept_shared_attachments: typing.Optional[builtins.str] = None,
        default_route_table_association: typing.Optional[builtins.str] = None,
        default_route_table_propagation: typing.Optional[builtins.str] = None,
        description: typing.Optional[builtins.str] = None,
        dns_support: typing.Optional[builtins.str] = None,
        multicast_support: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        vpn_ecmp_support: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TransitGateway``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param amazon_side_asn: ``AWS::EC2::TransitGateway.AmazonSideAsn``.
        :param auto_accept_shared_attachments: ``AWS::EC2::TransitGateway.AutoAcceptSharedAttachments``.
        :param default_route_table_association: ``AWS::EC2::TransitGateway.DefaultRouteTableAssociation``.
        :param default_route_table_propagation: ``AWS::EC2::TransitGateway.DefaultRouteTablePropagation``.
        :param description: ``AWS::EC2::TransitGateway.Description``.
        :param dns_support: ``AWS::EC2::TransitGateway.DnsSupport``.
        :param multicast_support: ``AWS::EC2::TransitGateway.MulticastSupport``.
        :param tags: ``AWS::EC2::TransitGateway.Tags``.
        :param vpn_ecmp_support: ``AWS::EC2::TransitGateway.VpnEcmpSupport``.
        '''
        props = CfnTransitGatewayProps(
            amazon_side_asn=amazon_side_asn,
            auto_accept_shared_attachments=auto_accept_shared_attachments,
            default_route_table_association=default_route_table_association,
            default_route_table_propagation=default_route_table_propagation,
            description=description,
            dns_support=dns_support,
            multicast_support=multicast_support,
            tags=tags,
            vpn_ecmp_support=vpn_ecmp_support,
        )

        jsii.create(CfnTransitGateway, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::TransitGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="amazonSideAsn")
    def amazon_side_asn(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::TransitGateway.AmazonSideAsn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-amazonsideasn
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "amazonSideAsn"))

    @amazon_side_asn.setter
    def amazon_side_asn(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "amazonSideAsn", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="autoAcceptSharedAttachments")
    def auto_accept_shared_attachments(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.AutoAcceptSharedAttachments``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-autoacceptsharedattachments
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "autoAcceptSharedAttachments"))

    @auto_accept_shared_attachments.setter
    def auto_accept_shared_attachments(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "autoAcceptSharedAttachments", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="defaultRouteTableAssociation")
    def default_route_table_association(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.DefaultRouteTableAssociation``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-defaultroutetableassociation
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "defaultRouteTableAssociation"))

    @default_route_table_association.setter
    def default_route_table_association(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "defaultRouteTableAssociation", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="defaultRouteTablePropagation")
    def default_route_table_propagation(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.DefaultRouteTablePropagation``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-defaultroutetablepropagation
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "defaultRouteTablePropagation"))

    @default_route_table_propagation.setter
    def default_route_table_propagation(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "defaultRouteTablePropagation", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="description")
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-description
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "description"))

    @description.setter
    def description(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "description", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="dnsSupport")
    def dns_support(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.DnsSupport``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-dnssupport
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "dnsSupport"))

    @dns_support.setter
    def dns_support(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "dnsSupport", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="multicastSupport")
    def multicast_support(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.MulticastSupport``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-multicastsupport
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "multicastSupport"))

    @multicast_support.setter
    def multicast_support(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "multicastSupport", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnEcmpSupport")
    def vpn_ecmp_support(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.VpnEcmpSupport``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-vpnecmpsupport
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "vpnEcmpSupport"))

    @vpn_ecmp_support.setter
    def vpn_ecmp_support(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "vpnEcmpSupport", value)


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTransitGatewayAttachment(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayAttachment",
):
    '''A CloudFormation ``AWS::EC2::TransitGatewayAttachment``.

    :cloudformationResource: AWS::EC2::TransitGatewayAttachment
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayattachment.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        subnet_ids: typing.List[builtins.str],
        transit_gateway_id: builtins.str,
        vpc_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TransitGatewayAttachment``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param subnet_ids: ``AWS::EC2::TransitGatewayAttachment.SubnetIds``.
        :param transit_gateway_id: ``AWS::EC2::TransitGatewayAttachment.TransitGatewayId``.
        :param vpc_id: ``AWS::EC2::TransitGatewayAttachment.VpcId``.
        :param tags: ``AWS::EC2::TransitGatewayAttachment.Tags``.
        '''
        props = CfnTransitGatewayAttachmentProps(
            subnet_ids=subnet_ids,
            transit_gateway_id=transit_gateway_id,
            vpc_id=vpc_id,
            tags=tags,
        )

        jsii.create(CfnTransitGatewayAttachment, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::TransitGatewayAttachment.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayattachment.html#cfn-ec2-transitgatewayattachment-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetIds")
    def subnet_ids(self) -> typing.List[builtins.str]:
        '''``AWS::EC2::TransitGatewayAttachment.SubnetIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayattachment.html#cfn-ec2-transitgatewayattachment-subnetids
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "subnetIds"))

    @subnet_ids.setter
    def subnet_ids(self, value: typing.List[builtins.str]) -> None:
        jsii.set(self, "subnetIds", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayId")
    def transit_gateway_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayAttachment.TransitGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayattachment.html#cfn-ec2-transitgatewayattachment-transitgatewayid
        '''
        return typing.cast(builtins.str, jsii.get(self, "transitGatewayId"))

    @transit_gateway_id.setter
    def transit_gateway_id(self, value: builtins.str) -> None:
        jsii.set(self, "transitGatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayAttachment.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayattachment.html#cfn-ec2-transitgatewayattachment-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayAttachmentProps",
    jsii_struct_bases=[],
    name_mapping={
        "subnet_ids": "subnetIds",
        "transit_gateway_id": "transitGatewayId",
        "vpc_id": "vpcId",
        "tags": "tags",
    },
)
class CfnTransitGatewayAttachmentProps:
    def __init__(
        self,
        *,
        subnet_ids: typing.List[builtins.str],
        transit_gateway_id: builtins.str,
        vpc_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TransitGatewayAttachment``.

        :param subnet_ids: ``AWS::EC2::TransitGatewayAttachment.SubnetIds``.
        :param transit_gateway_id: ``AWS::EC2::TransitGatewayAttachment.TransitGatewayId``.
        :param vpc_id: ``AWS::EC2::TransitGatewayAttachment.VpcId``.
        :param tags: ``AWS::EC2::TransitGatewayAttachment.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayattachment.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "subnet_ids": subnet_ids,
            "transit_gateway_id": transit_gateway_id,
            "vpc_id": vpc_id,
        }
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def subnet_ids(self) -> typing.List[builtins.str]:
        '''``AWS::EC2::TransitGatewayAttachment.SubnetIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayattachment.html#cfn-ec2-transitgatewayattachment-subnetids
        '''
        result = self._values.get("subnet_ids")
        assert result is not None, "Required property 'subnet_ids' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def transit_gateway_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayAttachment.TransitGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayattachment.html#cfn-ec2-transitgatewayattachment-transitgatewayid
        '''
        result = self._values.get("transit_gateway_id")
        assert result is not None, "Required property 'transit_gateway_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayAttachment.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayattachment.html#cfn-ec2-transitgatewayattachment-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::TransitGatewayAttachment.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayattachment.html#cfn-ec2-transitgatewayattachment-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTransitGatewayAttachmentProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTransitGatewayMulticastDomain(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayMulticastDomain",
):
    '''A CloudFormation ``AWS::EC2::TransitGatewayMulticastDomain``.

    :cloudformationResource: AWS::EC2::TransitGatewayMulticastDomain
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomain.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        options: typing.Any = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        transit_gateway_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TransitGatewayMulticastDomain``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param options: ``AWS::EC2::TransitGatewayMulticastDomain.Options``.
        :param tags: ``AWS::EC2::TransitGatewayMulticastDomain.Tags``.
        :param transit_gateway_id: ``AWS::EC2::TransitGatewayMulticastDomain.TransitGatewayId``.
        '''
        props = CfnTransitGatewayMulticastDomainProps(
            options=options, tags=tags, transit_gateway_id=transit_gateway_id
        )

        jsii.create(CfnTransitGatewayMulticastDomain, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrCreationTime")
    def attr_creation_time(self) -> builtins.str:
        '''
        :cloudformationAttribute: CreationTime
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrCreationTime"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrState")
    def attr_state(self) -> builtins.str:
        '''
        :cloudformationAttribute: State
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrState"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrTransitGatewayMulticastDomainArn")
    def attr_transit_gateway_multicast_domain_arn(self) -> builtins.str:
        '''
        :cloudformationAttribute: TransitGatewayMulticastDomainArn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrTransitGatewayMulticastDomainArn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrTransitGatewayMulticastDomainId")
    def attr_transit_gateway_multicast_domain_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: TransitGatewayMulticastDomainId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrTransitGatewayMulticastDomainId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::TransitGatewayMulticastDomain.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomain.html#cfn-ec2-transitgatewaymulticastdomain-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="options")
    def options(self) -> typing.Any:
        '''``AWS::EC2::TransitGatewayMulticastDomain.Options``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomain.html#cfn-ec2-transitgatewaymulticastdomain-options
        '''
        return typing.cast(typing.Any, jsii.get(self, "options"))

    @options.setter
    def options(self, value: typing.Any) -> None:
        jsii.set(self, "options", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayId")
    def transit_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastDomain.TransitGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomain.html#cfn-ec2-transitgatewaymulticastdomain-transitgatewayid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "transitGatewayId"))

    @transit_gateway_id.setter
    def transit_gateway_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "transitGatewayId", value)


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTransitGatewayMulticastDomainAssociation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayMulticastDomainAssociation",
):
    '''A CloudFormation ``AWS::EC2::TransitGatewayMulticastDomainAssociation``.

    :cloudformationResource: AWS::EC2::TransitGatewayMulticastDomainAssociation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomainassociation.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        state: typing.Optional[builtins.str] = None,
        subnet_id: typing.Optional[builtins.str] = None,
        transit_gateway_attachment_id: typing.Optional[builtins.str] = None,
        transit_gateway_multicast_domain_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TransitGatewayMulticastDomainAssociation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param state: ``AWS::EC2::TransitGatewayMulticastDomainAssociation.State``.
        :param subnet_id: ``AWS::EC2::TransitGatewayMulticastDomainAssociation.SubnetId``.
        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayMulticastDomainAssociation.TransitGatewayAttachmentId``.
        :param transit_gateway_multicast_domain_id: ``AWS::EC2::TransitGatewayMulticastDomainAssociation.TransitGatewayMulticastDomainId``.
        '''
        props = CfnTransitGatewayMulticastDomainAssociationProps(
            state=state,
            subnet_id=subnet_id,
            transit_gateway_attachment_id=transit_gateway_attachment_id,
            transit_gateway_multicast_domain_id=transit_gateway_multicast_domain_id,
        )

        jsii.create(CfnTransitGatewayMulticastDomainAssociation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrResourceId")
    def attr_resource_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: ResourceId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrResourceType")
    def attr_resource_type(self) -> builtins.str:
        '''
        :cloudformationAttribute: ResourceType
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceType"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="state")
    def state(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastDomainAssociation.State``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomainassociation.html#cfn-ec2-transitgatewaymulticastdomainassociation-state
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "state"))

    @state.setter
    def state(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "state", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetId")
    def subnet_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastDomainAssociation.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomainassociation.html#cfn-ec2-transitgatewaymulticastdomainassociation-subnetid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "subnetId"))

    @subnet_id.setter
    def subnet_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "subnetId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayAttachmentId")
    def transit_gateway_attachment_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastDomainAssociation.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomainassociation.html#cfn-ec2-transitgatewaymulticastdomainassociation-transitgatewayattachmentid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "transitGatewayAttachmentId"))

    @transit_gateway_attachment_id.setter
    def transit_gateway_attachment_id(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "transitGatewayAttachmentId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayMulticastDomainId")
    def transit_gateway_multicast_domain_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastDomainAssociation.TransitGatewayMulticastDomainId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomainassociation.html#cfn-ec2-transitgatewaymulticastdomainassociation-transitgatewaymulticastdomainid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "transitGatewayMulticastDomainId"))

    @transit_gateway_multicast_domain_id.setter
    def transit_gateway_multicast_domain_id(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "transitGatewayMulticastDomainId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayMulticastDomainAssociationProps",
    jsii_struct_bases=[],
    name_mapping={
        "state": "state",
        "subnet_id": "subnetId",
        "transit_gateway_attachment_id": "transitGatewayAttachmentId",
        "transit_gateway_multicast_domain_id": "transitGatewayMulticastDomainId",
    },
)
class CfnTransitGatewayMulticastDomainAssociationProps:
    def __init__(
        self,
        *,
        state: typing.Optional[builtins.str] = None,
        subnet_id: typing.Optional[builtins.str] = None,
        transit_gateway_attachment_id: typing.Optional[builtins.str] = None,
        transit_gateway_multicast_domain_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TransitGatewayMulticastDomainAssociation``.

        :param state: ``AWS::EC2::TransitGatewayMulticastDomainAssociation.State``.
        :param subnet_id: ``AWS::EC2::TransitGatewayMulticastDomainAssociation.SubnetId``.
        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayMulticastDomainAssociation.TransitGatewayAttachmentId``.
        :param transit_gateway_multicast_domain_id: ``AWS::EC2::TransitGatewayMulticastDomainAssociation.TransitGatewayMulticastDomainId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomainassociation.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if state is not None:
            self._values["state"] = state
        if subnet_id is not None:
            self._values["subnet_id"] = subnet_id
        if transit_gateway_attachment_id is not None:
            self._values["transit_gateway_attachment_id"] = transit_gateway_attachment_id
        if transit_gateway_multicast_domain_id is not None:
            self._values["transit_gateway_multicast_domain_id"] = transit_gateway_multicast_domain_id

    @builtins.property
    def state(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastDomainAssociation.State``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomainassociation.html#cfn-ec2-transitgatewaymulticastdomainassociation-state
        '''
        result = self._values.get("state")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def subnet_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastDomainAssociation.SubnetId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomainassociation.html#cfn-ec2-transitgatewaymulticastdomainassociation-subnetid
        '''
        result = self._values.get("subnet_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def transit_gateway_attachment_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastDomainAssociation.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomainassociation.html#cfn-ec2-transitgatewaymulticastdomainassociation-transitgatewayattachmentid
        '''
        result = self._values.get("transit_gateway_attachment_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def transit_gateway_multicast_domain_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastDomainAssociation.TransitGatewayMulticastDomainId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomainassociation.html#cfn-ec2-transitgatewaymulticastdomainassociation-transitgatewaymulticastdomainid
        '''
        result = self._values.get("transit_gateway_multicast_domain_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTransitGatewayMulticastDomainAssociationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayMulticastDomainProps",
    jsii_struct_bases=[],
    name_mapping={
        "options": "options",
        "tags": "tags",
        "transit_gateway_id": "transitGatewayId",
    },
)
class CfnTransitGatewayMulticastDomainProps:
    def __init__(
        self,
        *,
        options: typing.Any = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        transit_gateway_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TransitGatewayMulticastDomain``.

        :param options: ``AWS::EC2::TransitGatewayMulticastDomain.Options``.
        :param tags: ``AWS::EC2::TransitGatewayMulticastDomain.Tags``.
        :param transit_gateway_id: ``AWS::EC2::TransitGatewayMulticastDomain.TransitGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomain.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if options is not None:
            self._values["options"] = options
        if tags is not None:
            self._values["tags"] = tags
        if transit_gateway_id is not None:
            self._values["transit_gateway_id"] = transit_gateway_id

    @builtins.property
    def options(self) -> typing.Any:
        '''``AWS::EC2::TransitGatewayMulticastDomain.Options``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomain.html#cfn-ec2-transitgatewaymulticastdomain-options
        '''
        result = self._values.get("options")
        return typing.cast(typing.Any, result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::TransitGatewayMulticastDomain.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomain.html#cfn-ec2-transitgatewaymulticastdomain-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    @builtins.property
    def transit_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastDomain.TransitGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastdomain.html#cfn-ec2-transitgatewaymulticastdomain-transitgatewayid
        '''
        result = self._values.get("transit_gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTransitGatewayMulticastDomainProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTransitGatewayMulticastGroupMember(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayMulticastGroupMember",
):
    '''A CloudFormation ``AWS::EC2::TransitGatewayMulticastGroupMember``.

    :cloudformationResource: AWS::EC2::TransitGatewayMulticastGroupMember
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupmember.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        group_ip_address: typing.Optional[builtins.str] = None,
        network_interface_id: typing.Optional[builtins.str] = None,
        transit_gateway_attachment_id: typing.Optional[builtins.str] = None,
        transit_gateway_multicast_domain_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TransitGatewayMulticastGroupMember``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param group_ip_address: ``AWS::EC2::TransitGatewayMulticastGroupMember.GroupIpAddress``.
        :param network_interface_id: ``AWS::EC2::TransitGatewayMulticastGroupMember.NetworkInterfaceId``.
        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayMulticastGroupMember.TransitGatewayAttachmentId``.
        :param transit_gateway_multicast_domain_id: ``AWS::EC2::TransitGatewayMulticastGroupMember.TransitGatewayMulticastDomainId``.
        '''
        props = CfnTransitGatewayMulticastGroupMemberProps(
            group_ip_address=group_ip_address,
            network_interface_id=network_interface_id,
            transit_gateway_attachment_id=transit_gateway_attachment_id,
            transit_gateway_multicast_domain_id=transit_gateway_multicast_domain_id,
        )

        jsii.create(CfnTransitGatewayMulticastGroupMember, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrGroupMember")
    def attr_group_member(self) -> aws_cdk.core.IResolvable:
        '''
        :cloudformationAttribute: GroupMember
        '''
        return typing.cast(aws_cdk.core.IResolvable, jsii.get(self, "attrGroupMember"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrGroupSource")
    def attr_group_source(self) -> aws_cdk.core.IResolvable:
        '''
        :cloudformationAttribute: GroupSource
        '''
        return typing.cast(aws_cdk.core.IResolvable, jsii.get(self, "attrGroupSource"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrMemberType")
    def attr_member_type(self) -> builtins.str:
        '''
        :cloudformationAttribute: MemberType
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMemberType"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrResourceId")
    def attr_resource_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: ResourceId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrResourceType")
    def attr_resource_type(self) -> builtins.str:
        '''
        :cloudformationAttribute: ResourceType
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceType"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrSourceType")
    def attr_source_type(self) -> builtins.str:
        '''
        :cloudformationAttribute: SourceType
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrSourceType"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrSubnetId")
    def attr_subnet_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: SubnetId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrSubnetId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="groupIpAddress")
    def group_ip_address(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupMember.GroupIpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupmember.html#cfn-ec2-transitgatewaymulticastgroupmember-groupipaddress
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "groupIpAddress"))

    @group_ip_address.setter
    def group_ip_address(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "groupIpAddress", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkInterfaceId")
    def network_interface_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupMember.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupmember.html#cfn-ec2-transitgatewaymulticastgroupmember-networkinterfaceid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "networkInterfaceId"))

    @network_interface_id.setter
    def network_interface_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "networkInterfaceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayAttachmentId")
    def transit_gateway_attachment_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupMember.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupmember.html#cfn-ec2-transitgatewaymulticastgroupmember-transitgatewayattachmentid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "transitGatewayAttachmentId"))

    @transit_gateway_attachment_id.setter
    def transit_gateway_attachment_id(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "transitGatewayAttachmentId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayMulticastDomainId")
    def transit_gateway_multicast_domain_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupMember.TransitGatewayMulticastDomainId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupmember.html#cfn-ec2-transitgatewaymulticastgroupmember-transitgatewaymulticastdomainid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "transitGatewayMulticastDomainId"))

    @transit_gateway_multicast_domain_id.setter
    def transit_gateway_multicast_domain_id(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "transitGatewayMulticastDomainId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayMulticastGroupMemberProps",
    jsii_struct_bases=[],
    name_mapping={
        "group_ip_address": "groupIpAddress",
        "network_interface_id": "networkInterfaceId",
        "transit_gateway_attachment_id": "transitGatewayAttachmentId",
        "transit_gateway_multicast_domain_id": "transitGatewayMulticastDomainId",
    },
)
class CfnTransitGatewayMulticastGroupMemberProps:
    def __init__(
        self,
        *,
        group_ip_address: typing.Optional[builtins.str] = None,
        network_interface_id: typing.Optional[builtins.str] = None,
        transit_gateway_attachment_id: typing.Optional[builtins.str] = None,
        transit_gateway_multicast_domain_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TransitGatewayMulticastGroupMember``.

        :param group_ip_address: ``AWS::EC2::TransitGatewayMulticastGroupMember.GroupIpAddress``.
        :param network_interface_id: ``AWS::EC2::TransitGatewayMulticastGroupMember.NetworkInterfaceId``.
        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayMulticastGroupMember.TransitGatewayAttachmentId``.
        :param transit_gateway_multicast_domain_id: ``AWS::EC2::TransitGatewayMulticastGroupMember.TransitGatewayMulticastDomainId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupmember.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if group_ip_address is not None:
            self._values["group_ip_address"] = group_ip_address
        if network_interface_id is not None:
            self._values["network_interface_id"] = network_interface_id
        if transit_gateway_attachment_id is not None:
            self._values["transit_gateway_attachment_id"] = transit_gateway_attachment_id
        if transit_gateway_multicast_domain_id is not None:
            self._values["transit_gateway_multicast_domain_id"] = transit_gateway_multicast_domain_id

    @builtins.property
    def group_ip_address(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupMember.GroupIpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupmember.html#cfn-ec2-transitgatewaymulticastgroupmember-groupipaddress
        '''
        result = self._values.get("group_ip_address")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def network_interface_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupMember.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupmember.html#cfn-ec2-transitgatewaymulticastgroupmember-networkinterfaceid
        '''
        result = self._values.get("network_interface_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def transit_gateway_attachment_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupMember.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupmember.html#cfn-ec2-transitgatewaymulticastgroupmember-transitgatewayattachmentid
        '''
        result = self._values.get("transit_gateway_attachment_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def transit_gateway_multicast_domain_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupMember.TransitGatewayMulticastDomainId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupmember.html#cfn-ec2-transitgatewaymulticastgroupmember-transitgatewaymulticastdomainid
        '''
        result = self._values.get("transit_gateway_multicast_domain_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTransitGatewayMulticastGroupMemberProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTransitGatewayMulticastGroupSource(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayMulticastGroupSource",
):
    '''A CloudFormation ``AWS::EC2::TransitGatewayMulticastGroupSource``.

    :cloudformationResource: AWS::EC2::TransitGatewayMulticastGroupSource
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupsource.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        group_ip_address: typing.Optional[builtins.str] = None,
        network_interface_id: typing.Optional[builtins.str] = None,
        transit_gateway_attachment_id: typing.Optional[builtins.str] = None,
        transit_gateway_multicast_domain_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TransitGatewayMulticastGroupSource``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param group_ip_address: ``AWS::EC2::TransitGatewayMulticastGroupSource.GroupIpAddress``.
        :param network_interface_id: ``AWS::EC2::TransitGatewayMulticastGroupSource.NetworkInterfaceId``.
        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayMulticastGroupSource.TransitGatewayAttachmentId``.
        :param transit_gateway_multicast_domain_id: ``AWS::EC2::TransitGatewayMulticastGroupSource.TransitGatewayMulticastDomainId``.
        '''
        props = CfnTransitGatewayMulticastGroupSourceProps(
            group_ip_address=group_ip_address,
            network_interface_id=network_interface_id,
            transit_gateway_attachment_id=transit_gateway_attachment_id,
            transit_gateway_multicast_domain_id=transit_gateway_multicast_domain_id,
        )

        jsii.create(CfnTransitGatewayMulticastGroupSource, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrGroupMember")
    def attr_group_member(self) -> aws_cdk.core.IResolvable:
        '''
        :cloudformationAttribute: GroupMember
        '''
        return typing.cast(aws_cdk.core.IResolvable, jsii.get(self, "attrGroupMember"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrGroupSource")
    def attr_group_source(self) -> aws_cdk.core.IResolvable:
        '''
        :cloudformationAttribute: GroupSource
        '''
        return typing.cast(aws_cdk.core.IResolvable, jsii.get(self, "attrGroupSource"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrMemberType")
    def attr_member_type(self) -> builtins.str:
        '''
        :cloudformationAttribute: MemberType
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrMemberType"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrResourceId")
    def attr_resource_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: ResourceId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrResourceType")
    def attr_resource_type(self) -> builtins.str:
        '''
        :cloudformationAttribute: ResourceType
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrResourceType"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrSourceType")
    def attr_source_type(self) -> builtins.str:
        '''
        :cloudformationAttribute: SourceType
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrSourceType"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrSubnetId")
    def attr_subnet_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: SubnetId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrSubnetId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="groupIpAddress")
    def group_ip_address(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupSource.GroupIpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupsource.html#cfn-ec2-transitgatewaymulticastgroupsource-groupipaddress
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "groupIpAddress"))

    @group_ip_address.setter
    def group_ip_address(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "groupIpAddress", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkInterfaceId")
    def network_interface_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupSource.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupsource.html#cfn-ec2-transitgatewaymulticastgroupsource-networkinterfaceid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "networkInterfaceId"))

    @network_interface_id.setter
    def network_interface_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "networkInterfaceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayAttachmentId")
    def transit_gateway_attachment_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupSource.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupsource.html#cfn-ec2-transitgatewaymulticastgroupsource-transitgatewayattachmentid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "transitGatewayAttachmentId"))

    @transit_gateway_attachment_id.setter
    def transit_gateway_attachment_id(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "transitGatewayAttachmentId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayMulticastDomainId")
    def transit_gateway_multicast_domain_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupSource.TransitGatewayMulticastDomainId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupsource.html#cfn-ec2-transitgatewaymulticastgroupsource-transitgatewaymulticastdomainid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "transitGatewayMulticastDomainId"))

    @transit_gateway_multicast_domain_id.setter
    def transit_gateway_multicast_domain_id(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "transitGatewayMulticastDomainId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayMulticastGroupSourceProps",
    jsii_struct_bases=[],
    name_mapping={
        "group_ip_address": "groupIpAddress",
        "network_interface_id": "networkInterfaceId",
        "transit_gateway_attachment_id": "transitGatewayAttachmentId",
        "transit_gateway_multicast_domain_id": "transitGatewayMulticastDomainId",
    },
)
class CfnTransitGatewayMulticastGroupSourceProps:
    def __init__(
        self,
        *,
        group_ip_address: typing.Optional[builtins.str] = None,
        network_interface_id: typing.Optional[builtins.str] = None,
        transit_gateway_attachment_id: typing.Optional[builtins.str] = None,
        transit_gateway_multicast_domain_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TransitGatewayMulticastGroupSource``.

        :param group_ip_address: ``AWS::EC2::TransitGatewayMulticastGroupSource.GroupIpAddress``.
        :param network_interface_id: ``AWS::EC2::TransitGatewayMulticastGroupSource.NetworkInterfaceId``.
        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayMulticastGroupSource.TransitGatewayAttachmentId``.
        :param transit_gateway_multicast_domain_id: ``AWS::EC2::TransitGatewayMulticastGroupSource.TransitGatewayMulticastDomainId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupsource.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if group_ip_address is not None:
            self._values["group_ip_address"] = group_ip_address
        if network_interface_id is not None:
            self._values["network_interface_id"] = network_interface_id
        if transit_gateway_attachment_id is not None:
            self._values["transit_gateway_attachment_id"] = transit_gateway_attachment_id
        if transit_gateway_multicast_domain_id is not None:
            self._values["transit_gateway_multicast_domain_id"] = transit_gateway_multicast_domain_id

    @builtins.property
    def group_ip_address(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupSource.GroupIpAddress``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupsource.html#cfn-ec2-transitgatewaymulticastgroupsource-groupipaddress
        '''
        result = self._values.get("group_ip_address")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def network_interface_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupSource.NetworkInterfaceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupsource.html#cfn-ec2-transitgatewaymulticastgroupsource-networkinterfaceid
        '''
        result = self._values.get("network_interface_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def transit_gateway_attachment_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupSource.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupsource.html#cfn-ec2-transitgatewaymulticastgroupsource-transitgatewayattachmentid
        '''
        result = self._values.get("transit_gateway_attachment_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def transit_gateway_multicast_domain_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayMulticastGroupSource.TransitGatewayMulticastDomainId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaymulticastgroupsource.html#cfn-ec2-transitgatewaymulticastgroupsource-transitgatewaymulticastdomainid
        '''
        result = self._values.get("transit_gateway_multicast_domain_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTransitGatewayMulticastGroupSourceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayProps",
    jsii_struct_bases=[],
    name_mapping={
        "amazon_side_asn": "amazonSideAsn",
        "auto_accept_shared_attachments": "autoAcceptSharedAttachments",
        "default_route_table_association": "defaultRouteTableAssociation",
        "default_route_table_propagation": "defaultRouteTablePropagation",
        "description": "description",
        "dns_support": "dnsSupport",
        "multicast_support": "multicastSupport",
        "tags": "tags",
        "vpn_ecmp_support": "vpnEcmpSupport",
    },
)
class CfnTransitGatewayProps:
    def __init__(
        self,
        *,
        amazon_side_asn: typing.Optional[jsii.Number] = None,
        auto_accept_shared_attachments: typing.Optional[builtins.str] = None,
        default_route_table_association: typing.Optional[builtins.str] = None,
        default_route_table_propagation: typing.Optional[builtins.str] = None,
        description: typing.Optional[builtins.str] = None,
        dns_support: typing.Optional[builtins.str] = None,
        multicast_support: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        vpn_ecmp_support: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TransitGateway``.

        :param amazon_side_asn: ``AWS::EC2::TransitGateway.AmazonSideAsn``.
        :param auto_accept_shared_attachments: ``AWS::EC2::TransitGateway.AutoAcceptSharedAttachments``.
        :param default_route_table_association: ``AWS::EC2::TransitGateway.DefaultRouteTableAssociation``.
        :param default_route_table_propagation: ``AWS::EC2::TransitGateway.DefaultRouteTablePropagation``.
        :param description: ``AWS::EC2::TransitGateway.Description``.
        :param dns_support: ``AWS::EC2::TransitGateway.DnsSupport``.
        :param multicast_support: ``AWS::EC2::TransitGateway.MulticastSupport``.
        :param tags: ``AWS::EC2::TransitGateway.Tags``.
        :param vpn_ecmp_support: ``AWS::EC2::TransitGateway.VpnEcmpSupport``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if amazon_side_asn is not None:
            self._values["amazon_side_asn"] = amazon_side_asn
        if auto_accept_shared_attachments is not None:
            self._values["auto_accept_shared_attachments"] = auto_accept_shared_attachments
        if default_route_table_association is not None:
            self._values["default_route_table_association"] = default_route_table_association
        if default_route_table_propagation is not None:
            self._values["default_route_table_propagation"] = default_route_table_propagation
        if description is not None:
            self._values["description"] = description
        if dns_support is not None:
            self._values["dns_support"] = dns_support
        if multicast_support is not None:
            self._values["multicast_support"] = multicast_support
        if tags is not None:
            self._values["tags"] = tags
        if vpn_ecmp_support is not None:
            self._values["vpn_ecmp_support"] = vpn_ecmp_support

    @builtins.property
    def amazon_side_asn(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::TransitGateway.AmazonSideAsn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-amazonsideasn
        '''
        result = self._values.get("amazon_side_asn")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def auto_accept_shared_attachments(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.AutoAcceptSharedAttachments``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-autoacceptsharedattachments
        '''
        result = self._values.get("auto_accept_shared_attachments")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def default_route_table_association(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.DefaultRouteTableAssociation``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-defaultroutetableassociation
        '''
        result = self._values.get("default_route_table_association")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def default_route_table_propagation(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.DefaultRouteTablePropagation``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-defaultroutetablepropagation
        '''
        result = self._values.get("default_route_table_propagation")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.Description``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def dns_support(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.DnsSupport``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-dnssupport
        '''
        result = self._values.get("dns_support")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def multicast_support(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.MulticastSupport``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-multicastsupport
        '''
        result = self._values.get("multicast_support")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::TransitGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    @builtins.property
    def vpn_ecmp_support(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGateway.VpnEcmpSupport``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgateway.html#cfn-ec2-transitgateway-vpnecmpsupport
        '''
        result = self._values.get("vpn_ecmp_support")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTransitGatewayProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTransitGatewayRoute(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayRoute",
):
    '''A CloudFormation ``AWS::EC2::TransitGatewayRoute``.

    :cloudformationResource: AWS::EC2::TransitGatewayRoute
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroute.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        transit_gateway_route_table_id: builtins.str,
        blackhole: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        destination_cidr_block: typing.Optional[builtins.str] = None,
        transit_gateway_attachment_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TransitGatewayRoute``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param transit_gateway_route_table_id: ``AWS::EC2::TransitGatewayRoute.TransitGatewayRouteTableId``.
        :param blackhole: ``AWS::EC2::TransitGatewayRoute.Blackhole``.
        :param destination_cidr_block: ``AWS::EC2::TransitGatewayRoute.DestinationCidrBlock``.
        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayRoute.TransitGatewayAttachmentId``.
        '''
        props = CfnTransitGatewayRouteProps(
            transit_gateway_route_table_id=transit_gateway_route_table_id,
            blackhole=blackhole,
            destination_cidr_block=destination_cidr_block,
            transit_gateway_attachment_id=transit_gateway_attachment_id,
        )

        jsii.create(CfnTransitGatewayRoute, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayRouteTableId")
    def transit_gateway_route_table_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRoute.TransitGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroute.html#cfn-ec2-transitgatewayroute-transitgatewayroutetableid
        '''
        return typing.cast(builtins.str, jsii.get(self, "transitGatewayRouteTableId"))

    @transit_gateway_route_table_id.setter
    def transit_gateway_route_table_id(self, value: builtins.str) -> None:
        jsii.set(self, "transitGatewayRouteTableId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="blackhole")
    def blackhole(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::TransitGatewayRoute.Blackhole``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroute.html#cfn-ec2-transitgatewayroute-blackhole
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "blackhole"))

    @blackhole.setter
    def blackhole(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "blackhole", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationCidrBlock")
    def destination_cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayRoute.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroute.html#cfn-ec2-transitgatewayroute-destinationcidrblock
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "destinationCidrBlock"))

    @destination_cidr_block.setter
    def destination_cidr_block(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "destinationCidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayAttachmentId")
    def transit_gateway_attachment_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayRoute.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroute.html#cfn-ec2-transitgatewayroute-transitgatewayattachmentid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "transitGatewayAttachmentId"))

    @transit_gateway_attachment_id.setter
    def transit_gateway_attachment_id(
        self,
        value: typing.Optional[builtins.str],
    ) -> None:
        jsii.set(self, "transitGatewayAttachmentId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayRouteProps",
    jsii_struct_bases=[],
    name_mapping={
        "transit_gateway_route_table_id": "transitGatewayRouteTableId",
        "blackhole": "blackhole",
        "destination_cidr_block": "destinationCidrBlock",
        "transit_gateway_attachment_id": "transitGatewayAttachmentId",
    },
)
class CfnTransitGatewayRouteProps:
    def __init__(
        self,
        *,
        transit_gateway_route_table_id: builtins.str,
        blackhole: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        destination_cidr_block: typing.Optional[builtins.str] = None,
        transit_gateway_attachment_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TransitGatewayRoute``.

        :param transit_gateway_route_table_id: ``AWS::EC2::TransitGatewayRoute.TransitGatewayRouteTableId``.
        :param blackhole: ``AWS::EC2::TransitGatewayRoute.Blackhole``.
        :param destination_cidr_block: ``AWS::EC2::TransitGatewayRoute.DestinationCidrBlock``.
        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayRoute.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroute.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "transit_gateway_route_table_id": transit_gateway_route_table_id,
        }
        if blackhole is not None:
            self._values["blackhole"] = blackhole
        if destination_cidr_block is not None:
            self._values["destination_cidr_block"] = destination_cidr_block
        if transit_gateway_attachment_id is not None:
            self._values["transit_gateway_attachment_id"] = transit_gateway_attachment_id

    @builtins.property
    def transit_gateway_route_table_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRoute.TransitGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroute.html#cfn-ec2-transitgatewayroute-transitgatewayroutetableid
        '''
        result = self._values.get("transit_gateway_route_table_id")
        assert result is not None, "Required property 'transit_gateway_route_table_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def blackhole(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::TransitGatewayRoute.Blackhole``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroute.html#cfn-ec2-transitgatewayroute-blackhole
        '''
        result = self._values.get("blackhole")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def destination_cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayRoute.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroute.html#cfn-ec2-transitgatewayroute-destinationcidrblock
        '''
        result = self._values.get("destination_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def transit_gateway_attachment_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::TransitGatewayRoute.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroute.html#cfn-ec2-transitgatewayroute-transitgatewayattachmentid
        '''
        result = self._values.get("transit_gateway_attachment_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTransitGatewayRouteProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTransitGatewayRouteTable(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayRouteTable",
):
    '''A CloudFormation ``AWS::EC2::TransitGatewayRouteTable``.

    :cloudformationResource: AWS::EC2::TransitGatewayRouteTable
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetable.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        transit_gateway_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::TransitGatewayRouteTable``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param transit_gateway_id: ``AWS::EC2::TransitGatewayRouteTable.TransitGatewayId``.
        :param tags: ``AWS::EC2::TransitGatewayRouteTable.Tags``.
        '''
        props = CfnTransitGatewayRouteTableProps(
            transit_gateway_id=transit_gateway_id, tags=tags
        )

        jsii.create(CfnTransitGatewayRouteTable, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::TransitGatewayRouteTable.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetable.html#cfn-ec2-transitgatewayroutetable-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayId")
    def transit_gateway_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRouteTable.TransitGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetable.html#cfn-ec2-transitgatewayroutetable-transitgatewayid
        '''
        return typing.cast(builtins.str, jsii.get(self, "transitGatewayId"))

    @transit_gateway_id.setter
    def transit_gateway_id(self, value: builtins.str) -> None:
        jsii.set(self, "transitGatewayId", value)


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTransitGatewayRouteTableAssociation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayRouteTableAssociation",
):
    '''A CloudFormation ``AWS::EC2::TransitGatewayRouteTableAssociation``.

    :cloudformationResource: AWS::EC2::TransitGatewayRouteTableAssociation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetableassociation.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        transit_gateway_attachment_id: builtins.str,
        transit_gateway_route_table_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::TransitGatewayRouteTableAssociation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayRouteTableAssociation.TransitGatewayAttachmentId``.
        :param transit_gateway_route_table_id: ``AWS::EC2::TransitGatewayRouteTableAssociation.TransitGatewayRouteTableId``.
        '''
        props = CfnTransitGatewayRouteTableAssociationProps(
            transit_gateway_attachment_id=transit_gateway_attachment_id,
            transit_gateway_route_table_id=transit_gateway_route_table_id,
        )

        jsii.create(CfnTransitGatewayRouteTableAssociation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayAttachmentId")
    def transit_gateway_attachment_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRouteTableAssociation.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetableassociation.html#cfn-ec2-transitgatewayroutetableassociation-transitgatewayattachmentid
        '''
        return typing.cast(builtins.str, jsii.get(self, "transitGatewayAttachmentId"))

    @transit_gateway_attachment_id.setter
    def transit_gateway_attachment_id(self, value: builtins.str) -> None:
        jsii.set(self, "transitGatewayAttachmentId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayRouteTableId")
    def transit_gateway_route_table_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRouteTableAssociation.TransitGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetableassociation.html#cfn-ec2-transitgatewayroutetableassociation-transitgatewayroutetableid
        '''
        return typing.cast(builtins.str, jsii.get(self, "transitGatewayRouteTableId"))

    @transit_gateway_route_table_id.setter
    def transit_gateway_route_table_id(self, value: builtins.str) -> None:
        jsii.set(self, "transitGatewayRouteTableId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayRouteTableAssociationProps",
    jsii_struct_bases=[],
    name_mapping={
        "transit_gateway_attachment_id": "transitGatewayAttachmentId",
        "transit_gateway_route_table_id": "transitGatewayRouteTableId",
    },
)
class CfnTransitGatewayRouteTableAssociationProps:
    def __init__(
        self,
        *,
        transit_gateway_attachment_id: builtins.str,
        transit_gateway_route_table_id: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TransitGatewayRouteTableAssociation``.

        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayRouteTableAssociation.TransitGatewayAttachmentId``.
        :param transit_gateway_route_table_id: ``AWS::EC2::TransitGatewayRouteTableAssociation.TransitGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetableassociation.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "transit_gateway_attachment_id": transit_gateway_attachment_id,
            "transit_gateway_route_table_id": transit_gateway_route_table_id,
        }

    @builtins.property
    def transit_gateway_attachment_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRouteTableAssociation.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetableassociation.html#cfn-ec2-transitgatewayroutetableassociation-transitgatewayattachmentid
        '''
        result = self._values.get("transit_gateway_attachment_id")
        assert result is not None, "Required property 'transit_gateway_attachment_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def transit_gateway_route_table_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRouteTableAssociation.TransitGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetableassociation.html#cfn-ec2-transitgatewayroutetableassociation-transitgatewayroutetableid
        '''
        result = self._values.get("transit_gateway_route_table_id")
        assert result is not None, "Required property 'transit_gateway_route_table_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTransitGatewayRouteTableAssociationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnTransitGatewayRouteTablePropagation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayRouteTablePropagation",
):
    '''A CloudFormation ``AWS::EC2::TransitGatewayRouteTablePropagation``.

    :cloudformationResource: AWS::EC2::TransitGatewayRouteTablePropagation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetablepropagation.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        transit_gateway_attachment_id: builtins.str,
        transit_gateway_route_table_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::TransitGatewayRouteTablePropagation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayRouteTablePropagation.TransitGatewayAttachmentId``.
        :param transit_gateway_route_table_id: ``AWS::EC2::TransitGatewayRouteTablePropagation.TransitGatewayRouteTableId``.
        '''
        props = CfnTransitGatewayRouteTablePropagationProps(
            transit_gateway_attachment_id=transit_gateway_attachment_id,
            transit_gateway_route_table_id=transit_gateway_route_table_id,
        )

        jsii.create(CfnTransitGatewayRouteTablePropagation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayAttachmentId")
    def transit_gateway_attachment_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRouteTablePropagation.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetablepropagation.html#cfn-ec2-transitgatewayroutetablepropagation-transitgatewayattachmentid
        '''
        return typing.cast(builtins.str, jsii.get(self, "transitGatewayAttachmentId"))

    @transit_gateway_attachment_id.setter
    def transit_gateway_attachment_id(self, value: builtins.str) -> None:
        jsii.set(self, "transitGatewayAttachmentId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayRouteTableId")
    def transit_gateway_route_table_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRouteTablePropagation.TransitGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetablepropagation.html#cfn-ec2-transitgatewayroutetablepropagation-transitgatewayroutetableid
        '''
        return typing.cast(builtins.str, jsii.get(self, "transitGatewayRouteTableId"))

    @transit_gateway_route_table_id.setter
    def transit_gateway_route_table_id(self, value: builtins.str) -> None:
        jsii.set(self, "transitGatewayRouteTableId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayRouteTablePropagationProps",
    jsii_struct_bases=[],
    name_mapping={
        "transit_gateway_attachment_id": "transitGatewayAttachmentId",
        "transit_gateway_route_table_id": "transitGatewayRouteTableId",
    },
)
class CfnTransitGatewayRouteTablePropagationProps:
    def __init__(
        self,
        *,
        transit_gateway_attachment_id: builtins.str,
        transit_gateway_route_table_id: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TransitGatewayRouteTablePropagation``.

        :param transit_gateway_attachment_id: ``AWS::EC2::TransitGatewayRouteTablePropagation.TransitGatewayAttachmentId``.
        :param transit_gateway_route_table_id: ``AWS::EC2::TransitGatewayRouteTablePropagation.TransitGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetablepropagation.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "transit_gateway_attachment_id": transit_gateway_attachment_id,
            "transit_gateway_route_table_id": transit_gateway_route_table_id,
        }

    @builtins.property
    def transit_gateway_attachment_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRouteTablePropagation.TransitGatewayAttachmentId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetablepropagation.html#cfn-ec2-transitgatewayroutetablepropagation-transitgatewayattachmentid
        '''
        result = self._values.get("transit_gateway_attachment_id")
        assert result is not None, "Required property 'transit_gateway_attachment_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def transit_gateway_route_table_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRouteTablePropagation.TransitGatewayRouteTableId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetablepropagation.html#cfn-ec2-transitgatewayroutetablepropagation-transitgatewayroutetableid
        '''
        result = self._values.get("transit_gateway_route_table_id")
        assert result is not None, "Required property 'transit_gateway_route_table_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTransitGatewayRouteTablePropagationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnTransitGatewayRouteTableProps",
    jsii_struct_bases=[],
    name_mapping={"transit_gateway_id": "transitGatewayId", "tags": "tags"},
)
class CfnTransitGatewayRouteTableProps:
    def __init__(
        self,
        *,
        transit_gateway_id: builtins.str,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::TransitGatewayRouteTable``.

        :param transit_gateway_id: ``AWS::EC2::TransitGatewayRouteTable.TransitGatewayId``.
        :param tags: ``AWS::EC2::TransitGatewayRouteTable.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetable.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "transit_gateway_id": transit_gateway_id,
        }
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def transit_gateway_id(self) -> builtins.str:
        '''``AWS::EC2::TransitGatewayRouteTable.TransitGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetable.html#cfn-ec2-transitgatewayroutetable-transitgatewayid
        '''
        result = self._values.get("transit_gateway_id")
        assert result is not None, "Required property 'transit_gateway_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::TransitGatewayRouteTable.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewayroutetable.html#cfn-ec2-transitgatewayroutetable-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnTransitGatewayRouteTableProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPC(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPC",
):
    '''A CloudFormation ``AWS::EC2::VPC``.

    :cloudformationResource: AWS::EC2::VPC
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        cidr_block: builtins.str,
        enable_dns_hostnames: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        enable_dns_support: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        instance_tenancy: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::VPC``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param cidr_block: ``AWS::EC2::VPC.CidrBlock``.
        :param enable_dns_hostnames: ``AWS::EC2::VPC.EnableDnsHostnames``.
        :param enable_dns_support: ``AWS::EC2::VPC.EnableDnsSupport``.
        :param instance_tenancy: ``AWS::EC2::VPC.InstanceTenancy``.
        :param tags: ``AWS::EC2::VPC.Tags``.
        '''
        props = CfnVPCProps(
            cidr_block=cidr_block,
            enable_dns_hostnames=enable_dns_hostnames,
            enable_dns_support=enable_dns_support,
            instance_tenancy=instance_tenancy,
            tags=tags,
        )

        jsii.create(CfnVPC, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrCidrBlock")
    def attr_cidr_block(self) -> builtins.str:
        '''
        :cloudformationAttribute: CidrBlock
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrCidrBlock"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrCidrBlockAssociations")
    def attr_cidr_block_associations(self) -> typing.List[builtins.str]:
        '''
        :cloudformationAttribute: CidrBlockAssociations
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "attrCidrBlockAssociations"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrDefaultNetworkAcl")
    def attr_default_network_acl(self) -> builtins.str:
        '''
        :cloudformationAttribute: DefaultNetworkAcl
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrDefaultNetworkAcl"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrDefaultSecurityGroup")
    def attr_default_security_group(self) -> builtins.str:
        '''
        :cloudformationAttribute: DefaultSecurityGroup
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrDefaultSecurityGroup"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrIpv6CidrBlocks")
    def attr_ipv6_cidr_blocks(self) -> typing.List[builtins.str]:
        '''
        :cloudformationAttribute: Ipv6CidrBlocks
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "attrIpv6CidrBlocks"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::VPC.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html#cfn-aws-ec2-vpc-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cidrBlock")
    def cidr_block(self) -> builtins.str:
        '''``AWS::EC2::VPC.CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html#cfn-aws-ec2-vpc-cidrblock
        '''
        return typing.cast(builtins.str, jsii.get(self, "cidrBlock"))

    @cidr_block.setter
    def cidr_block(self, value: builtins.str) -> None:
        jsii.set(self, "cidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="enableDnsHostnames")
    def enable_dns_hostnames(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPC.EnableDnsHostnames``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html#cfn-aws-ec2-vpc-EnableDnsHostnames
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "enableDnsHostnames"))

    @enable_dns_hostnames.setter
    def enable_dns_hostnames(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "enableDnsHostnames", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="enableDnsSupport")
    def enable_dns_support(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPC.EnableDnsSupport``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html#cfn-aws-ec2-vpc-EnableDnsSupport
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "enableDnsSupport"))

    @enable_dns_support.setter
    def enable_dns_support(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "enableDnsSupport", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceTenancy")
    def instance_tenancy(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPC.InstanceTenancy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html#cfn-aws-ec2-vpc-instancetenancy
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "instanceTenancy"))

    @instance_tenancy.setter
    def instance_tenancy(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "instanceTenancy", value)


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPCCidrBlock(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPCCidrBlock",
):
    '''A CloudFormation ``AWS::EC2::VPCCidrBlock``.

    :cloudformationResource: AWS::EC2::VPCCidrBlock
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpccidrblock.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        vpc_id: builtins.str,
        amazon_provided_ipv6_cidr_block: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        cidr_block: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::VPCCidrBlock``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param vpc_id: ``AWS::EC2::VPCCidrBlock.VpcId``.
        :param amazon_provided_ipv6_cidr_block: ``AWS::EC2::VPCCidrBlock.AmazonProvidedIpv6CidrBlock``.
        :param cidr_block: ``AWS::EC2::VPCCidrBlock.CidrBlock``.
        '''
        props = CfnVPCCidrBlockProps(
            vpc_id=vpc_id,
            amazon_provided_ipv6_cidr_block=amazon_provided_ipv6_cidr_block,
            cidr_block=cidr_block,
        )

        jsii.create(CfnVPCCidrBlock, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCCidrBlock.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpccidrblock.html#cfn-ec2-vpccidrblock-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="amazonProvidedIpv6CidrBlock")
    def amazon_provided_ipv6_cidr_block(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPCCidrBlock.AmazonProvidedIpv6CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpccidrblock.html#cfn-ec2-vpccidrblock-amazonprovidedipv6cidrblock
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "amazonProvidedIpv6CidrBlock"))

    @amazon_provided_ipv6_cidr_block.setter
    def amazon_provided_ipv6_cidr_block(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "amazonProvidedIpv6CidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cidrBlock")
    def cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCCidrBlock.CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpccidrblock.html#cfn-ec2-vpccidrblock-cidrblock
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "cidrBlock"))

    @cidr_block.setter
    def cidr_block(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "cidrBlock", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPCCidrBlockProps",
    jsii_struct_bases=[],
    name_mapping={
        "vpc_id": "vpcId",
        "amazon_provided_ipv6_cidr_block": "amazonProvidedIpv6CidrBlock",
        "cidr_block": "cidrBlock",
    },
)
class CfnVPCCidrBlockProps:
    def __init__(
        self,
        *,
        vpc_id: builtins.str,
        amazon_provided_ipv6_cidr_block: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        cidr_block: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPCCidrBlock``.

        :param vpc_id: ``AWS::EC2::VPCCidrBlock.VpcId``.
        :param amazon_provided_ipv6_cidr_block: ``AWS::EC2::VPCCidrBlock.AmazonProvidedIpv6CidrBlock``.
        :param cidr_block: ``AWS::EC2::VPCCidrBlock.CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpccidrblock.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "vpc_id": vpc_id,
        }
        if amazon_provided_ipv6_cidr_block is not None:
            self._values["amazon_provided_ipv6_cidr_block"] = amazon_provided_ipv6_cidr_block
        if cidr_block is not None:
            self._values["cidr_block"] = cidr_block

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCCidrBlock.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpccidrblock.html#cfn-ec2-vpccidrblock-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def amazon_provided_ipv6_cidr_block(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPCCidrBlock.AmazonProvidedIpv6CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpccidrblock.html#cfn-ec2-vpccidrblock-amazonprovidedipv6cidrblock
        '''
        result = self._values.get("amazon_provided_ipv6_cidr_block")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def cidr_block(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCCidrBlock.CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpccidrblock.html#cfn-ec2-vpccidrblock-cidrblock
        '''
        result = self._values.get("cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPCCidrBlockProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPCDHCPOptionsAssociation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPCDHCPOptionsAssociation",
):
    '''A CloudFormation ``AWS::EC2::VPCDHCPOptionsAssociation``.

    :cloudformationResource: AWS::EC2::VPCDHCPOptionsAssociation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-dhcp-options-assoc.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        dhcp_options_id: builtins.str,
        vpc_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::VPCDHCPOptionsAssociation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param dhcp_options_id: ``AWS::EC2::VPCDHCPOptionsAssociation.DhcpOptionsId``.
        :param vpc_id: ``AWS::EC2::VPCDHCPOptionsAssociation.VpcId``.
        '''
        props = CfnVPCDHCPOptionsAssociationProps(
            dhcp_options_id=dhcp_options_id, vpc_id=vpc_id
        )

        jsii.create(CfnVPCDHCPOptionsAssociation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="dhcpOptionsId")
    def dhcp_options_id(self) -> builtins.str:
        '''``AWS::EC2::VPCDHCPOptionsAssociation.DhcpOptionsId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-dhcp-options-assoc.html#cfn-ec2-vpcdhcpoptionsassociation-dhcpoptionsid
        '''
        return typing.cast(builtins.str, jsii.get(self, "dhcpOptionsId"))

    @dhcp_options_id.setter
    def dhcp_options_id(self, value: builtins.str) -> None:
        jsii.set(self, "dhcpOptionsId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCDHCPOptionsAssociation.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-dhcp-options-assoc.html#cfn-ec2-vpcdhcpoptionsassociation-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPCDHCPOptionsAssociationProps",
    jsii_struct_bases=[],
    name_mapping={"dhcp_options_id": "dhcpOptionsId", "vpc_id": "vpcId"},
)
class CfnVPCDHCPOptionsAssociationProps:
    def __init__(self, *, dhcp_options_id: builtins.str, vpc_id: builtins.str) -> None:
        '''Properties for defining a ``AWS::EC2::VPCDHCPOptionsAssociation``.

        :param dhcp_options_id: ``AWS::EC2::VPCDHCPOptionsAssociation.DhcpOptionsId``.
        :param vpc_id: ``AWS::EC2::VPCDHCPOptionsAssociation.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-dhcp-options-assoc.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "dhcp_options_id": dhcp_options_id,
            "vpc_id": vpc_id,
        }

    @builtins.property
    def dhcp_options_id(self) -> builtins.str:
        '''``AWS::EC2::VPCDHCPOptionsAssociation.DhcpOptionsId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-dhcp-options-assoc.html#cfn-ec2-vpcdhcpoptionsassociation-dhcpoptionsid
        '''
        result = self._values.get("dhcp_options_id")
        assert result is not None, "Required property 'dhcp_options_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCDHCPOptionsAssociation.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-dhcp-options-assoc.html#cfn-ec2-vpcdhcpoptionsassociation-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPCDHCPOptionsAssociationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPCEndpoint(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPCEndpoint",
):
    '''A CloudFormation ``AWS::EC2::VPCEndpoint``.

    :cloudformationResource: AWS::EC2::VPCEndpoint
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        service_name: builtins.str,
        vpc_id: builtins.str,
        policy_document: typing.Any = None,
        private_dns_enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        route_table_ids: typing.Optional[typing.List[builtins.str]] = None,
        security_group_ids: typing.Optional[typing.List[builtins.str]] = None,
        subnet_ids: typing.Optional[typing.List[builtins.str]] = None,
        vpc_endpoint_type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::VPCEndpoint``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param service_name: ``AWS::EC2::VPCEndpoint.ServiceName``.
        :param vpc_id: ``AWS::EC2::VPCEndpoint.VpcId``.
        :param policy_document: ``AWS::EC2::VPCEndpoint.PolicyDocument``.
        :param private_dns_enabled: ``AWS::EC2::VPCEndpoint.PrivateDnsEnabled``.
        :param route_table_ids: ``AWS::EC2::VPCEndpoint.RouteTableIds``.
        :param security_group_ids: ``AWS::EC2::VPCEndpoint.SecurityGroupIds``.
        :param subnet_ids: ``AWS::EC2::VPCEndpoint.SubnetIds``.
        :param vpc_endpoint_type: ``AWS::EC2::VPCEndpoint.VpcEndpointType``.
        '''
        props = CfnVPCEndpointProps(
            service_name=service_name,
            vpc_id=vpc_id,
            policy_document=policy_document,
            private_dns_enabled=private_dns_enabled,
            route_table_ids=route_table_ids,
            security_group_ids=security_group_ids,
            subnet_ids=subnet_ids,
            vpc_endpoint_type=vpc_endpoint_type,
        )

        jsii.create(CfnVPCEndpoint, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrCreationTimestamp")
    def attr_creation_timestamp(self) -> builtins.str:
        '''
        :cloudformationAttribute: CreationTimestamp
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrCreationTimestamp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrDnsEntries")
    def attr_dns_entries(self) -> typing.List[builtins.str]:
        '''
        :cloudformationAttribute: DnsEntries
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "attrDnsEntries"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrNetworkInterfaceIds")
    def attr_network_interface_ids(self) -> typing.List[builtins.str]:
        '''
        :cloudformationAttribute: NetworkInterfaceIds
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "attrNetworkInterfaceIds"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="policyDocument")
    def policy_document(self) -> typing.Any:
        '''``AWS::EC2::VPCEndpoint.PolicyDocument``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-policydocument
        '''
        return typing.cast(typing.Any, jsii.get(self, "policyDocument"))

    @policy_document.setter
    def policy_document(self, value: typing.Any) -> None:
        jsii.set(self, "policyDocument", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="serviceName")
    def service_name(self) -> builtins.str:
        '''``AWS::EC2::VPCEndpoint.ServiceName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-servicename
        '''
        return typing.cast(builtins.str, jsii.get(self, "serviceName"))

    @service_name.setter
    def service_name(self, value: builtins.str) -> None:
        jsii.set(self, "serviceName", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCEndpoint.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateDnsEnabled")
    def private_dns_enabled(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPCEndpoint.PrivateDnsEnabled``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-privatednsenabled
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "privateDnsEnabled"))

    @private_dns_enabled.setter
    def private_dns_enabled(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "privateDnsEnabled", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="routeTableIds")
    def route_table_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpoint.RouteTableIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-routetableids
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "routeTableIds"))

    @route_table_ids.setter
    def route_table_ids(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "routeTableIds", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroupIds")
    def security_group_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpoint.SecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-securitygroupids
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "securityGroupIds"))

    @security_group_ids.setter
    def security_group_ids(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "securityGroupIds", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetIds")
    def subnet_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpoint.SubnetIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-subnetids
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "subnetIds"))

    @subnet_ids.setter
    def subnet_ids(self, value: typing.Optional[typing.List[builtins.str]]) -> None:
        jsii.set(self, "subnetIds", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointType")
    def vpc_endpoint_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCEndpoint.VpcEndpointType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-vpcendpointtype
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "vpcEndpointType"))

    @vpc_endpoint_type.setter
    def vpc_endpoint_type(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "vpcEndpointType", value)


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPCEndpointConnectionNotification(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPCEndpointConnectionNotification",
):
    '''A CloudFormation ``AWS::EC2::VPCEndpointConnectionNotification``.

    :cloudformationResource: AWS::EC2::VPCEndpointConnectionNotification
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointconnectionnotification.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        connection_events: typing.List[builtins.str],
        connection_notification_arn: builtins.str,
        service_id: typing.Optional[builtins.str] = None,
        vpc_endpoint_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::VPCEndpointConnectionNotification``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param connection_events: ``AWS::EC2::VPCEndpointConnectionNotification.ConnectionEvents``.
        :param connection_notification_arn: ``AWS::EC2::VPCEndpointConnectionNotification.ConnectionNotificationArn``.
        :param service_id: ``AWS::EC2::VPCEndpointConnectionNotification.ServiceId``.
        :param vpc_endpoint_id: ``AWS::EC2::VPCEndpointConnectionNotification.VPCEndpointId``.
        '''
        props = CfnVPCEndpointConnectionNotificationProps(
            connection_events=connection_events,
            connection_notification_arn=connection_notification_arn,
            service_id=service_id,
            vpc_endpoint_id=vpc_endpoint_id,
        )

        jsii.create(CfnVPCEndpointConnectionNotification, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connectionEvents")
    def connection_events(self) -> typing.List[builtins.str]:
        '''``AWS::EC2::VPCEndpointConnectionNotification.ConnectionEvents``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointconnectionnotification.html#cfn-ec2-vpcendpointconnectionnotification-connectionevents
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "connectionEvents"))

    @connection_events.setter
    def connection_events(self, value: typing.List[builtins.str]) -> None:
        jsii.set(self, "connectionEvents", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connectionNotificationArn")
    def connection_notification_arn(self) -> builtins.str:
        '''``AWS::EC2::VPCEndpointConnectionNotification.ConnectionNotificationArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointconnectionnotification.html#cfn-ec2-vpcendpointconnectionnotification-connectionnotificationarn
        '''
        return typing.cast(builtins.str, jsii.get(self, "connectionNotificationArn"))

    @connection_notification_arn.setter
    def connection_notification_arn(self, value: builtins.str) -> None:
        jsii.set(self, "connectionNotificationArn", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="serviceId")
    def service_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCEndpointConnectionNotification.ServiceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointconnectionnotification.html#cfn-ec2-vpcendpointconnectionnotification-serviceid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "serviceId"))

    @service_id.setter
    def service_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "serviceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointId")
    def vpc_endpoint_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCEndpointConnectionNotification.VPCEndpointId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointconnectionnotification.html#cfn-ec2-vpcendpointconnectionnotification-vpcendpointid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "vpcEndpointId"))

    @vpc_endpoint_id.setter
    def vpc_endpoint_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "vpcEndpointId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPCEndpointConnectionNotificationProps",
    jsii_struct_bases=[],
    name_mapping={
        "connection_events": "connectionEvents",
        "connection_notification_arn": "connectionNotificationArn",
        "service_id": "serviceId",
        "vpc_endpoint_id": "vpcEndpointId",
    },
)
class CfnVPCEndpointConnectionNotificationProps:
    def __init__(
        self,
        *,
        connection_events: typing.List[builtins.str],
        connection_notification_arn: builtins.str,
        service_id: typing.Optional[builtins.str] = None,
        vpc_endpoint_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPCEndpointConnectionNotification``.

        :param connection_events: ``AWS::EC2::VPCEndpointConnectionNotification.ConnectionEvents``.
        :param connection_notification_arn: ``AWS::EC2::VPCEndpointConnectionNotification.ConnectionNotificationArn``.
        :param service_id: ``AWS::EC2::VPCEndpointConnectionNotification.ServiceId``.
        :param vpc_endpoint_id: ``AWS::EC2::VPCEndpointConnectionNotification.VPCEndpointId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointconnectionnotification.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "connection_events": connection_events,
            "connection_notification_arn": connection_notification_arn,
        }
        if service_id is not None:
            self._values["service_id"] = service_id
        if vpc_endpoint_id is not None:
            self._values["vpc_endpoint_id"] = vpc_endpoint_id

    @builtins.property
    def connection_events(self) -> typing.List[builtins.str]:
        '''``AWS::EC2::VPCEndpointConnectionNotification.ConnectionEvents``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointconnectionnotification.html#cfn-ec2-vpcendpointconnectionnotification-connectionevents
        '''
        result = self._values.get("connection_events")
        assert result is not None, "Required property 'connection_events' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def connection_notification_arn(self) -> builtins.str:
        '''``AWS::EC2::VPCEndpointConnectionNotification.ConnectionNotificationArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointconnectionnotification.html#cfn-ec2-vpcendpointconnectionnotification-connectionnotificationarn
        '''
        result = self._values.get("connection_notification_arn")
        assert result is not None, "Required property 'connection_notification_arn' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def service_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCEndpointConnectionNotification.ServiceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointconnectionnotification.html#cfn-ec2-vpcendpointconnectionnotification-serviceid
        '''
        result = self._values.get("service_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vpc_endpoint_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCEndpointConnectionNotification.VPCEndpointId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointconnectionnotification.html#cfn-ec2-vpcendpointconnectionnotification-vpcendpointid
        '''
        result = self._values.get("vpc_endpoint_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPCEndpointConnectionNotificationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPCEndpointProps",
    jsii_struct_bases=[],
    name_mapping={
        "service_name": "serviceName",
        "vpc_id": "vpcId",
        "policy_document": "policyDocument",
        "private_dns_enabled": "privateDnsEnabled",
        "route_table_ids": "routeTableIds",
        "security_group_ids": "securityGroupIds",
        "subnet_ids": "subnetIds",
        "vpc_endpoint_type": "vpcEndpointType",
    },
)
class CfnVPCEndpointProps:
    def __init__(
        self,
        *,
        service_name: builtins.str,
        vpc_id: builtins.str,
        policy_document: typing.Any = None,
        private_dns_enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        route_table_ids: typing.Optional[typing.List[builtins.str]] = None,
        security_group_ids: typing.Optional[typing.List[builtins.str]] = None,
        subnet_ids: typing.Optional[typing.List[builtins.str]] = None,
        vpc_endpoint_type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPCEndpoint``.

        :param service_name: ``AWS::EC2::VPCEndpoint.ServiceName``.
        :param vpc_id: ``AWS::EC2::VPCEndpoint.VpcId``.
        :param policy_document: ``AWS::EC2::VPCEndpoint.PolicyDocument``.
        :param private_dns_enabled: ``AWS::EC2::VPCEndpoint.PrivateDnsEnabled``.
        :param route_table_ids: ``AWS::EC2::VPCEndpoint.RouteTableIds``.
        :param security_group_ids: ``AWS::EC2::VPCEndpoint.SecurityGroupIds``.
        :param subnet_ids: ``AWS::EC2::VPCEndpoint.SubnetIds``.
        :param vpc_endpoint_type: ``AWS::EC2::VPCEndpoint.VpcEndpointType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "service_name": service_name,
            "vpc_id": vpc_id,
        }
        if policy_document is not None:
            self._values["policy_document"] = policy_document
        if private_dns_enabled is not None:
            self._values["private_dns_enabled"] = private_dns_enabled
        if route_table_ids is not None:
            self._values["route_table_ids"] = route_table_ids
        if security_group_ids is not None:
            self._values["security_group_ids"] = security_group_ids
        if subnet_ids is not None:
            self._values["subnet_ids"] = subnet_ids
        if vpc_endpoint_type is not None:
            self._values["vpc_endpoint_type"] = vpc_endpoint_type

    @builtins.property
    def service_name(self) -> builtins.str:
        '''``AWS::EC2::VPCEndpoint.ServiceName``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-servicename
        '''
        result = self._values.get("service_name")
        assert result is not None, "Required property 'service_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCEndpoint.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def policy_document(self) -> typing.Any:
        '''``AWS::EC2::VPCEndpoint.PolicyDocument``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-policydocument
        '''
        result = self._values.get("policy_document")
        return typing.cast(typing.Any, result)

    @builtins.property
    def private_dns_enabled(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPCEndpoint.PrivateDnsEnabled``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-privatednsenabled
        '''
        result = self._values.get("private_dns_enabled")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def route_table_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpoint.RouteTableIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-routetableids
        '''
        result = self._values.get("route_table_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def security_group_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpoint.SecurityGroupIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-securitygroupids
        '''
        result = self._values.get("security_group_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def subnet_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpoint.SubnetIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-subnetids
        '''
        result = self._values.get("subnet_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def vpc_endpoint_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCEndpoint.VpcEndpointType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpoint.html#cfn-ec2-vpcendpoint-vpcendpointtype
        '''
        result = self._values.get("vpc_endpoint_type")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPCEndpointProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPCEndpointService(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPCEndpointService",
):
    '''A CloudFormation ``AWS::EC2::VPCEndpointService``.

    :cloudformationResource: AWS::EC2::VPCEndpointService
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservice.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        acceptance_required: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        gateway_load_balancer_arns: typing.Optional[typing.List[builtins.str]] = None,
        network_load_balancer_arns: typing.Optional[typing.List[builtins.str]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::VPCEndpointService``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param acceptance_required: ``AWS::EC2::VPCEndpointService.AcceptanceRequired``.
        :param gateway_load_balancer_arns: ``AWS::EC2::VPCEndpointService.GatewayLoadBalancerArns``.
        :param network_load_balancer_arns: ``AWS::EC2::VPCEndpointService.NetworkLoadBalancerArns``.
        '''
        props = CfnVPCEndpointServiceProps(
            acceptance_required=acceptance_required,
            gateway_load_balancer_arns=gateway_load_balancer_arns,
            network_load_balancer_arns=network_load_balancer_arns,
        )

        jsii.create(CfnVPCEndpointService, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="acceptanceRequired")
    def acceptance_required(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPCEndpointService.AcceptanceRequired``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservice.html#cfn-ec2-vpcendpointservice-acceptancerequired
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "acceptanceRequired"))

    @acceptance_required.setter
    def acceptance_required(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "acceptanceRequired", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="gatewayLoadBalancerArns")
    def gateway_load_balancer_arns(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpointService.GatewayLoadBalancerArns``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservice.html#cfn-ec2-vpcendpointservice-gatewayloadbalancerarns
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "gatewayLoadBalancerArns"))

    @gateway_load_balancer_arns.setter
    def gateway_load_balancer_arns(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "gatewayLoadBalancerArns", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkLoadBalancerArns")
    def network_load_balancer_arns(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpointService.NetworkLoadBalancerArns``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservice.html#cfn-ec2-vpcendpointservice-networkloadbalancerarns
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "networkLoadBalancerArns"))

    @network_load_balancer_arns.setter
    def network_load_balancer_arns(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "networkLoadBalancerArns", value)


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPCEndpointServicePermissions(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPCEndpointServicePermissions",
):
    '''A CloudFormation ``AWS::EC2::VPCEndpointServicePermissions``.

    :cloudformationResource: AWS::EC2::VPCEndpointServicePermissions
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservicepermissions.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        service_id: builtins.str,
        allowed_principals: typing.Optional[typing.List[builtins.str]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::VPCEndpointServicePermissions``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param service_id: ``AWS::EC2::VPCEndpointServicePermissions.ServiceId``.
        :param allowed_principals: ``AWS::EC2::VPCEndpointServicePermissions.AllowedPrincipals``.
        '''
        props = CfnVPCEndpointServicePermissionsProps(
            service_id=service_id, allowed_principals=allowed_principals
        )

        jsii.create(CfnVPCEndpointServicePermissions, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="serviceId")
    def service_id(self) -> builtins.str:
        '''``AWS::EC2::VPCEndpointServicePermissions.ServiceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservicepermissions.html#cfn-ec2-vpcendpointservicepermissions-serviceid
        '''
        return typing.cast(builtins.str, jsii.get(self, "serviceId"))

    @service_id.setter
    def service_id(self, value: builtins.str) -> None:
        jsii.set(self, "serviceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="allowedPrincipals")
    def allowed_principals(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpointServicePermissions.AllowedPrincipals``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservicepermissions.html#cfn-ec2-vpcendpointservicepermissions-allowedprincipals
        '''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "allowedPrincipals"))

    @allowed_principals.setter
    def allowed_principals(
        self,
        value: typing.Optional[typing.List[builtins.str]],
    ) -> None:
        jsii.set(self, "allowedPrincipals", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPCEndpointServicePermissionsProps",
    jsii_struct_bases=[],
    name_mapping={
        "service_id": "serviceId",
        "allowed_principals": "allowedPrincipals",
    },
)
class CfnVPCEndpointServicePermissionsProps:
    def __init__(
        self,
        *,
        service_id: builtins.str,
        allowed_principals: typing.Optional[typing.List[builtins.str]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPCEndpointServicePermissions``.

        :param service_id: ``AWS::EC2::VPCEndpointServicePermissions.ServiceId``.
        :param allowed_principals: ``AWS::EC2::VPCEndpointServicePermissions.AllowedPrincipals``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservicepermissions.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "service_id": service_id,
        }
        if allowed_principals is not None:
            self._values["allowed_principals"] = allowed_principals

    @builtins.property
    def service_id(self) -> builtins.str:
        '''``AWS::EC2::VPCEndpointServicePermissions.ServiceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservicepermissions.html#cfn-ec2-vpcendpointservicepermissions-serviceid
        '''
        result = self._values.get("service_id")
        assert result is not None, "Required property 'service_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def allowed_principals(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpointServicePermissions.AllowedPrincipals``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservicepermissions.html#cfn-ec2-vpcendpointservicepermissions-allowedprincipals
        '''
        result = self._values.get("allowed_principals")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPCEndpointServicePermissionsProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPCEndpointServiceProps",
    jsii_struct_bases=[],
    name_mapping={
        "acceptance_required": "acceptanceRequired",
        "gateway_load_balancer_arns": "gatewayLoadBalancerArns",
        "network_load_balancer_arns": "networkLoadBalancerArns",
    },
)
class CfnVPCEndpointServiceProps:
    def __init__(
        self,
        *,
        acceptance_required: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        gateway_load_balancer_arns: typing.Optional[typing.List[builtins.str]] = None,
        network_load_balancer_arns: typing.Optional[typing.List[builtins.str]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPCEndpointService``.

        :param acceptance_required: ``AWS::EC2::VPCEndpointService.AcceptanceRequired``.
        :param gateway_load_balancer_arns: ``AWS::EC2::VPCEndpointService.GatewayLoadBalancerArns``.
        :param network_load_balancer_arns: ``AWS::EC2::VPCEndpointService.NetworkLoadBalancerArns``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservice.html
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if acceptance_required is not None:
            self._values["acceptance_required"] = acceptance_required
        if gateway_load_balancer_arns is not None:
            self._values["gateway_load_balancer_arns"] = gateway_load_balancer_arns
        if network_load_balancer_arns is not None:
            self._values["network_load_balancer_arns"] = network_load_balancer_arns

    @builtins.property
    def acceptance_required(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPCEndpointService.AcceptanceRequired``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservice.html#cfn-ec2-vpcendpointservice-acceptancerequired
        '''
        result = self._values.get("acceptance_required")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def gateway_load_balancer_arns(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpointService.GatewayLoadBalancerArns``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservice.html#cfn-ec2-vpcendpointservice-gatewayloadbalancerarns
        '''
        result = self._values.get("gateway_load_balancer_arns")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def network_load_balancer_arns(self) -> typing.Optional[typing.List[builtins.str]]:
        '''``AWS::EC2::VPCEndpointService.NetworkLoadBalancerArns``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservice.html#cfn-ec2-vpcendpointservice-networkloadbalancerarns
        '''
        result = self._values.get("network_load_balancer_arns")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPCEndpointServiceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPCGatewayAttachment(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPCGatewayAttachment",
):
    '''A CloudFormation ``AWS::EC2::VPCGatewayAttachment``.

    :cloudformationResource: AWS::EC2::VPCGatewayAttachment
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        vpc_id: builtins.str,
        internet_gateway_id: typing.Optional[builtins.str] = None,
        vpn_gateway_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::VPCGatewayAttachment``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param vpc_id: ``AWS::EC2::VPCGatewayAttachment.VpcId``.
        :param internet_gateway_id: ``AWS::EC2::VPCGatewayAttachment.InternetGatewayId``.
        :param vpn_gateway_id: ``AWS::EC2::VPCGatewayAttachment.VpnGatewayId``.
        '''
        props = CfnVPCGatewayAttachmentProps(
            vpc_id=vpc_id,
            internet_gateway_id=internet_gateway_id,
            vpn_gateway_id=vpn_gateway_id,
        )

        jsii.create(CfnVPCGatewayAttachment, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCGatewayAttachment.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html#cfn-ec2-vpcgatewayattachment-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="internetGatewayId")
    def internet_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCGatewayAttachment.InternetGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html#cfn-ec2-vpcgatewayattachment-internetgatewayid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "internetGatewayId"))

    @internet_gateway_id.setter
    def internet_gateway_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "internetGatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnGatewayId")
    def vpn_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCGatewayAttachment.VpnGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html#cfn-ec2-vpcgatewayattachment-vpngatewayid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "vpnGatewayId"))

    @vpn_gateway_id.setter
    def vpn_gateway_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "vpnGatewayId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPCGatewayAttachmentProps",
    jsii_struct_bases=[],
    name_mapping={
        "vpc_id": "vpcId",
        "internet_gateway_id": "internetGatewayId",
        "vpn_gateway_id": "vpnGatewayId",
    },
)
class CfnVPCGatewayAttachmentProps:
    def __init__(
        self,
        *,
        vpc_id: builtins.str,
        internet_gateway_id: typing.Optional[builtins.str] = None,
        vpn_gateway_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPCGatewayAttachment``.

        :param vpc_id: ``AWS::EC2::VPCGatewayAttachment.VpcId``.
        :param internet_gateway_id: ``AWS::EC2::VPCGatewayAttachment.InternetGatewayId``.
        :param vpn_gateway_id: ``AWS::EC2::VPCGatewayAttachment.VpnGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "vpc_id": vpc_id,
        }
        if internet_gateway_id is not None:
            self._values["internet_gateway_id"] = internet_gateway_id
        if vpn_gateway_id is not None:
            self._values["vpn_gateway_id"] = vpn_gateway_id

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCGatewayAttachment.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html#cfn-ec2-vpcgatewayattachment-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def internet_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCGatewayAttachment.InternetGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html#cfn-ec2-vpcgatewayattachment-internetgatewayid
        '''
        result = self._values.get("internet_gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vpn_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCGatewayAttachment.VpnGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html#cfn-ec2-vpcgatewayattachment-vpngatewayid
        '''
        result = self._values.get("vpn_gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPCGatewayAttachmentProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPCPeeringConnection(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPCPeeringConnection",
):
    '''A CloudFormation ``AWS::EC2::VPCPeeringConnection``.

    :cloudformationResource: AWS::EC2::VPCPeeringConnection
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        peer_vpc_id: builtins.str,
        vpc_id: builtins.str,
        peer_owner_id: typing.Optional[builtins.str] = None,
        peer_region: typing.Optional[builtins.str] = None,
        peer_role_arn: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::VPCPeeringConnection``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param peer_vpc_id: ``AWS::EC2::VPCPeeringConnection.PeerVpcId``.
        :param vpc_id: ``AWS::EC2::VPCPeeringConnection.VpcId``.
        :param peer_owner_id: ``AWS::EC2::VPCPeeringConnection.PeerOwnerId``.
        :param peer_region: ``AWS::EC2::VPCPeeringConnection.PeerRegion``.
        :param peer_role_arn: ``AWS::EC2::VPCPeeringConnection.PeerRoleArn``.
        :param tags: ``AWS::EC2::VPCPeeringConnection.Tags``.
        '''
        props = CfnVPCPeeringConnectionProps(
            peer_vpc_id=peer_vpc_id,
            vpc_id=vpc_id,
            peer_owner_id=peer_owner_id,
            peer_region=peer_region,
            peer_role_arn=peer_role_arn,
            tags=tags,
        )

        jsii.create(CfnVPCPeeringConnection, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::VPCPeeringConnection.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="peerVpcId")
    def peer_vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCPeeringConnection.PeerVpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-peervpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "peerVpcId"))

    @peer_vpc_id.setter
    def peer_vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "peerVpcId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCPeeringConnection.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-vpcid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @vpc_id.setter
    def vpc_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpcId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="peerOwnerId")
    def peer_owner_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCPeeringConnection.PeerOwnerId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-peerownerid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "peerOwnerId"))

    @peer_owner_id.setter
    def peer_owner_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "peerOwnerId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="peerRegion")
    def peer_region(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCPeeringConnection.PeerRegion``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-peerregion
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "peerRegion"))

    @peer_region.setter
    def peer_region(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "peerRegion", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="peerRoleArn")
    def peer_role_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCPeeringConnection.PeerRoleArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-peerrolearn
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "peerRoleArn"))

    @peer_role_arn.setter
    def peer_role_arn(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "peerRoleArn", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPCPeeringConnectionProps",
    jsii_struct_bases=[],
    name_mapping={
        "peer_vpc_id": "peerVpcId",
        "vpc_id": "vpcId",
        "peer_owner_id": "peerOwnerId",
        "peer_region": "peerRegion",
        "peer_role_arn": "peerRoleArn",
        "tags": "tags",
    },
)
class CfnVPCPeeringConnectionProps:
    def __init__(
        self,
        *,
        peer_vpc_id: builtins.str,
        vpc_id: builtins.str,
        peer_owner_id: typing.Optional[builtins.str] = None,
        peer_region: typing.Optional[builtins.str] = None,
        peer_role_arn: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPCPeeringConnection``.

        :param peer_vpc_id: ``AWS::EC2::VPCPeeringConnection.PeerVpcId``.
        :param vpc_id: ``AWS::EC2::VPCPeeringConnection.VpcId``.
        :param peer_owner_id: ``AWS::EC2::VPCPeeringConnection.PeerOwnerId``.
        :param peer_region: ``AWS::EC2::VPCPeeringConnection.PeerRegion``.
        :param peer_role_arn: ``AWS::EC2::VPCPeeringConnection.PeerRoleArn``.
        :param tags: ``AWS::EC2::VPCPeeringConnection.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "peer_vpc_id": peer_vpc_id,
            "vpc_id": vpc_id,
        }
        if peer_owner_id is not None:
            self._values["peer_owner_id"] = peer_owner_id
        if peer_region is not None:
            self._values["peer_region"] = peer_region
        if peer_role_arn is not None:
            self._values["peer_role_arn"] = peer_role_arn
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def peer_vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCPeeringConnection.PeerVpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-peervpcid
        '''
        result = self._values.get("peer_vpc_id")
        assert result is not None, "Required property 'peer_vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''``AWS::EC2::VPCPeeringConnection.VpcId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-vpcid
        '''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def peer_owner_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCPeeringConnection.PeerOwnerId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-peerownerid
        '''
        result = self._values.get("peer_owner_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def peer_region(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCPeeringConnection.PeerRegion``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-peerregion
        '''
        result = self._values.get("peer_region")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def peer_role_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPCPeeringConnection.PeerRoleArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-peerrolearn
        '''
        result = self._values.get("peer_role_arn")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::VPCPeeringConnection.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcpeeringconnection.html#cfn-ec2-vpcpeeringconnection-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPCPeeringConnectionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPCProps",
    jsii_struct_bases=[],
    name_mapping={
        "cidr_block": "cidrBlock",
        "enable_dns_hostnames": "enableDnsHostnames",
        "enable_dns_support": "enableDnsSupport",
        "instance_tenancy": "instanceTenancy",
        "tags": "tags",
    },
)
class CfnVPCProps:
    def __init__(
        self,
        *,
        cidr_block: builtins.str,
        enable_dns_hostnames: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        enable_dns_support: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        instance_tenancy: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPC``.

        :param cidr_block: ``AWS::EC2::VPC.CidrBlock``.
        :param enable_dns_hostnames: ``AWS::EC2::VPC.EnableDnsHostnames``.
        :param enable_dns_support: ``AWS::EC2::VPC.EnableDnsSupport``.
        :param instance_tenancy: ``AWS::EC2::VPC.InstanceTenancy``.
        :param tags: ``AWS::EC2::VPC.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cidr_block": cidr_block,
        }
        if enable_dns_hostnames is not None:
            self._values["enable_dns_hostnames"] = enable_dns_hostnames
        if enable_dns_support is not None:
            self._values["enable_dns_support"] = enable_dns_support
        if instance_tenancy is not None:
            self._values["instance_tenancy"] = instance_tenancy
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def cidr_block(self) -> builtins.str:
        '''``AWS::EC2::VPC.CidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html#cfn-aws-ec2-vpc-cidrblock
        '''
        result = self._values.get("cidr_block")
        assert result is not None, "Required property 'cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def enable_dns_hostnames(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPC.EnableDnsHostnames``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html#cfn-aws-ec2-vpc-EnableDnsHostnames
        '''
        result = self._values.get("enable_dns_hostnames")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def enable_dns_support(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPC.EnableDnsSupport``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html#cfn-aws-ec2-vpc-EnableDnsSupport
        '''
        result = self._values.get("enable_dns_support")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def instance_tenancy(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPC.InstanceTenancy``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html#cfn-aws-ec2-vpc-instancetenancy
        '''
        result = self._values.get("instance_tenancy")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::VPC.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html#cfn-aws-ec2-vpc-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPCProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPNConnection(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPNConnection",
):
    '''A CloudFormation ``AWS::EC2::VPNConnection``.

    :cloudformationResource: AWS::EC2::VPNConnection
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        customer_gateway_id: builtins.str,
        type: builtins.str,
        static_routes_only: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        transit_gateway_id: typing.Optional[builtins.str] = None,
        vpn_gateway_id: typing.Optional[builtins.str] = None,
        vpn_tunnel_options_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVPNConnection.VpnTunnelOptionsSpecificationProperty"]]]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::VPNConnection``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param customer_gateway_id: ``AWS::EC2::VPNConnection.CustomerGatewayId``.
        :param type: ``AWS::EC2::VPNConnection.Type``.
        :param static_routes_only: ``AWS::EC2::VPNConnection.StaticRoutesOnly``.
        :param tags: ``AWS::EC2::VPNConnection.Tags``.
        :param transit_gateway_id: ``AWS::EC2::VPNConnection.TransitGatewayId``.
        :param vpn_gateway_id: ``AWS::EC2::VPNConnection.VpnGatewayId``.
        :param vpn_tunnel_options_specifications: ``AWS::EC2::VPNConnection.VpnTunnelOptionsSpecifications``.
        '''
        props = CfnVPNConnectionProps(
            customer_gateway_id=customer_gateway_id,
            type=type,
            static_routes_only=static_routes_only,
            tags=tags,
            transit_gateway_id=transit_gateway_id,
            vpn_gateway_id=vpn_gateway_id,
            vpn_tunnel_options_specifications=vpn_tunnel_options_specifications,
        )

        jsii.create(CfnVPNConnection, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::VPNConnection.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="customerGatewayId")
    def customer_gateway_id(self) -> builtins.str:
        '''``AWS::EC2::VPNConnection.CustomerGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-customergatewayid
        '''
        return typing.cast(builtins.str, jsii.get(self, "customerGatewayId"))

    @customer_gateway_id.setter
    def customer_gateway_id(self, value: builtins.str) -> None:
        jsii.set(self, "customerGatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="type")
    def type(self) -> builtins.str:
        '''``AWS::EC2::VPNConnection.Type``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-type
        '''
        return typing.cast(builtins.str, jsii.get(self, "type"))

    @type.setter
    def type(self, value: builtins.str) -> None:
        jsii.set(self, "type", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="staticRoutesOnly")
    def static_routes_only(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPNConnection.StaticRoutesOnly``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-StaticRoutesOnly
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "staticRoutesOnly"))

    @static_routes_only.setter
    def static_routes_only(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "staticRoutesOnly", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="transitGatewayId")
    def transit_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPNConnection.TransitGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-transitgatewayid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "transitGatewayId"))

    @transit_gateway_id.setter
    def transit_gateway_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "transitGatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnGatewayId")
    def vpn_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPNConnection.VpnGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-vpngatewayid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "vpnGatewayId"))

    @vpn_gateway_id.setter
    def vpn_gateway_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "vpnGatewayId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnTunnelOptionsSpecifications")
    def vpn_tunnel_options_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVPNConnection.VpnTunnelOptionsSpecificationProperty"]]]]:
        '''``AWS::EC2::VPNConnection.VpnTunnelOptionsSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-vpntunneloptionsspecifications
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVPNConnection.VpnTunnelOptionsSpecificationProperty"]]]], jsii.get(self, "vpnTunnelOptionsSpecifications"))

    @vpn_tunnel_options_specifications.setter
    def vpn_tunnel_options_specifications(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnVPNConnection.VpnTunnelOptionsSpecificationProperty"]]]],
    ) -> None:
        jsii.set(self, "vpnTunnelOptionsSpecifications", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-ec2.CfnVPNConnection.VpnTunnelOptionsSpecificationProperty",
        jsii_struct_bases=[],
        name_mapping={
            "pre_shared_key": "preSharedKey",
            "tunnel_inside_cidr": "tunnelInsideCidr",
        },
    )
    class VpnTunnelOptionsSpecificationProperty:
        def __init__(
            self,
            *,
            pre_shared_key: typing.Optional[builtins.str] = None,
            tunnel_inside_cidr: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param pre_shared_key: ``CfnVPNConnection.VpnTunnelOptionsSpecificationProperty.PreSharedKey``.
            :param tunnel_inside_cidr: ``CfnVPNConnection.VpnTunnelOptionsSpecificationProperty.TunnelInsideCidr``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-vpnconnection-vpntunneloptionsspecification.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if pre_shared_key is not None:
                self._values["pre_shared_key"] = pre_shared_key
            if tunnel_inside_cidr is not None:
                self._values["tunnel_inside_cidr"] = tunnel_inside_cidr

        @builtins.property
        def pre_shared_key(self) -> typing.Optional[builtins.str]:
            '''``CfnVPNConnection.VpnTunnelOptionsSpecificationProperty.PreSharedKey``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-vpnconnection-vpntunneloptionsspecification.html#cfn-ec2-vpnconnection-vpntunneloptionsspecification-presharedkey
            '''
            result = self._values.get("pre_shared_key")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def tunnel_inside_cidr(self) -> typing.Optional[builtins.str]:
            '''``CfnVPNConnection.VpnTunnelOptionsSpecificationProperty.TunnelInsideCidr``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-vpnconnection-vpntunneloptionsspecification.html#cfn-ec2-vpnconnection-vpntunneloptionsspecification-tunnelinsidecidr
            '''
            result = self._values.get("tunnel_inside_cidr")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "VpnTunnelOptionsSpecificationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPNConnectionProps",
    jsii_struct_bases=[],
    name_mapping={
        "customer_gateway_id": "customerGatewayId",
        "type": "type",
        "static_routes_only": "staticRoutesOnly",
        "tags": "tags",
        "transit_gateway_id": "transitGatewayId",
        "vpn_gateway_id": "vpnGatewayId",
        "vpn_tunnel_options_specifications": "vpnTunnelOptionsSpecifications",
    },
)
class CfnVPNConnectionProps:
    def __init__(
        self,
        *,
        customer_gateway_id: builtins.str,
        type: builtins.str,
        static_routes_only: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        transit_gateway_id: typing.Optional[builtins.str] = None,
        vpn_gateway_id: typing.Optional[builtins.str] = None,
        vpn_tunnel_options_specifications: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnVPNConnection.VpnTunnelOptionsSpecificationProperty]]]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPNConnection``.

        :param customer_gateway_id: ``AWS::EC2::VPNConnection.CustomerGatewayId``.
        :param type: ``AWS::EC2::VPNConnection.Type``.
        :param static_routes_only: ``AWS::EC2::VPNConnection.StaticRoutesOnly``.
        :param tags: ``AWS::EC2::VPNConnection.Tags``.
        :param transit_gateway_id: ``AWS::EC2::VPNConnection.TransitGatewayId``.
        :param vpn_gateway_id: ``AWS::EC2::VPNConnection.VpnGatewayId``.
        :param vpn_tunnel_options_specifications: ``AWS::EC2::VPNConnection.VpnTunnelOptionsSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "customer_gateway_id": customer_gateway_id,
            "type": type,
        }
        if static_routes_only is not None:
            self._values["static_routes_only"] = static_routes_only
        if tags is not None:
            self._values["tags"] = tags
        if transit_gateway_id is not None:
            self._values["transit_gateway_id"] = transit_gateway_id
        if vpn_gateway_id is not None:
            self._values["vpn_gateway_id"] = vpn_gateway_id
        if vpn_tunnel_options_specifications is not None:
            self._values["vpn_tunnel_options_specifications"] = vpn_tunnel_options_specifications

    @builtins.property
    def customer_gateway_id(self) -> builtins.str:
        '''``AWS::EC2::VPNConnection.CustomerGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-customergatewayid
        '''
        result = self._values.get("customer_gateway_id")
        assert result is not None, "Required property 'customer_gateway_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def type(self) -> builtins.str:
        '''``AWS::EC2::VPNConnection.Type``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def static_routes_only(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::VPNConnection.StaticRoutesOnly``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-StaticRoutesOnly
        '''
        result = self._values.get("static_routes_only")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::VPNConnection.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    @builtins.property
    def transit_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPNConnection.TransitGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-transitgatewayid
        '''
        result = self._values.get("transit_gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vpn_gateway_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::VPNConnection.VpnGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-vpngatewayid
        '''
        result = self._values.get("vpn_gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vpn_tunnel_options_specifications(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnVPNConnection.VpnTunnelOptionsSpecificationProperty]]]]:
        '''``AWS::EC2::VPNConnection.VpnTunnelOptionsSpecifications``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection.html#cfn-ec2-vpnconnection-vpntunneloptionsspecifications
        '''
        result = self._values.get("vpn_tunnel_options_specifications")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnVPNConnection.VpnTunnelOptionsSpecificationProperty]]]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPNConnectionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPNConnectionRoute(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPNConnectionRoute",
):
    '''A CloudFormation ``AWS::EC2::VPNConnectionRoute``.

    :cloudformationResource: AWS::EC2::VPNConnectionRoute
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection-route.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        destination_cidr_block: builtins.str,
        vpn_connection_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::VPNConnectionRoute``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param destination_cidr_block: ``AWS::EC2::VPNConnectionRoute.DestinationCidrBlock``.
        :param vpn_connection_id: ``AWS::EC2::VPNConnectionRoute.VpnConnectionId``.
        '''
        props = CfnVPNConnectionRouteProps(
            destination_cidr_block=destination_cidr_block,
            vpn_connection_id=vpn_connection_id,
        )

        jsii.create(CfnVPNConnectionRoute, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="destinationCidrBlock")
    def destination_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::VPNConnectionRoute.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection-route.html#cfn-ec2-vpnconnectionroute-cidrblock
        '''
        return typing.cast(builtins.str, jsii.get(self, "destinationCidrBlock"))

    @destination_cidr_block.setter
    def destination_cidr_block(self, value: builtins.str) -> None:
        jsii.set(self, "destinationCidrBlock", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnConnectionId")
    def vpn_connection_id(self) -> builtins.str:
        '''``AWS::EC2::VPNConnectionRoute.VpnConnectionId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection-route.html#cfn-ec2-vpnconnectionroute-connectionid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpnConnectionId"))

    @vpn_connection_id.setter
    def vpn_connection_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpnConnectionId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPNConnectionRouteProps",
    jsii_struct_bases=[],
    name_mapping={
        "destination_cidr_block": "destinationCidrBlock",
        "vpn_connection_id": "vpnConnectionId",
    },
)
class CfnVPNConnectionRouteProps:
    def __init__(
        self,
        *,
        destination_cidr_block: builtins.str,
        vpn_connection_id: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPNConnectionRoute``.

        :param destination_cidr_block: ``AWS::EC2::VPNConnectionRoute.DestinationCidrBlock``.
        :param vpn_connection_id: ``AWS::EC2::VPNConnectionRoute.VpnConnectionId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection-route.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "destination_cidr_block": destination_cidr_block,
            "vpn_connection_id": vpn_connection_id,
        }

    @builtins.property
    def destination_cidr_block(self) -> builtins.str:
        '''``AWS::EC2::VPNConnectionRoute.DestinationCidrBlock``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection-route.html#cfn-ec2-vpnconnectionroute-cidrblock
        '''
        result = self._values.get("destination_cidr_block")
        assert result is not None, "Required property 'destination_cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def vpn_connection_id(self) -> builtins.str:
        '''``AWS::EC2::VPNConnectionRoute.VpnConnectionId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-connection-route.html#cfn-ec2-vpnconnectionroute-connectionid
        '''
        result = self._values.get("vpn_connection_id")
        assert result is not None, "Required property 'vpn_connection_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPNConnectionRouteProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPNGateway(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPNGateway",
):
    '''A CloudFormation ``AWS::EC2::VPNGateway``.

    :cloudformationResource: AWS::EC2::VPNGateway
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gateway.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        type: builtins.str,
        amazon_side_asn: typing.Optional[jsii.Number] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::VPNGateway``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param type: ``AWS::EC2::VPNGateway.Type``.
        :param amazon_side_asn: ``AWS::EC2::VPNGateway.AmazonSideAsn``.
        :param tags: ``AWS::EC2::VPNGateway.Tags``.
        '''
        props = CfnVPNGatewayProps(
            type=type, amazon_side_asn=amazon_side_asn, tags=tags
        )

        jsii.create(CfnVPNGateway, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::VPNGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gateway.html#cfn-ec2-vpngateway-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="type")
    def type(self) -> builtins.str:
        '''``AWS::EC2::VPNGateway.Type``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gateway.html#cfn-ec2-vpngateway-type
        '''
        return typing.cast(builtins.str, jsii.get(self, "type"))

    @type.setter
    def type(self, value: builtins.str) -> None:
        jsii.set(self, "type", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="amazonSideAsn")
    def amazon_side_asn(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::VPNGateway.AmazonSideAsn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gateway.html#cfn-ec2-vpngateway-amazonsideasn
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "amazonSideAsn"))

    @amazon_side_asn.setter
    def amazon_side_asn(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "amazonSideAsn", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPNGatewayProps",
    jsii_struct_bases=[],
    name_mapping={"type": "type", "amazon_side_asn": "amazonSideAsn", "tags": "tags"},
)
class CfnVPNGatewayProps:
    def __init__(
        self,
        *,
        type: builtins.str,
        amazon_side_asn: typing.Optional[jsii.Number] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPNGateway``.

        :param type: ``AWS::EC2::VPNGateway.Type``.
        :param amazon_side_asn: ``AWS::EC2::VPNGateway.AmazonSideAsn``.
        :param tags: ``AWS::EC2::VPNGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gateway.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if amazon_side_asn is not None:
            self._values["amazon_side_asn"] = amazon_side_asn
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def type(self) -> builtins.str:
        '''``AWS::EC2::VPNGateway.Type``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gateway.html#cfn-ec2-vpngateway-type
        '''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def amazon_side_asn(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::VPNGateway.AmazonSideAsn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gateway.html#cfn-ec2-vpngateway-amazonsideasn
        '''
        result = self._values.get("amazon_side_asn")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::VPNGateway.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gateway.html#cfn-ec2-vpngateway-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPNGatewayProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVPNGatewayRoutePropagation(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVPNGatewayRoutePropagation",
):
    '''A CloudFormation ``AWS::EC2::VPNGatewayRoutePropagation``.

    :cloudformationResource: AWS::EC2::VPNGatewayRoutePropagation
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gatewayrouteprop.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        route_table_ids: typing.List[builtins.str],
        vpn_gateway_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::VPNGatewayRoutePropagation``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param route_table_ids: ``AWS::EC2::VPNGatewayRoutePropagation.RouteTableIds``.
        :param vpn_gateway_id: ``AWS::EC2::VPNGatewayRoutePropagation.VpnGatewayId``.
        '''
        props = CfnVPNGatewayRoutePropagationProps(
            route_table_ids=route_table_ids, vpn_gateway_id=vpn_gateway_id
        )

        jsii.create(CfnVPNGatewayRoutePropagation, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="routeTableIds")
    def route_table_ids(self) -> typing.List[builtins.str]:
        '''``AWS::EC2::VPNGatewayRoutePropagation.RouteTableIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gatewayrouteprop.html#cfn-ec2-vpngatewayrouteprop-routetableids
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "routeTableIds"))

    @route_table_ids.setter
    def route_table_ids(self, value: typing.List[builtins.str]) -> None:
        jsii.set(self, "routeTableIds", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnGatewayId")
    def vpn_gateway_id(self) -> builtins.str:
        '''``AWS::EC2::VPNGatewayRoutePropagation.VpnGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gatewayrouteprop.html#cfn-ec2-vpngatewayrouteprop-vpngatewayid
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpnGatewayId"))

    @vpn_gateway_id.setter
    def vpn_gateway_id(self, value: builtins.str) -> None:
        jsii.set(self, "vpnGatewayId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVPNGatewayRoutePropagationProps",
    jsii_struct_bases=[],
    name_mapping={
        "route_table_ids": "routeTableIds",
        "vpn_gateway_id": "vpnGatewayId",
    },
)
class CfnVPNGatewayRoutePropagationProps:
    def __init__(
        self,
        *,
        route_table_ids: typing.List[builtins.str],
        vpn_gateway_id: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VPNGatewayRoutePropagation``.

        :param route_table_ids: ``AWS::EC2::VPNGatewayRoutePropagation.RouteTableIds``.
        :param vpn_gateway_id: ``AWS::EC2::VPNGatewayRoutePropagation.VpnGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gatewayrouteprop.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "route_table_ids": route_table_ids,
            "vpn_gateway_id": vpn_gateway_id,
        }

    @builtins.property
    def route_table_ids(self) -> typing.List[builtins.str]:
        '''``AWS::EC2::VPNGatewayRoutePropagation.RouteTableIds``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gatewayrouteprop.html#cfn-ec2-vpngatewayrouteprop-routetableids
        '''
        result = self._values.get("route_table_ids")
        assert result is not None, "Required property 'route_table_ids' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def vpn_gateway_id(self) -> builtins.str:
        '''``AWS::EC2::VPNGatewayRoutePropagation.VpnGatewayId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpn-gatewayrouteprop.html#cfn-ec2-vpngatewayrouteprop-vpngatewayid
        '''
        result = self._values.get("vpn_gateway_id")
        assert result is not None, "Required property 'vpn_gateway_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVPNGatewayRoutePropagationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVolume(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVolume",
):
    '''A CloudFormation ``AWS::EC2::Volume``.

    :cloudformationResource: AWS::EC2::Volume
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        availability_zone: builtins.str,
        auto_enable_io: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        encrypted: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        iops: typing.Optional[jsii.Number] = None,
        kms_key_id: typing.Optional[builtins.str] = None,
        multi_attach_enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        outpost_arn: typing.Optional[builtins.str] = None,
        size: typing.Optional[jsii.Number] = None,
        snapshot_id: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        throughput: typing.Optional[jsii.Number] = None,
        volume_type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Create a new ``AWS::EC2::Volume``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param availability_zone: ``AWS::EC2::Volume.AvailabilityZone``.
        :param auto_enable_io: ``AWS::EC2::Volume.AutoEnableIO``.
        :param encrypted: ``AWS::EC2::Volume.Encrypted``.
        :param iops: ``AWS::EC2::Volume.Iops``.
        :param kms_key_id: ``AWS::EC2::Volume.KmsKeyId``.
        :param multi_attach_enabled: ``AWS::EC2::Volume.MultiAttachEnabled``.
        :param outpost_arn: ``AWS::EC2::Volume.OutpostArn``.
        :param size: ``AWS::EC2::Volume.Size``.
        :param snapshot_id: ``AWS::EC2::Volume.SnapshotId``.
        :param tags: ``AWS::EC2::Volume.Tags``.
        :param throughput: ``AWS::EC2::Volume.Throughput``.
        :param volume_type: ``AWS::EC2::Volume.VolumeType``.
        '''
        props = CfnVolumeProps(
            availability_zone=availability_zone,
            auto_enable_io=auto_enable_io,
            encrypted=encrypted,
            iops=iops,
            kms_key_id=kms_key_id,
            multi_attach_enabled=multi_attach_enabled,
            outpost_arn=outpost_arn,
            size=size,
            snapshot_id=snapshot_id,
            tags=tags,
            throughput=throughput,
            volume_type=volume_type,
        )

        jsii.create(CfnVolume, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::EC2::Volume.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> builtins.str:
        '''``AWS::EC2::Volume.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-availabilityzone
        '''
        return typing.cast(builtins.str, jsii.get(self, "availabilityZone"))

    @availability_zone.setter
    def availability_zone(self, value: builtins.str) -> None:
        jsii.set(self, "availabilityZone", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="autoEnableIo")
    def auto_enable_io(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Volume.AutoEnableIO``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-autoenableio
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "autoEnableIo"))

    @auto_enable_io.setter
    def auto_enable_io(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "autoEnableIo", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="encrypted")
    def encrypted(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Volume.Encrypted``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-encrypted
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "encrypted"))

    @encrypted.setter
    def encrypted(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "encrypted", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="iops")
    def iops(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::Volume.Iops``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-iops
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "iops"))

    @iops.setter
    def iops(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "iops", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="kmsKeyId")
    def kms_key_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Volume.KmsKeyId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-kmskeyid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "kmsKeyId"))

    @kms_key_id.setter
    def kms_key_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "kmsKeyId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="multiAttachEnabled")
    def multi_attach_enabled(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Volume.MultiAttachEnabled``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-multiattachenabled
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "multiAttachEnabled"))

    @multi_attach_enabled.setter
    def multi_attach_enabled(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "multiAttachEnabled", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="outpostArn")
    def outpost_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Volume.OutpostArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-outpostarn
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "outpostArn"))

    @outpost_arn.setter
    def outpost_arn(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "outpostArn", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="size")
    def size(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::Volume.Size``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-size
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "size"))

    @size.setter
    def size(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "size", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="snapshotId")
    def snapshot_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Volume.SnapshotId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-snapshotid
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "snapshotId"))

    @snapshot_id.setter
    def snapshot_id(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "snapshotId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="throughput")
    def throughput(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::Volume.Throughput``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-throughput
        '''
        return typing.cast(typing.Optional[jsii.Number], jsii.get(self, "throughput"))

    @throughput.setter
    def throughput(self, value: typing.Optional[jsii.Number]) -> None:
        jsii.set(self, "throughput", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="volumeType")
    def volume_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Volume.VolumeType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-volumetype
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "volumeType"))

    @volume_type.setter
    def volume_type(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "volumeType", value)


@jsii.implements(aws_cdk.core.IInspectable)
class CfnVolumeAttachment(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CfnVolumeAttachment",
):
    '''A CloudFormation ``AWS::EC2::VolumeAttachment``.

    :cloudformationResource: AWS::EC2::VolumeAttachment
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volumeattachment.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        device: builtins.str,
        instance_id: builtins.str,
        volume_id: builtins.str,
    ) -> None:
        '''Create a new ``AWS::EC2::VolumeAttachment``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param device: ``AWS::EC2::VolumeAttachment.Device``.
        :param instance_id: ``AWS::EC2::VolumeAttachment.InstanceId``.
        :param volume_id: ``AWS::EC2::VolumeAttachment.VolumeId``.
        '''
        props = CfnVolumeAttachmentProps(
            device=device, instance_id=instance_id, volume_id=volume_id
        )

        jsii.create(CfnVolumeAttachment, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''(experimental) Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="device")
    def device(self) -> builtins.str:
        '''``AWS::EC2::VolumeAttachment.Device``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volumeattachment.html#cfn-ec2-ebs-volumeattachment-device
        '''
        return typing.cast(builtins.str, jsii.get(self, "device"))

    @device.setter
    def device(self, value: builtins.str) -> None:
        jsii.set(self, "device", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceId")
    def instance_id(self) -> builtins.str:
        '''``AWS::EC2::VolumeAttachment.InstanceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volumeattachment.html#cfn-ec2-ebs-volumeattachment-instanceid
        '''
        return typing.cast(builtins.str, jsii.get(self, "instanceId"))

    @instance_id.setter
    def instance_id(self, value: builtins.str) -> None:
        jsii.set(self, "instanceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="volumeId")
    def volume_id(self) -> builtins.str:
        '''``AWS::EC2::VolumeAttachment.VolumeId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volumeattachment.html#cfn-ec2-ebs-volumeattachment-volumeid
        '''
        return typing.cast(builtins.str, jsii.get(self, "volumeId"))

    @volume_id.setter
    def volume_id(self, value: builtins.str) -> None:
        jsii.set(self, "volumeId", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVolumeAttachmentProps",
    jsii_struct_bases=[],
    name_mapping={
        "device": "device",
        "instance_id": "instanceId",
        "volume_id": "volumeId",
    },
)
class CfnVolumeAttachmentProps:
    def __init__(
        self,
        *,
        device: builtins.str,
        instance_id: builtins.str,
        volume_id: builtins.str,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::VolumeAttachment``.

        :param device: ``AWS::EC2::VolumeAttachment.Device``.
        :param instance_id: ``AWS::EC2::VolumeAttachment.InstanceId``.
        :param volume_id: ``AWS::EC2::VolumeAttachment.VolumeId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volumeattachment.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "device": device,
            "instance_id": instance_id,
            "volume_id": volume_id,
        }

    @builtins.property
    def device(self) -> builtins.str:
        '''``AWS::EC2::VolumeAttachment.Device``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volumeattachment.html#cfn-ec2-ebs-volumeattachment-device
        '''
        result = self._values.get("device")
        assert result is not None, "Required property 'device' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def instance_id(self) -> builtins.str:
        '''``AWS::EC2::VolumeAttachment.InstanceId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volumeattachment.html#cfn-ec2-ebs-volumeattachment-instanceid
        '''
        result = self._values.get("instance_id")
        assert result is not None, "Required property 'instance_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def volume_id(self) -> builtins.str:
        '''``AWS::EC2::VolumeAttachment.VolumeId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volumeattachment.html#cfn-ec2-ebs-volumeattachment-volumeid
        '''
        result = self._values.get("volume_id")
        assert result is not None, "Required property 'volume_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVolumeAttachmentProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CfnVolumeProps",
    jsii_struct_bases=[],
    name_mapping={
        "availability_zone": "availabilityZone",
        "auto_enable_io": "autoEnableIo",
        "encrypted": "encrypted",
        "iops": "iops",
        "kms_key_id": "kmsKeyId",
        "multi_attach_enabled": "multiAttachEnabled",
        "outpost_arn": "outpostArn",
        "size": "size",
        "snapshot_id": "snapshotId",
        "tags": "tags",
        "throughput": "throughput",
        "volume_type": "volumeType",
    },
)
class CfnVolumeProps:
    def __init__(
        self,
        *,
        availability_zone: builtins.str,
        auto_enable_io: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        encrypted: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        iops: typing.Optional[jsii.Number] = None,
        kms_key_id: typing.Optional[builtins.str] = None,
        multi_attach_enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        outpost_arn: typing.Optional[builtins.str] = None,
        size: typing.Optional[jsii.Number] = None,
        snapshot_id: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.List[aws_cdk.core.CfnTag]] = None,
        throughput: typing.Optional[jsii.Number] = None,
        volume_type: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for defining a ``AWS::EC2::Volume``.

        :param availability_zone: ``AWS::EC2::Volume.AvailabilityZone``.
        :param auto_enable_io: ``AWS::EC2::Volume.AutoEnableIO``.
        :param encrypted: ``AWS::EC2::Volume.Encrypted``.
        :param iops: ``AWS::EC2::Volume.Iops``.
        :param kms_key_id: ``AWS::EC2::Volume.KmsKeyId``.
        :param multi_attach_enabled: ``AWS::EC2::Volume.MultiAttachEnabled``.
        :param outpost_arn: ``AWS::EC2::Volume.OutpostArn``.
        :param size: ``AWS::EC2::Volume.Size``.
        :param snapshot_id: ``AWS::EC2::Volume.SnapshotId``.
        :param tags: ``AWS::EC2::Volume.Tags``.
        :param throughput: ``AWS::EC2::Volume.Throughput``.
        :param volume_type: ``AWS::EC2::Volume.VolumeType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "availability_zone": availability_zone,
        }
        if auto_enable_io is not None:
            self._values["auto_enable_io"] = auto_enable_io
        if encrypted is not None:
            self._values["encrypted"] = encrypted
        if iops is not None:
            self._values["iops"] = iops
        if kms_key_id is not None:
            self._values["kms_key_id"] = kms_key_id
        if multi_attach_enabled is not None:
            self._values["multi_attach_enabled"] = multi_attach_enabled
        if outpost_arn is not None:
            self._values["outpost_arn"] = outpost_arn
        if size is not None:
            self._values["size"] = size
        if snapshot_id is not None:
            self._values["snapshot_id"] = snapshot_id
        if tags is not None:
            self._values["tags"] = tags
        if throughput is not None:
            self._values["throughput"] = throughput
        if volume_type is not None:
            self._values["volume_type"] = volume_type

    @builtins.property
    def availability_zone(self) -> builtins.str:
        '''``AWS::EC2::Volume.AvailabilityZone``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-availabilityzone
        '''
        result = self._values.get("availability_zone")
        assert result is not None, "Required property 'availability_zone' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def auto_enable_io(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Volume.AutoEnableIO``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-autoenableio
        '''
        result = self._values.get("auto_enable_io")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def encrypted(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Volume.Encrypted``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-encrypted
        '''
        result = self._values.get("encrypted")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def iops(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::Volume.Iops``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-iops
        '''
        result = self._values.get("iops")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def kms_key_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Volume.KmsKeyId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-kmskeyid
        '''
        result = self._values.get("kms_key_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def multi_attach_enabled(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::EC2::Volume.MultiAttachEnabled``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-multiattachenabled
        '''
        result = self._values.get("multi_attach_enabled")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def outpost_arn(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Volume.OutpostArn``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-outpostarn
        '''
        result = self._values.get("outpost_arn")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def size(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::Volume.Size``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-size
        '''
        result = self._values.get("size")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def snapshot_id(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Volume.SnapshotId``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-snapshotid
        '''
        result = self._values.get("snapshot_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::EC2::Volume.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    @builtins.property
    def throughput(self) -> typing.Optional[jsii.Number]:
        '''``AWS::EC2::Volume.Throughput``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-throughput
        '''
        result = self._values.get("throughput")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def volume_type(self) -> typing.Optional[builtins.str]:
        '''``AWS::EC2::Volume.VolumeType``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html#cfn-ec2-ebs-volume-volumetype
        '''
        result = self._values.get("volume_type")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnVolumeProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class CloudFormationInit(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.CloudFormationInit",
):
    '''A CloudFormation-init configuration.'''

    @jsii.member(jsii_name="fromConfig") # type: ignore[misc]
    @builtins.classmethod
    def from_config(cls, config: "InitConfig") -> "CloudFormationInit":
        '''Use an existing InitConfig object as the default and only config.

        :param config: -
        '''
        return typing.cast("CloudFormationInit", jsii.sinvoke(cls, "fromConfig", [config]))

    @jsii.member(jsii_name="fromConfigSets") # type: ignore[misc]
    @builtins.classmethod
    def from_config_sets(
        cls,
        *,
        configs: typing.Mapping[builtins.str, "InitConfig"],
        config_sets: typing.Mapping[builtins.str, typing.List[builtins.str]],
    ) -> "CloudFormationInit":
        '''Build a CloudFormationInit from config sets.

        :param configs: The sets of configs to pick from.
        :param config_sets: The definitions of each config set.
        '''
        props = ConfigSetProps(configs=configs, config_sets=config_sets)

        return typing.cast("CloudFormationInit", jsii.sinvoke(cls, "fromConfigSets", [props]))

    @jsii.member(jsii_name="fromElements") # type: ignore[misc]
    @builtins.classmethod
    def from_elements(cls, *elements: "InitElement") -> "CloudFormationInit":
        '''Build a new config from a set of Init Elements.

        :param elements: -
        '''
        return typing.cast("CloudFormationInit", jsii.sinvoke(cls, "fromElements", [*elements]))

    @jsii.member(jsii_name="addConfig")
    def add_config(self, config_name: builtins.str, config: "InitConfig") -> None:
        '''Add a config with the given name to this CloudFormationInit object.

        :param config_name: -
        :param config: -
        '''
        return typing.cast(None, jsii.invoke(self, "addConfig", [config_name, config]))

    @jsii.member(jsii_name="addConfigSet")
    def add_config_set(
        self,
        config_set_name: builtins.str,
        config_names: typing.Optional[typing.List[builtins.str]] = None,
    ) -> None:
        '''Add a config set with the given name to this CloudFormationInit object.

        The new configset will reference the given configs in the given order.

        :param config_set_name: -
        :param config_names: -
        '''
        return typing.cast(None, jsii.invoke(self, "addConfigSet", [config_set_name, config_names]))

    @jsii.member(jsii_name="attach")
    def attach(
        self,
        attached_resource: aws_cdk.core.CfnResource,
        *,
        instance_role: aws_cdk.aws_iam.IRole,
        platform: "OperatingSystemType",
        user_data: "UserData",
        config_sets: typing.Optional[typing.List[builtins.str]] = None,
        embed_fingerprint: typing.Optional[builtins.bool] = None,
        ignore_failures: typing.Optional[builtins.bool] = None,
        print_log: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Attach the CloudFormation Init config to the given resource.

        As an app builder, use ``instance.applyCloudFormationInit()`` or
        ``autoScalingGroup.applyCloudFormationInit()`` to trigger this method.

        This method does the following:

        - Renders the ``AWS::CloudFormation::Init`` object to the given resource's
          metadata, potentially adding a ``AWS::CloudFormation::Authentication`` object
          next to it if required.
        - Updates the instance role policy to be able to call the APIs required for
          ``cfn-init`` and ``cfn-signal`` to work, and potentially add permissions to download
          referenced asset and bucket resources.
        - Updates the given UserData with commands to execute the ``cfn-init`` script.

        :param attached_resource: -
        :param instance_role: Instance role of the consuming instance or fleet.
        :param platform: OS Platform the init config will be used for.
        :param user_data: UserData to add commands to.
        :param config_sets: ConfigSet to activate. Default: ['default']
        :param embed_fingerprint: Whether to embed a hash into the userData. If ``true`` (the default), a hash of the config will be embedded into the UserData, so that if the config changes, the UserData changes and the instance will be replaced. If ``false``, no such hash will be embedded, and if the CloudFormation Init config changes nothing will happen to the running instance. Default: true
        :param ignore_failures: Don't fail the instance creation when cfn-init fails. You can use this to prevent CloudFormation from rolling back when instances fail to start up, to help in debugging. Default: false
        :param print_log: Print the results of running cfn-init to the Instance System Log. By default, the output of running cfn-init is written to a log file on the instance. Set this to ``true`` to print it to the System Log (visible from the EC2 Console), ``false`` to not print it. (Be aware that the system log is refreshed at certain points in time of the instance life cycle, and successful execution may not always show up). Default: true
        '''
        attach_options = AttachInitOptions(
            instance_role=instance_role,
            platform=platform,
            user_data=user_data,
            config_sets=config_sets,
            embed_fingerprint=embed_fingerprint,
            ignore_failures=ignore_failures,
            print_log=print_log,
        )

        return typing.cast(None, jsii.invoke(self, "attach", [attached_resource, attach_options]))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.CommonNetworkAclEntryOptions",
    jsii_struct_bases=[],
    name_mapping={
        "cidr": "cidr",
        "rule_number": "ruleNumber",
        "traffic": "traffic",
        "direction": "direction",
        "network_acl_entry_name": "networkAclEntryName",
        "rule_action": "ruleAction",
    },
)
class CommonNetworkAclEntryOptions:
    def __init__(
        self,
        *,
        cidr: AclCidr,
        rule_number: jsii.Number,
        traffic: AclTraffic,
        direction: typing.Optional["TrafficDirection"] = None,
        network_acl_entry_name: typing.Optional[builtins.str] = None,
        rule_action: typing.Optional[Action] = None,
    ) -> None:
        '''(experimental) Basic NetworkACL entry props.

        :param cidr: (experimental) The CIDR range to allow or deny.
        :param rule_number: (experimental) Rule number to assign to the entry, such as 100. ACL entries are processed in ascending order by rule number. Entries can't use the same rule number unless one is an egress rule and the other is an ingress rule.
        :param traffic: (experimental) What kind of traffic this ACL rule applies to.
        :param direction: (experimental) Traffic direction, with respect to the subnet, this rule applies to. Default: TrafficDirection.INGRESS
        :param network_acl_entry_name: (experimental) The name of the NetworkAclEntry. It is not recommended to use an explicit group name. Default: If you don't specify a NetworkAclName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        :param rule_action: (experimental) Whether to allow or deny traffic that matches the rule; valid values are "allow" or "deny". Any traffic that is not explicitly allowed is automatically denied in a custom ACL, all traffic is automatically allowed in a default ACL. Default: ALLOW

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cidr": cidr,
            "rule_number": rule_number,
            "traffic": traffic,
        }
        if direction is not None:
            self._values["direction"] = direction
        if network_acl_entry_name is not None:
            self._values["network_acl_entry_name"] = network_acl_entry_name
        if rule_action is not None:
            self._values["rule_action"] = rule_action

    @builtins.property
    def cidr(self) -> AclCidr:
        '''(experimental) The CIDR range to allow or deny.

        :stability: experimental
        '''
        result = self._values.get("cidr")
        assert result is not None, "Required property 'cidr' is missing"
        return typing.cast(AclCidr, result)

    @builtins.property
    def rule_number(self) -> jsii.Number:
        '''(experimental) Rule number to assign to the entry, such as 100.

        ACL entries are processed in ascending order by rule number.
        Entries can't use the same rule number unless one is an egress rule and the other is an ingress rule.

        :stability: experimental
        '''
        result = self._values.get("rule_number")
        assert result is not None, "Required property 'rule_number' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def traffic(self) -> AclTraffic:
        '''(experimental) What kind of traffic this ACL rule applies to.

        :stability: experimental
        '''
        result = self._values.get("traffic")
        assert result is not None, "Required property 'traffic' is missing"
        return typing.cast(AclTraffic, result)

    @builtins.property
    def direction(self) -> typing.Optional["TrafficDirection"]:
        '''(experimental) Traffic direction, with respect to the subnet, this rule applies to.

        :default: TrafficDirection.INGRESS

        :stability: experimental
        '''
        result = self._values.get("direction")
        return typing.cast(typing.Optional["TrafficDirection"], result)

    @builtins.property
    def network_acl_entry_name(self) -> typing.Optional[builtins.str]:
        '''(experimental) The name of the NetworkAclEntry.

        It is not recommended to use an explicit group name.

        :default:

        If you don't specify a NetworkAclName, AWS CloudFormation generates a
        unique physical ID and uses that ID for the group name.

        :stability: experimental
        '''
        result = self._values.get("network_acl_entry_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def rule_action(self) -> typing.Optional[Action]:
        '''(experimental) Whether to allow or deny traffic that matches the rule; valid values are "allow" or "deny".

        Any traffic that is not explicitly allowed is automatically denied in a custom
        ACL, all traffic is automatically allowed in a default ACL.

        :default: ALLOW

        :stability: experimental
        '''
        result = self._values.get("rule_action")
        return typing.cast(typing.Optional[Action], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CommonNetworkAclEntryOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.ConfigSetProps",
    jsii_struct_bases=[],
    name_mapping={"configs": "configs", "config_sets": "configSets"},
)
class ConfigSetProps:
    def __init__(
        self,
        *,
        configs: typing.Mapping[builtins.str, "InitConfig"],
        config_sets: typing.Mapping[builtins.str, typing.List[builtins.str]],
    ) -> None:
        '''Options for CloudFormationInit.withConfigSets.

        :param configs: The sets of configs to pick from.
        :param config_sets: The definitions of each config set.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "configs": configs,
            "config_sets": config_sets,
        }

    @builtins.property
    def configs(self) -> typing.Mapping[builtins.str, "InitConfig"]:
        '''The sets of configs to pick from.'''
        result = self._values.get("configs")
        assert result is not None, "Required property 'configs' is missing"
        return typing.cast(typing.Mapping[builtins.str, "InitConfig"], result)

    @builtins.property
    def config_sets(self) -> typing.Mapping[builtins.str, typing.List[builtins.str]]:
        '''The definitions of each config set.'''
        result = self._values.get("config_sets")
        assert result is not None, "Required property 'config_sets' is missing"
        return typing.cast(typing.Mapping[builtins.str, typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ConfigSetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.ConfigureNatOptions",
    jsii_struct_bases=[],
    name_mapping={
        "nat_subnets": "natSubnets",
        "private_subnets": "privateSubnets",
        "vpc": "vpc",
    },
)
class ConfigureNatOptions:
    def __init__(
        self,
        *,
        nat_subnets: typing.List["PublicSubnet"],
        private_subnets: typing.List["PrivateSubnet"],
        vpc: "Vpc",
    ) -> None:
        '''(experimental) Options passed by the VPC when NAT needs to be configured.

        :param nat_subnets: (experimental) The public subnets where the NAT providers need to be placed.
        :param private_subnets: (experimental) The private subnets that need to route through the NAT providers. There may be more private subnets than public subnets with NAT providers.
        :param vpc: (experimental) The VPC we're configuring NAT for.

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "nat_subnets": nat_subnets,
            "private_subnets": private_subnets,
            "vpc": vpc,
        }

    @builtins.property
    def nat_subnets(self) -> typing.List["PublicSubnet"]:
        '''(experimental) The public subnets where the NAT providers need to be placed.

        :stability: experimental
        '''
        result = self._values.get("nat_subnets")
        assert result is not None, "Required property 'nat_subnets' is missing"
        return typing.cast(typing.List["PublicSubnet"], result)

    @builtins.property
    def private_subnets(self) -> typing.List["PrivateSubnet"]:
        '''(experimental) The private subnets that need to route through the NAT providers.

        There may be more private subnets than public subnets with NAT providers.

        :stability: experimental
        '''
        result = self._values.get("private_subnets")
        assert result is not None, "Required property 'private_subnets' is missing"
        return typing.cast(typing.List["PrivateSubnet"], result)

    @builtins.property
    def vpc(self) -> "Vpc":
        '''(experimental) The VPC we're configuring NAT for.

        :stability: experimental
        '''
        result = self._values.get("vpc")
        assert result is not None, "Required property 'vpc' is missing"
        return typing.cast("Vpc", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ConfigureNatOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.ConnectionRule",
    jsii_struct_bases=[],
    name_mapping={
        "from_port": "fromPort",
        "description": "description",
        "protocol": "protocol",
        "to_port": "toPort",
    },
)
class ConnectionRule:
    def __init__(
        self,
        *,
        from_port: jsii.Number,
        description: typing.Optional[builtins.str] = None,
        protocol: typing.Optional[builtins.str] = None,
        to_port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''
        :param from_port: Start of port range for the TCP and UDP protocols, or an ICMP type number. If you specify icmp for the IpProtocol property, you can specify -1 as a wildcard (i.e., any ICMP type number).
        :param description: Description of this connection. It is applied to both the ingress rule and the egress rule. Default: No description
        :param protocol: The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers). Use -1 to specify all protocols. If you specify -1, or a protocol number other than tcp, udp, icmp, or 58 (ICMPv6), traffic on all ports is allowed, regardless of any ports you specify. For tcp, udp, and icmp, you must specify a port range. For protocol 58 (ICMPv6), you can optionally specify a port range; if you don't, traffic for all types and codes is allowed. Default: tcp
        :param to_port: End of port range for the TCP and UDP protocols, or an ICMP code. If you specify icmp for the IpProtocol property, you can specify -1 as a wildcard (i.e., any ICMP code). Default: If toPort is not specified, it will be the same as fromPort.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "from_port": from_port,
        }
        if description is not None:
            self._values["description"] = description
        if protocol is not None:
            self._values["protocol"] = protocol
        if to_port is not None:
            self._values["to_port"] = to_port

    @builtins.property
    def from_port(self) -> jsii.Number:
        '''Start of port range for the TCP and UDP protocols, or an ICMP type number.

        If you specify icmp for the IpProtocol property, you can specify
        -1 as a wildcard (i.e., any ICMP type number).
        '''
        result = self._values.get("from_port")
        assert result is not None, "Required property 'from_port' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''Description of this connection.

        It is applied to both the ingress rule
        and the egress rule.

        :default: No description
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def protocol(self) -> typing.Optional[builtins.str]:
        '''The IP protocol name (tcp, udp, icmp) or number (see Protocol Numbers).

        Use -1 to specify all protocols. If you specify -1, or a protocol number
        other than tcp, udp, icmp, or 58 (ICMPv6), traffic on all ports is
        allowed, regardless of any ports you specify. For tcp, udp, and icmp, you
        must specify a port range. For protocol 58 (ICMPv6), you can optionally
        specify a port range; if you don't, traffic for all types and codes is
        allowed.

        :default: tcp
        '''
        result = self._values.get("protocol")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def to_port(self) -> typing.Optional[jsii.Number]:
        '''End of port range for the TCP and UDP protocols, or an ICMP code.

        If you specify icmp for the IpProtocol property, you can specify -1 as a
        wildcard (i.e., any ICMP code).

        :default: If toPort is not specified, it will be the same as fromPort.
        '''
        result = self._values.get("to_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ConnectionRule(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.ConnectionsProps",
    jsii_struct_bases=[],
    name_mapping={
        "default_port": "defaultPort",
        "peer": "peer",
        "security_groups": "securityGroups",
    },
)
class ConnectionsProps:
    def __init__(
        self,
        *,
        default_port: typing.Optional["Port"] = None,
        peer: typing.Optional["IPeer"] = None,
        security_groups: typing.Optional[typing.List["ISecurityGroup"]] = None,
    ) -> None:
        '''Properties to intialize a new Connections object.

        :param default_port: Default port range for initiating connections to and from this object. Default: - No default port
        :param peer: Class that represents the rule by which others can connect to this connectable. This object is required, but will be derived from securityGroup if that is passed. Default: Derived from securityGroup if set.
        :param security_groups: What securityGroup(s) this object is managing connections for. Default: No security groups
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if default_port is not None:
            self._values["default_port"] = default_port
        if peer is not None:
            self._values["peer"] = peer
        if security_groups is not None:
            self._values["security_groups"] = security_groups

    @builtins.property
    def default_port(self) -> typing.Optional["Port"]:
        '''Default port range for initiating connections to and from this object.

        :default: - No default port
        '''
        result = self._values.get("default_port")
        return typing.cast(typing.Optional["Port"], result)

    @builtins.property
    def peer(self) -> typing.Optional["IPeer"]:
        '''Class that represents the rule by which others can connect to this connectable.

        This object is required, but will be derived from securityGroup if that is passed.

        :default: Derived from securityGroup if set.
        '''
        result = self._values.get("peer")
        return typing.cast(typing.Optional["IPeer"], result)

    @builtins.property
    def security_groups(self) -> typing.Optional[typing.List["ISecurityGroup"]]:
        '''What securityGroup(s) this object is managing connections for.

        :default: No security groups
        '''
        result = self._values.get("security_groups")
        return typing.cast(typing.Optional[typing.List["ISecurityGroup"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ConnectionsProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.CpuCredits")
class CpuCredits(enum.Enum):
    '''Provides the options for specifying the CPU credit type for burstable EC2 instance types (T2, T3, T3a, etc).

    :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances-how-to.html
    '''

    STANDARD = "STANDARD"
    '''Standard bursting mode.

    :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances-standard-mode.html
    '''
    UNLIMITED = "UNLIMITED"
    '''Unlimited bursting mode.

    :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances-unlimited-mode.html
    '''


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.DefaultInstanceTenancy")
class DefaultInstanceTenancy(enum.Enum):
    '''The default tenancy of instances launched into the VPC.'''

    DEFAULT = "DEFAULT"
    '''Instances can be launched with any tenancy.'''
    DEDICATED = "DEDICATED"
    '''Any instance launched into the VPC automatically has dedicated tenancy, unless you launch it with the default tenancy.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.EbsDeviceOptionsBase",
    jsii_struct_bases=[],
    name_mapping={
        "delete_on_termination": "deleteOnTermination",
        "iops": "iops",
        "volume_type": "volumeType",
    },
)
class EbsDeviceOptionsBase:
    def __init__(
        self,
        *,
        delete_on_termination: typing.Optional[builtins.bool] = None,
        iops: typing.Optional[jsii.Number] = None,
        volume_type: typing.Optional["EbsDeviceVolumeType"] = None,
    ) -> None:
        '''Base block device options for an EBS volume.

        :param delete_on_termination: Indicates whether to delete the volume when the instance is terminated. Default: - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS)
        :param iops: The number of I/O operations per second (IOPS) to provision for the volume. Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1} The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS, you need at least 100 GiB storage on the volume. Default: - none, required for {@link EbsDeviceVolumeType.IO1}
        :param volume_type: The EBS volume type. Default: {@link EbsDeviceVolumeType.GP2}
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if delete_on_termination is not None:
            self._values["delete_on_termination"] = delete_on_termination
        if iops is not None:
            self._values["iops"] = iops
        if volume_type is not None:
            self._values["volume_type"] = volume_type

    @builtins.property
    def delete_on_termination(self) -> typing.Optional[builtins.bool]:
        '''Indicates whether to delete the volume when the instance is terminated.

        :default: - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS)
        '''
        result = self._values.get("delete_on_termination")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def iops(self) -> typing.Optional[jsii.Number]:
        '''The number of I/O operations per second (IOPS) to provision for the volume.

        Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1}

        The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS,
        you need at least 100 GiB storage on the volume.

        :default: - none, required for {@link EbsDeviceVolumeType.IO1}

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
        '''
        result = self._values.get("iops")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def volume_type(self) -> typing.Optional["EbsDeviceVolumeType"]:
        '''The EBS volume type.

        :default: {@link EbsDeviceVolumeType.GP2}

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
        '''
        result = self._values.get("volume_type")
        return typing.cast(typing.Optional["EbsDeviceVolumeType"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EbsDeviceOptionsBase(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.EbsDeviceSnapshotOptions",
    jsii_struct_bases=[EbsDeviceOptionsBase],
    name_mapping={
        "delete_on_termination": "deleteOnTermination",
        "iops": "iops",
        "volume_type": "volumeType",
        "volume_size": "volumeSize",
    },
)
class EbsDeviceSnapshotOptions(EbsDeviceOptionsBase):
    def __init__(
        self,
        *,
        delete_on_termination: typing.Optional[builtins.bool] = None,
        iops: typing.Optional[jsii.Number] = None,
        volume_type: typing.Optional["EbsDeviceVolumeType"] = None,
        volume_size: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Block device options for an EBS volume created from a snapshot.

        :param delete_on_termination: Indicates whether to delete the volume when the instance is terminated. Default: - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS)
        :param iops: The number of I/O operations per second (IOPS) to provision for the volume. Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1} The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS, you need at least 100 GiB storage on the volume. Default: - none, required for {@link EbsDeviceVolumeType.IO1}
        :param volume_type: The EBS volume type. Default: {@link EbsDeviceVolumeType.GP2}
        :param volume_size: The volume size, in Gibibytes (GiB). If you specify volumeSize, it must be equal or greater than the size of the snapshot. Default: - The snapshot size
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if delete_on_termination is not None:
            self._values["delete_on_termination"] = delete_on_termination
        if iops is not None:
            self._values["iops"] = iops
        if volume_type is not None:
            self._values["volume_type"] = volume_type
        if volume_size is not None:
            self._values["volume_size"] = volume_size

    @builtins.property
    def delete_on_termination(self) -> typing.Optional[builtins.bool]:
        '''Indicates whether to delete the volume when the instance is terminated.

        :default: - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS)
        '''
        result = self._values.get("delete_on_termination")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def iops(self) -> typing.Optional[jsii.Number]:
        '''The number of I/O operations per second (IOPS) to provision for the volume.

        Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1}

        The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS,
        you need at least 100 GiB storage on the volume.

        :default: - none, required for {@link EbsDeviceVolumeType.IO1}

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
        '''
        result = self._values.get("iops")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def volume_type(self) -> typing.Optional["EbsDeviceVolumeType"]:
        '''The EBS volume type.

        :default: {@link EbsDeviceVolumeType.GP2}

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
        '''
        result = self._values.get("volume_type")
        return typing.cast(typing.Optional["EbsDeviceVolumeType"], result)

    @builtins.property
    def volume_size(self) -> typing.Optional[jsii.Number]:
        '''The volume size, in Gibibytes (GiB).

        If you specify volumeSize, it must be equal or greater than the size of the snapshot.

        :default: - The snapshot size
        '''
        result = self._values.get("volume_size")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EbsDeviceSnapshotOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.EbsDeviceVolumeType")
class EbsDeviceVolumeType(enum.Enum):
    '''Supported EBS volume types for blockDevices.'''

    STANDARD = "STANDARD"
    '''Magnetic.'''
    IO1 = "IO1"
    '''Provisioned IOPS SSD - IO1.'''
    IO2 = "IO2"
    '''Provisioned IOPS SSD - IO2.'''
    GP2 = "GP2"
    '''General Purpose SSD - GP2.'''
    GP3 = "GP3"
    '''General Purpose SSD - GP3.'''
    ST1 = "ST1"
    '''Throughput Optimized HDD.'''
    SC1 = "SC1"
    '''Cold HDD.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.ExecuteFileOptions",
    jsii_struct_bases=[],
    name_mapping={"file_path": "filePath", "arguments": "arguments"},
)
class ExecuteFileOptions:
    def __init__(
        self,
        *,
        file_path: builtins.str,
        arguments: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Options when executing a file.

        :param file_path: The path to the file.
        :param arguments: The arguments to be passed to the file. Default: No arguments are passed to the file.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "file_path": file_path,
        }
        if arguments is not None:
            self._values["arguments"] = arguments

    @builtins.property
    def file_path(self) -> builtins.str:
        '''The path to the file.'''
        result = self._values.get("file_path")
        assert result is not None, "Required property 'file_path' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def arguments(self) -> typing.Optional[builtins.str]:
        '''The arguments to be passed to the file.

        :default: No arguments are passed to the file.
        '''
        result = self._values.get("arguments")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ExecuteFileOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class FlowLogDestination(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-ec2.FlowLogDestination",
):
    '''(experimental) The destination type for the flow log.

    :stability: experimental
    '''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_FlowLogDestinationProxy"]:
        return _FlowLogDestinationProxy

    def __init__(self) -> None:
        jsii.create(FlowLogDestination, self, [])

    @jsii.member(jsii_name="toCloudWatchLogs") # type: ignore[misc]
    @builtins.classmethod
    def to_cloud_watch_logs(
        cls,
        log_group: typing.Optional[aws_cdk.aws_logs.ILogGroup] = None,
        iam_role: typing.Optional[aws_cdk.aws_iam.IRole] = None,
    ) -> "FlowLogDestination":
        '''(experimental) Use CloudWatch logs as the destination.

        :param log_group: -
        :param iam_role: -

        :stability: experimental
        '''
        return typing.cast("FlowLogDestination", jsii.sinvoke(cls, "toCloudWatchLogs", [log_group, iam_role]))

    @jsii.member(jsii_name="toS3") # type: ignore[misc]
    @builtins.classmethod
    def to_s3(
        cls,
        bucket: typing.Optional[aws_cdk.aws_s3.IBucket] = None,
        key_prefix: typing.Optional[builtins.str] = None,
    ) -> "FlowLogDestination":
        '''(experimental) Use S3 as the destination.

        :param bucket: -
        :param key_prefix: -

        :stability: experimental
        '''
        return typing.cast("FlowLogDestination", jsii.sinvoke(cls, "toS3", [bucket, key_prefix]))

    @jsii.member(jsii_name="bind") # type: ignore[misc]
    @abc.abstractmethod
    def bind(
        self,
        scope: aws_cdk.core.Construct,
        flow_log: "FlowLog",
    ) -> "FlowLogDestinationConfig":
        '''(experimental) Generates a flow log destination configuration.

        :param scope: -
        :param flow_log: -

        :stability: experimental
        '''
        ...


class _FlowLogDestinationProxy(FlowLogDestination):
    @jsii.member(jsii_name="bind")
    def bind(
        self,
        scope: aws_cdk.core.Construct,
        flow_log: "FlowLog",
    ) -> "FlowLogDestinationConfig":
        '''(experimental) Generates a flow log destination configuration.

        :param scope: -
        :param flow_log: -

        :stability: experimental
        '''
        return typing.cast("FlowLogDestinationConfig", jsii.invoke(self, "bind", [scope, flow_log]))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.FlowLogDestinationConfig",
    jsii_struct_bases=[],
    name_mapping={
        "log_destination_type": "logDestinationType",
        "iam_role": "iamRole",
        "key_prefix": "keyPrefix",
        "log_group": "logGroup",
        "s3_bucket": "s3Bucket",
    },
)
class FlowLogDestinationConfig:
    def __init__(
        self,
        *,
        log_destination_type: "FlowLogDestinationType",
        iam_role: typing.Optional[aws_cdk.aws_iam.IRole] = None,
        key_prefix: typing.Optional[builtins.str] = None,
        log_group: typing.Optional[aws_cdk.aws_logs.ILogGroup] = None,
        s3_bucket: typing.Optional[aws_cdk.aws_s3.IBucket] = None,
    ) -> None:
        '''(experimental) Flow Log Destination configuration.

        :param log_destination_type: (experimental) The type of destination to publish the flow logs to. Default: - CLOUD_WATCH_LOGS
        :param iam_role: (experimental) The IAM Role that has access to publish to CloudWatch logs. Default: - default IAM role is created for you
        :param key_prefix: (experimental) S3 bucket key prefix to publish the flow logs to. Default: - undefined
        :param log_group: (experimental) The CloudWatch Logs Log Group to publish the flow logs to. Default: - default log group is created for you
        :param s3_bucket: (experimental) S3 bucket to publish the flow logs to. Default: - undefined

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "log_destination_type": log_destination_type,
        }
        if iam_role is not None:
            self._values["iam_role"] = iam_role
        if key_prefix is not None:
            self._values["key_prefix"] = key_prefix
        if log_group is not None:
            self._values["log_group"] = log_group
        if s3_bucket is not None:
            self._values["s3_bucket"] = s3_bucket

    @builtins.property
    def log_destination_type(self) -> "FlowLogDestinationType":
        '''(experimental) The type of destination to publish the flow logs to.

        :default: - CLOUD_WATCH_LOGS

        :stability: experimental
        '''
        result = self._values.get("log_destination_type")
        assert result is not None, "Required property 'log_destination_type' is missing"
        return typing.cast("FlowLogDestinationType", result)

    @builtins.property
    def iam_role(self) -> typing.Optional[aws_cdk.aws_iam.IRole]:
        '''(experimental) The IAM Role that has access to publish to CloudWatch logs.

        :default: - default IAM role is created for you

        :stability: experimental
        '''
        result = self._values.get("iam_role")
        return typing.cast(typing.Optional[aws_cdk.aws_iam.IRole], result)

    @builtins.property
    def key_prefix(self) -> typing.Optional[builtins.str]:
        '''(experimental) S3 bucket key prefix to publish the flow logs to.

        :default: - undefined

        :stability: experimental
        '''
        result = self._values.get("key_prefix")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def log_group(self) -> typing.Optional[aws_cdk.aws_logs.ILogGroup]:
        '''(experimental) The CloudWatch Logs Log Group to publish the flow logs to.

        :default: - default log group is created for you

        :stability: experimental
        '''
        result = self._values.get("log_group")
        return typing.cast(typing.Optional[aws_cdk.aws_logs.ILogGroup], result)

    @builtins.property
    def s3_bucket(self) -> typing.Optional[aws_cdk.aws_s3.IBucket]:
        '''(experimental) S3 bucket to publish the flow logs to.

        :default: - undefined

        :stability: experimental
        '''
        result = self._values.get("s3_bucket")
        return typing.cast(typing.Optional[aws_cdk.aws_s3.IBucket], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FlowLogDestinationConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.FlowLogDestinationType")
class FlowLogDestinationType(enum.Enum):
    '''(experimental) The available destination types for Flow Logs.

    :stability: experimental
    '''

    CLOUD_WATCH_LOGS = "CLOUD_WATCH_LOGS"
    '''(experimental) Send flow logs to CloudWatch Logs Group.

    :stability: experimental
    '''
    S3 = "S3"
    '''(experimental) Send flow logs to S3 Bucket.

    :stability: experimental
    '''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.FlowLogOptions",
    jsii_struct_bases=[],
    name_mapping={"destination": "destination", "traffic_type": "trafficType"},
)
class FlowLogOptions:
    def __init__(
        self,
        *,
        destination: typing.Optional[FlowLogDestination] = None,
        traffic_type: typing.Optional["FlowLogTrafficType"] = None,
    ) -> None:
        '''(experimental) Options to add a flow log to a VPC.

        :param destination: (experimental) Specifies the type of destination to which the flow log data is to be published. Flow log data can be published to CloudWatch Logs or Amazon S3 Default: FlowLogDestinationType.toCloudWatchLogs()
        :param traffic_type: (experimental) The type of traffic to log. You can log traffic that the resource accepts or rejects, or all traffic. Default: ALL

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if destination is not None:
            self._values["destination"] = destination
        if traffic_type is not None:
            self._values["traffic_type"] = traffic_type

    @builtins.property
    def destination(self) -> typing.Optional[FlowLogDestination]:
        '''(experimental) Specifies the type of destination to which the flow log data is to be published.

        Flow log data can be published to CloudWatch Logs or Amazon S3

        :default: FlowLogDestinationType.toCloudWatchLogs()

        :stability: experimental
        '''
        result = self._values.get("destination")
        return typing.cast(typing.Optional[FlowLogDestination], result)

    @builtins.property
    def traffic_type(self) -> typing.Optional["FlowLogTrafficType"]:
        '''(experimental) The type of traffic to log.

        You can log traffic that the resource accepts or rejects, or all traffic.

        :default: ALL

        :stability: experimental
        '''
        result = self._values.get("traffic_type")
        return typing.cast(typing.Optional["FlowLogTrafficType"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FlowLogOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.FlowLogProps",
    jsii_struct_bases=[FlowLogOptions],
    name_mapping={
        "destination": "destination",
        "traffic_type": "trafficType",
        "resource_type": "resourceType",
        "flow_log_name": "flowLogName",
    },
)
class FlowLogProps(FlowLogOptions):
    def __init__(
        self,
        *,
        destination: typing.Optional[FlowLogDestination] = None,
        traffic_type: typing.Optional["FlowLogTrafficType"] = None,
        resource_type: "FlowLogResourceType",
        flow_log_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''(experimental) Properties of a VPC Flow Log.

        :param destination: (experimental) Specifies the type of destination to which the flow log data is to be published. Flow log data can be published to CloudWatch Logs or Amazon S3 Default: FlowLogDestinationType.toCloudWatchLogs()
        :param traffic_type: (experimental) The type of traffic to log. You can log traffic that the resource accepts or rejects, or all traffic. Default: ALL
        :param resource_type: (experimental) The type of resource for which to create the flow log.
        :param flow_log_name: (experimental) The name of the FlowLog. It is not recommended to use an explicit name. Default: If you don't specify a flowLogName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "resource_type": resource_type,
        }
        if destination is not None:
            self._values["destination"] = destination
        if traffic_type is not None:
            self._values["traffic_type"] = traffic_type
        if flow_log_name is not None:
            self._values["flow_log_name"] = flow_log_name

    @builtins.property
    def destination(self) -> typing.Optional[FlowLogDestination]:
        '''(experimental) Specifies the type of destination to which the flow log data is to be published.

        Flow log data can be published to CloudWatch Logs or Amazon S3

        :default: FlowLogDestinationType.toCloudWatchLogs()

        :stability: experimental
        '''
        result = self._values.get("destination")
        return typing.cast(typing.Optional[FlowLogDestination], result)

    @builtins.property
    def traffic_type(self) -> typing.Optional["FlowLogTrafficType"]:
        '''(experimental) The type of traffic to log.

        You can log traffic that the resource accepts or rejects, or all traffic.

        :default: ALL

        :stability: experimental
        '''
        result = self._values.get("traffic_type")
        return typing.cast(typing.Optional["FlowLogTrafficType"], result)

    @builtins.property
    def resource_type(self) -> "FlowLogResourceType":
        '''(experimental) The type of resource for which to create the flow log.

        :stability: experimental
        '''
        result = self._values.get("resource_type")
        assert result is not None, "Required property 'resource_type' is missing"
        return typing.cast("FlowLogResourceType", result)

    @builtins.property
    def flow_log_name(self) -> typing.Optional[builtins.str]:
        '''(experimental) The name of the FlowLog.

        It is not recommended to use an explicit name.

        :default:

        If you don't specify a flowLogName, AWS CloudFormation generates a
        unique physical ID and uses that ID for the group name.

        :stability: experimental
        '''
        result = self._values.get("flow_log_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FlowLogProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class FlowLogResourceType(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-ec2.FlowLogResourceType",
):
    '''(experimental) The type of resource to create the flow log for.

    :stability: experimental
    '''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_FlowLogResourceTypeProxy"]:
        return _FlowLogResourceTypeProxy

    def __init__(self) -> None:
        jsii.create(FlowLogResourceType, self, [])

    @jsii.member(jsii_name="fromNetworkInterfaceId") # type: ignore[misc]
    @builtins.classmethod
    def from_network_interface_id(cls, id: builtins.str) -> "FlowLogResourceType":
        '''(experimental) The Network Interface to attach the Flow Log to.

        :param id: -

        :stability: experimental
        '''
        return typing.cast("FlowLogResourceType", jsii.sinvoke(cls, "fromNetworkInterfaceId", [id]))

    @jsii.member(jsii_name="fromSubnet") # type: ignore[misc]
    @builtins.classmethod
    def from_subnet(cls, subnet: "ISubnet") -> "FlowLogResourceType":
        '''(experimental) The subnet to attach the Flow Log to.

        :param subnet: -

        :stability: experimental
        '''
        return typing.cast("FlowLogResourceType", jsii.sinvoke(cls, "fromSubnet", [subnet]))

    @jsii.member(jsii_name="fromVpc") # type: ignore[misc]
    @builtins.classmethod
    def from_vpc(cls, vpc: "IVpc") -> "FlowLogResourceType":
        '''(experimental) The VPC to attach the Flow Log to.

        :param vpc: -

        :stability: experimental
        '''
        return typing.cast("FlowLogResourceType", jsii.sinvoke(cls, "fromVpc", [vpc]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="resourceId")
    @abc.abstractmethod
    def resource_id(self) -> builtins.str:
        '''(experimental) The Id of the resource that the flow log should be attached to.

        :stability: experimental
        '''
        ...

    @resource_id.setter
    @abc.abstractmethod
    def resource_id(self, value: builtins.str) -> None:
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="resourceType")
    @abc.abstractmethod
    def resource_type(self) -> builtins.str:
        '''(experimental) The type of resource to attach a flow log to.

        :stability: experimental
        '''
        ...

    @resource_type.setter
    @abc.abstractmethod
    def resource_type(self, value: builtins.str) -> None:
        ...


class _FlowLogResourceTypeProxy(FlowLogResourceType):
    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="resourceId")
    def resource_id(self) -> builtins.str:
        '''(experimental) The Id of the resource that the flow log should be attached to.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "resourceId"))

    @resource_id.setter
    def resource_id(self, value: builtins.str) -> None:
        jsii.set(self, "resourceId", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="resourceType")
    def resource_type(self) -> builtins.str:
        '''(experimental) The type of resource to attach a flow log to.

        :stability: experimental
        '''
        return typing.cast(builtins.str, jsii.get(self, "resourceType"))

    @resource_type.setter
    def resource_type(self, value: builtins.str) -> None:
        jsii.set(self, "resourceType", value)


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.FlowLogTrafficType")
class FlowLogTrafficType(enum.Enum):
    '''(experimental) The type of VPC traffic to log.

    :stability: experimental
    '''

    ACCEPT = "ACCEPT"
    '''(experimental) Only log accepts.

    :stability: experimental
    '''
    ALL = "ALL"
    '''(experimental) Log all requests.

    :stability: experimental
    '''
    REJECT = "REJECT"
    '''(experimental) Only log rejects.

    :stability: experimental
    '''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.GatewayConfig",
    jsii_struct_bases=[],
    name_mapping={"az": "az", "gateway_id": "gatewayId"},
)
class GatewayConfig:
    def __init__(self, *, az: builtins.str, gateway_id: builtins.str) -> None:
        '''Pair represents a gateway created by NAT Provider.

        :param az: Availability Zone.
        :param gateway_id: Identity of gateway spawned by the provider.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "az": az,
            "gateway_id": gateway_id,
        }

    @builtins.property
    def az(self) -> builtins.str:
        '''Availability Zone.'''
        result = self._values.get("az")
        assert result is not None, "Required property 'az' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def gateway_id(self) -> builtins.str:
        '''Identity of gateway spawned by the provider.'''
        result = self._values.get("gateway_id")
        assert result is not None, "Required property 'gateway_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GatewayConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.GatewayVpcEndpointOptions",
    jsii_struct_bases=[],
    name_mapping={"service": "service", "subnets": "subnets"},
)
class GatewayVpcEndpointOptions:
    def __init__(
        self,
        *,
        service: "IGatewayVpcEndpointService",
        subnets: typing.Optional[typing.List["SubnetSelection"]] = None,
    ) -> None:
        '''Options to add a gateway endpoint to a VPC.

        :param service: The service to use for this gateway VPC endpoint.
        :param subnets: Where to add endpoint routing. By default, this endpoint will be routable from all subnets in the VPC. Specify a list of subnet selection objects here to be more specific. Default: - All subnets in the VPC
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "service": service,
        }
        if subnets is not None:
            self._values["subnets"] = subnets

    @builtins.property
    def service(self) -> "IGatewayVpcEndpointService":
        '''The service to use for this gateway VPC endpoint.'''
        result = self._values.get("service")
        assert result is not None, "Required property 'service' is missing"
        return typing.cast("IGatewayVpcEndpointService", result)

    @builtins.property
    def subnets(self) -> typing.Optional[typing.List["SubnetSelection"]]:
        '''Where to add endpoint routing.

        By default, this endpoint will be routable from all subnets in the VPC.
        Specify a list of subnet selection objects here to be more specific.

        :default: - All subnets in the VPC

        Example::

            # Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
            vpc.add_gateway_endpoint("DynamoDbEndpoint",
                service=ec2.GatewayVpcEndpointAwsService.DYNAMODB,
                # Add only to ISOLATED subnets
                subnets=[{"subnet_type": ec2.SubnetType.ISOLATED}
                ]
            )
        '''
        result = self._values.get("subnets")
        return typing.cast(typing.Optional[typing.List["SubnetSelection"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GatewayVpcEndpointOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.GatewayVpcEndpointProps",
    jsii_struct_bases=[GatewayVpcEndpointOptions],
    name_mapping={"service": "service", "subnets": "subnets", "vpc": "vpc"},
)
class GatewayVpcEndpointProps(GatewayVpcEndpointOptions):
    def __init__(
        self,
        *,
        service: "IGatewayVpcEndpointService",
        subnets: typing.Optional[typing.List["SubnetSelection"]] = None,
        vpc: "IVpc",
    ) -> None:
        '''Construction properties for a GatewayVpcEndpoint.

        :param service: The service to use for this gateway VPC endpoint.
        :param subnets: Where to add endpoint routing. By default, this endpoint will be routable from all subnets in the VPC. Specify a list of subnet selection objects here to be more specific. Default: - All subnets in the VPC
        :param vpc: The VPC network in which the gateway endpoint will be used.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "service": service,
            "vpc": vpc,
        }
        if subnets is not None:
            self._values["subnets"] = subnets

    @builtins.property
    def service(self) -> "IGatewayVpcEndpointService":
        '''The service to use for this gateway VPC endpoint.'''
        result = self._values.get("service")
        assert result is not None, "Required property 'service' is missing"
        return typing.cast("IGatewayVpcEndpointService", result)

    @builtins.property
    def subnets(self) -> typing.Optional[typing.List["SubnetSelection"]]:
        '''Where to add endpoint routing.

        By default, this endpoint will be routable from all subnets in the VPC.
        Specify a list of subnet selection objects here to be more specific.

        :default: - All subnets in the VPC

        Example::

            # Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
            vpc.add_gateway_endpoint("DynamoDbEndpoint",
                service=ec2.GatewayVpcEndpointAwsService.DYNAMODB,
                # Add only to ISOLATED subnets
                subnets=[{"subnet_type": ec2.SubnetType.ISOLATED}
                ]
            )
        '''
        result = self._values.get("subnets")
        return typing.cast(typing.Optional[typing.List["SubnetSelection"]], result)

    @builtins.property
    def vpc(self) -> "IVpc":
        '''The VPC network in which the gateway endpoint will be used.'''
        result = self._values.get("vpc")
        assert result is not None, "Required property 'vpc' is missing"
        return typing.cast("IVpc", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GatewayVpcEndpointProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.GenericLinuxImageProps",
    jsii_struct_bases=[],
    name_mapping={"user_data": "userData"},
)
class GenericLinuxImageProps:
    def __init__(self, *, user_data: typing.Optional["UserData"] = None) -> None:
        '''Configuration options for GenericLinuxImage.

        :param user_data: Initial user data. Default: - Empty UserData for Linux machines
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if user_data is not None:
            self._values["user_data"] = user_data

    @builtins.property
    def user_data(self) -> typing.Optional["UserData"]:
        '''Initial user data.

        :default: - Empty UserData for Linux machines
        '''
        result = self._values.get("user_data")
        return typing.cast(typing.Optional["UserData"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GenericLinuxImageProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.GenericWindowsImageProps",
    jsii_struct_bases=[],
    name_mapping={"user_data": "userData"},
)
class GenericWindowsImageProps:
    def __init__(self, *, user_data: typing.Optional["UserData"] = None) -> None:
        '''Configuration options for GenericWindowsImage.

        :param user_data: Initial user data. Default: - Empty UserData for Windows machines
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if user_data is not None:
            self._values["user_data"] = user_data

    @builtins.property
    def user_data(self) -> typing.Optional["UserData"]:
        '''Initial user data.

        :default: - Empty UserData for Windows machines
        '''
        result = self._values.get("user_data")
        return typing.cast(typing.Optional["UserData"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "GenericWindowsImageProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IConnectable")
class IConnectable(typing_extensions.Protocol):
    '''An object that has a Connections object.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IConnectableProxy"]:
        return _IConnectableProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connections")
    def connections(self) -> "Connections":
        ...


class _IConnectableProxy:
    '''An object that has a Connections object.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IConnectable"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connections")
    def connections(self) -> "Connections":
        return typing.cast("Connections", jsii.get(self, "connections"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IFlowLog")
class IFlowLog(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''(experimental) A FlowLog.

    :stability: experimental
    '''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IFlowLogProxy"]:
        return _IFlowLogProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="flowLogId")
    def flow_log_id(self) -> builtins.str:
        '''(experimental) The Id of the VPC Flow Log.

        :stability: experimental
        :attribute: true
        '''
        ...


class _IFlowLogProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''(experimental) A FlowLog.

    :stability: experimental
    '''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IFlowLog"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="flowLogId")
    def flow_log_id(self) -> builtins.str:
        '''(experimental) The Id of the VPC Flow Log.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "flowLogId"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IGatewayVpcEndpointService")
class IGatewayVpcEndpointService(typing_extensions.Protocol):
    '''A service for a gateway VPC endpoint.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IGatewayVpcEndpointServiceProxy"]:
        return _IGatewayVpcEndpointServiceProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="name")
    def name(self) -> builtins.str:
        '''The name of the service.'''
        ...


class _IGatewayVpcEndpointServiceProxy:
    '''A service for a gateway VPC endpoint.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IGatewayVpcEndpointService"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="name")
    def name(self) -> builtins.str:
        '''The name of the service.'''
        return typing.cast(builtins.str, jsii.get(self, "name"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IInstance")
class IInstance(
    aws_cdk.core.IResource,
    IConnectable,
    aws_cdk.aws_iam.IGrantable,
    typing_extensions.Protocol,
):
    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IInstanceProxy"]:
        return _IInstanceProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceAvailabilityZone")
    def instance_availability_zone(self) -> builtins.str:
        '''The availability zone the instance was launched in.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceId")
    def instance_id(self) -> builtins.str:
        '''The instance's ID.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePrivateDnsName")
    def instance_private_dns_name(self) -> builtins.str:
        '''Private DNS name for this instance.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePrivateIp")
    def instance_private_ip(self) -> builtins.str:
        '''Private IP for this instance.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePublicDnsName")
    def instance_public_dns_name(self) -> builtins.str:
        '''Publicly-routable DNS name for this instance.

        (May be an empty string if the instance does not have a public name).

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePublicIp")
    def instance_public_ip(self) -> builtins.str:
        '''Publicly-routable IP  address for this instance.

        (May be an empty string if the instance does not have a public IP).

        :attribute: true
        '''
        ...


class _IInstanceProxy(
    jsii.proxy_for(aws_cdk.core.IResource), # type: ignore[misc]
    jsii.proxy_for(IConnectable), # type: ignore[misc]
    jsii.proxy_for(aws_cdk.aws_iam.IGrantable), # type: ignore[misc]
):
    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IInstance"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceAvailabilityZone")
    def instance_availability_zone(self) -> builtins.str:
        '''The availability zone the instance was launched in.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instanceAvailabilityZone"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceId")
    def instance_id(self) -> builtins.str:
        '''The instance's ID.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instanceId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePrivateDnsName")
    def instance_private_dns_name(self) -> builtins.str:
        '''Private DNS name for this instance.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePrivateDnsName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePrivateIp")
    def instance_private_ip(self) -> builtins.str:
        '''Private IP for this instance.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePrivateIp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePublicDnsName")
    def instance_public_dns_name(self) -> builtins.str:
        '''Publicly-routable DNS name for this instance.

        (May be an empty string if the instance does not have a public name).

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePublicDnsName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePublicIp")
    def instance_public_ip(self) -> builtins.str:
        '''Publicly-routable IP  address for this instance.

        (May be an empty string if the instance does not have a public IP).

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePublicIp"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IInterfaceVpcEndpointService")
class IInterfaceVpcEndpointService(typing_extensions.Protocol):
    '''A service for an interface VPC endpoint.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IInterfaceVpcEndpointServiceProxy"]:
        return _IInterfaceVpcEndpointServiceProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="name")
    def name(self) -> builtins.str:
        '''The name of the service.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="port")
    def port(self) -> jsii.Number:
        '''The port of the service.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateDnsDefault")
    def private_dns_default(self) -> typing.Optional[builtins.bool]:
        '''Whether Private DNS is supported by default.'''
        ...


class _IInterfaceVpcEndpointServiceProxy:
    '''A service for an interface VPC endpoint.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IInterfaceVpcEndpointService"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="name")
    def name(self) -> builtins.str:
        '''The name of the service.'''
        return typing.cast(builtins.str, jsii.get(self, "name"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="port")
    def port(self) -> jsii.Number:
        '''The port of the service.'''
        return typing.cast(jsii.Number, jsii.get(self, "port"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateDnsDefault")
    def private_dns_default(self) -> typing.Optional[builtins.bool]:
        '''Whether Private DNS is supported by default.'''
        return typing.cast(typing.Optional[builtins.bool], jsii.get(self, "privateDnsDefault"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.ILaunchTemplate")
class ILaunchTemplate(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Interface for LaunchTemplate-like objects.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_ILaunchTemplateProxy"]:
        return _ILaunchTemplateProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="versionNumber")
    def version_number(self) -> builtins.str:
        '''The version number of this launch template to use.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="launchTemplateId")
    def launch_template_id(self) -> typing.Optional[builtins.str]:
        '''The identifier of the Launch Template.

        Exactly one of ``launchTemplateId`` and ``launchTemplateName`` will be set.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="launchTemplateName")
    def launch_template_name(self) -> typing.Optional[builtins.str]:
        '''The name of the Launch Template.

        Exactly one of ``launchTemplateId`` and ``launchTemplateName`` will be set.

        :attribute: true
        '''
        ...


class _ILaunchTemplateProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''Interface for LaunchTemplate-like objects.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.ILaunchTemplate"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="versionNumber")
    def version_number(self) -> builtins.str:
        '''The version number of this launch template to use.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "versionNumber"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="launchTemplateId")
    def launch_template_id(self) -> typing.Optional[builtins.str]:
        '''The identifier of the Launch Template.

        Exactly one of ``launchTemplateId`` and ``launchTemplateName`` will be set.

        :attribute: true
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "launchTemplateId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="launchTemplateName")
    def launch_template_name(self) -> typing.Optional[builtins.str]:
        '''The name of the Launch Template.

        Exactly one of ``launchTemplateId`` and ``launchTemplateName`` will be set.

        :attribute: true
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "launchTemplateName"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IMachineImage")
class IMachineImage(typing_extensions.Protocol):
    '''Interface for classes that can select an appropriate machine image to use.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IMachineImageProxy"]:
        return _IMachineImageProxy

    @jsii.member(jsii_name="getImage")
    def get_image(self, scope: aws_cdk.core.Construct) -> "MachineImageConfig":
        '''Return the image to use in the given context.

        :param scope: -
        '''
        ...


class _IMachineImageProxy:
    '''Interface for classes that can select an appropriate machine image to use.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IMachineImage"

    @jsii.member(jsii_name="getImage")
    def get_image(self, scope: aws_cdk.core.Construct) -> "MachineImageConfig":
        '''Return the image to use in the given context.

        :param scope: -
        '''
        return typing.cast("MachineImageConfig", jsii.invoke(self, "getImage", [scope]))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.INetworkAcl")
class INetworkAcl(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''(experimental) A NetworkAcl.

    :stability: experimental
    '''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_INetworkAclProxy"]:
        return _INetworkAclProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkAclId")
    def network_acl_id(self) -> builtins.str:
        '''(experimental) ID for the current Network ACL.

        :stability: experimental
        :attribute: true
        '''
        ...

    @jsii.member(jsii_name="addEntry")
    def add_entry(
        self,
        id: builtins.str,
        *,
        cidr: AclCidr,
        rule_number: jsii.Number,
        traffic: AclTraffic,
        direction: typing.Optional["TrafficDirection"] = None,
        network_acl_entry_name: typing.Optional[builtins.str] = None,
        rule_action: typing.Optional[Action] = None,
    ) -> "NetworkAclEntry":
        '''(experimental) Add a new entry to the ACL.

        :param id: -
        :param cidr: (experimental) The CIDR range to allow or deny.
        :param rule_number: (experimental) Rule number to assign to the entry, such as 100. ACL entries are processed in ascending order by rule number. Entries can't use the same rule number unless one is an egress rule and the other is an ingress rule.
        :param traffic: (experimental) What kind of traffic this ACL rule applies to.
        :param direction: (experimental) Traffic direction, with respect to the subnet, this rule applies to. Default: TrafficDirection.INGRESS
        :param network_acl_entry_name: (experimental) The name of the NetworkAclEntry. It is not recommended to use an explicit group name. Default: If you don't specify a NetworkAclName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        :param rule_action: (experimental) Whether to allow or deny traffic that matches the rule; valid values are "allow" or "deny". Any traffic that is not explicitly allowed is automatically denied in a custom ACL, all traffic is automatically allowed in a default ACL. Default: ALLOW

        :stability: experimental
        '''
        ...


class _INetworkAclProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''(experimental) A NetworkAcl.

    :stability: experimental
    '''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.INetworkAcl"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkAclId")
    def network_acl_id(self) -> builtins.str:
        '''(experimental) ID for the current Network ACL.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "networkAclId"))

    @jsii.member(jsii_name="addEntry")
    def add_entry(
        self,
        id: builtins.str,
        *,
        cidr: AclCidr,
        rule_number: jsii.Number,
        traffic: AclTraffic,
        direction: typing.Optional["TrafficDirection"] = None,
        network_acl_entry_name: typing.Optional[builtins.str] = None,
        rule_action: typing.Optional[Action] = None,
    ) -> "NetworkAclEntry":
        '''(experimental) Add a new entry to the ACL.

        :param id: -
        :param cidr: (experimental) The CIDR range to allow or deny.
        :param rule_number: (experimental) Rule number to assign to the entry, such as 100. ACL entries are processed in ascending order by rule number. Entries can't use the same rule number unless one is an egress rule and the other is an ingress rule.
        :param traffic: (experimental) What kind of traffic this ACL rule applies to.
        :param direction: (experimental) Traffic direction, with respect to the subnet, this rule applies to. Default: TrafficDirection.INGRESS
        :param network_acl_entry_name: (experimental) The name of the NetworkAclEntry. It is not recommended to use an explicit group name. Default: If you don't specify a NetworkAclName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        :param rule_action: (experimental) Whether to allow or deny traffic that matches the rule; valid values are "allow" or "deny". Any traffic that is not explicitly allowed is automatically denied in a custom ACL, all traffic is automatically allowed in a default ACL. Default: ALLOW

        :stability: experimental
        '''
        options = CommonNetworkAclEntryOptions(
            cidr=cidr,
            rule_number=rule_number,
            traffic=traffic,
            direction=direction,
            network_acl_entry_name=network_acl_entry_name,
            rule_action=rule_action,
        )

        return typing.cast("NetworkAclEntry", jsii.invoke(self, "addEntry", [id, options]))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.INetworkAclEntry")
class INetworkAclEntry(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''(experimental) A NetworkAclEntry.

    :stability: experimental
    '''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_INetworkAclEntryProxy"]:
        return _INetworkAclEntryProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkAcl")
    def network_acl(self) -> INetworkAcl:
        '''(experimental) The network ACL.

        :stability: experimental
        '''
        ...


class _INetworkAclEntryProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''(experimental) A NetworkAclEntry.

    :stability: experimental
    '''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.INetworkAclEntry"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkAcl")
    def network_acl(self) -> INetworkAcl:
        '''(experimental) The network ACL.

        :stability: experimental
        '''
        return typing.cast(INetworkAcl, jsii.get(self, "networkAcl"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IPeer")
class IPeer(IConnectable, typing_extensions.Protocol):
    '''Interface for classes that provide the peer-specification parts of a security group rule.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IPeerProxy"]:
        return _IPeerProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="canInlineRule")
    def can_inline_rule(self) -> builtins.bool:
        '''Whether the rule can be inlined into a SecurityGroup or not.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="uniqueId")
    def unique_id(self) -> builtins.str:
        '''A unique identifier for this connection peer.'''
        ...

    @jsii.member(jsii_name="toEgressRuleConfig")
    def to_egress_rule_config(self) -> typing.Any:
        '''Produce the egress rule JSON for the given connection.'''
        ...

    @jsii.member(jsii_name="toIngressRuleConfig")
    def to_ingress_rule_config(self) -> typing.Any:
        '''Produce the ingress rule JSON for the given connection.'''
        ...


class _IPeerProxy(
    jsii.proxy_for(IConnectable) # type: ignore[misc]
):
    '''Interface for classes that provide the peer-specification parts of a security group rule.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IPeer"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="canInlineRule")
    def can_inline_rule(self) -> builtins.bool:
        '''Whether the rule can be inlined into a SecurityGroup or not.'''
        return typing.cast(builtins.bool, jsii.get(self, "canInlineRule"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="uniqueId")
    def unique_id(self) -> builtins.str:
        '''A unique identifier for this connection peer.'''
        return typing.cast(builtins.str, jsii.get(self, "uniqueId"))

    @jsii.member(jsii_name="toEgressRuleConfig")
    def to_egress_rule_config(self) -> typing.Any:
        '''Produce the egress rule JSON for the given connection.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toEgressRuleConfig", []))

    @jsii.member(jsii_name="toIngressRuleConfig")
    def to_ingress_rule_config(self) -> typing.Any:
        '''Produce the ingress rule JSON for the given connection.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toIngressRuleConfig", []))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IRouteTable")
class IRouteTable(typing_extensions.Protocol):
    '''An abstract route table.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IRouteTableProxy"]:
        return _IRouteTableProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="routeTableId")
    def route_table_id(self) -> builtins.str:
        '''Route table ID.'''
        ...


class _IRouteTableProxy:
    '''An abstract route table.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IRouteTable"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="routeTableId")
    def route_table_id(self) -> builtins.str:
        '''Route table ID.'''
        return typing.cast(builtins.str, jsii.get(self, "routeTableId"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.ISecurityGroup")
class ISecurityGroup(aws_cdk.core.IResource, IPeer, typing_extensions.Protocol):
    '''Interface for security group-like objects.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_ISecurityGroupProxy"]:
        return _ISecurityGroupProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="allowAllOutbound")
    def allow_all_outbound(self) -> builtins.bool:
        '''Whether the SecurityGroup has been configured to allow all outbound traffic.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroupId")
    def security_group_id(self) -> builtins.str:
        '''ID for the current security group.

        :attribute: true
        '''
        ...

    @jsii.member(jsii_name="addEgressRule")
    def add_egress_rule(
        self,
        peer: IPeer,
        connection: "Port",
        description: typing.Optional[builtins.str] = None,
        remote_rule: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Add an egress rule for the current security group.

        ``remoteRule`` controls where the Rule object is created if the peer is also a
        securityGroup and they are in different stack. If false (default) the
        rule object is created under the current SecurityGroup object. If true and the
        peer is also a SecurityGroup, the rule object is created under the remote
        SecurityGroup object.

        :param peer: -
        :param connection: -
        :param description: -
        :param remote_rule: -
        '''
        ...

    @jsii.member(jsii_name="addIngressRule")
    def add_ingress_rule(
        self,
        peer: IPeer,
        connection: "Port",
        description: typing.Optional[builtins.str] = None,
        remote_rule: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Add an ingress rule for the current security group.

        ``remoteRule`` controls where the Rule object is created if the peer is also a
        securityGroup and they are in different stack. If false (default) the
        rule object is created under the current SecurityGroup object. If true and the
        peer is also a SecurityGroup, the rule object is created under the remote
        SecurityGroup object.

        :param peer: -
        :param connection: -
        :param description: -
        :param remote_rule: -
        '''
        ...


class _ISecurityGroupProxy(
    jsii.proxy_for(aws_cdk.core.IResource), # type: ignore[misc]
    jsii.proxy_for(IPeer), # type: ignore[misc]
):
    '''Interface for security group-like objects.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.ISecurityGroup"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="allowAllOutbound")
    def allow_all_outbound(self) -> builtins.bool:
        '''Whether the SecurityGroup has been configured to allow all outbound traffic.'''
        return typing.cast(builtins.bool, jsii.get(self, "allowAllOutbound"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroupId")
    def security_group_id(self) -> builtins.str:
        '''ID for the current security group.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "securityGroupId"))

    @jsii.member(jsii_name="addEgressRule")
    def add_egress_rule(
        self,
        peer: IPeer,
        connection: "Port",
        description: typing.Optional[builtins.str] = None,
        remote_rule: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Add an egress rule for the current security group.

        ``remoteRule`` controls where the Rule object is created if the peer is also a
        securityGroup and they are in different stack. If false (default) the
        rule object is created under the current SecurityGroup object. If true and the
        peer is also a SecurityGroup, the rule object is created under the remote
        SecurityGroup object.

        :param peer: -
        :param connection: -
        :param description: -
        :param remote_rule: -
        '''
        return typing.cast(None, jsii.invoke(self, "addEgressRule", [peer, connection, description, remote_rule]))

    @jsii.member(jsii_name="addIngressRule")
    def add_ingress_rule(
        self,
        peer: IPeer,
        connection: "Port",
        description: typing.Optional[builtins.str] = None,
        remote_rule: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Add an ingress rule for the current security group.

        ``remoteRule`` controls where the Rule object is created if the peer is also a
        securityGroup and they are in different stack. If false (default) the
        rule object is created under the current SecurityGroup object. If true and the
        peer is also a SecurityGroup, the rule object is created under the remote
        SecurityGroup object.

        :param peer: -
        :param connection: -
        :param description: -
        :param remote_rule: -
        '''
        return typing.cast(None, jsii.invoke(self, "addIngressRule", [peer, connection, description, remote_rule]))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.ISubnet")
class ISubnet(aws_cdk.core.IResource, typing_extensions.Protocol):
    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_ISubnetProxy"]:
        return _ISubnetProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> builtins.str:
        '''The Availability Zone the subnet is located in.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="internetConnectivityEstablished")
    def internet_connectivity_established(self) -> aws_cdk.core.IDependable:
        '''Dependable that can be depended upon to force internet connectivity established on the VPC.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipv4CidrBlock")
    def ipv4_cidr_block(self) -> builtins.str:
        '''The IPv4 CIDR block for this subnet.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="routeTable")
    def route_table(self) -> IRouteTable:
        '''The route table for this subnet.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetId")
    def subnet_id(self) -> builtins.str:
        '''The subnetId for this particular subnet.

        :attribute: true
        '''
        ...

    @jsii.member(jsii_name="associateNetworkAcl")
    def associate_network_acl(self, id: builtins.str, acl: INetworkAcl) -> None:
        '''Associate a Network ACL with this subnet.

        :param id: -
        :param acl: The Network ACL to associate.
        '''
        ...


class _ISubnetProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.ISubnet"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> builtins.str:
        '''The Availability Zone the subnet is located in.'''
        return typing.cast(builtins.str, jsii.get(self, "availabilityZone"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="internetConnectivityEstablished")
    def internet_connectivity_established(self) -> aws_cdk.core.IDependable:
        '''Dependable that can be depended upon to force internet connectivity established on the VPC.'''
        return typing.cast(aws_cdk.core.IDependable, jsii.get(self, "internetConnectivityEstablished"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipv4CidrBlock")
    def ipv4_cidr_block(self) -> builtins.str:
        '''The IPv4 CIDR block for this subnet.'''
        return typing.cast(builtins.str, jsii.get(self, "ipv4CidrBlock"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="routeTable")
    def route_table(self) -> IRouteTable:
        '''The route table for this subnet.'''
        return typing.cast(IRouteTable, jsii.get(self, "routeTable"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetId")
    def subnet_id(self) -> builtins.str:
        '''The subnetId for this particular subnet.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetId"))

    @jsii.member(jsii_name="associateNetworkAcl")
    def associate_network_acl(self, id: builtins.str, acl: INetworkAcl) -> None:
        '''Associate a Network ACL with this subnet.

        :param id: -
        :param acl: The Network ACL to associate.
        '''
        return typing.cast(None, jsii.invoke(self, "associateNetworkAcl", [id, acl]))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.ISubnetNetworkAclAssociation")
class ISubnetNetworkAclAssociation(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''(experimental) A SubnetNetworkAclAssociation.

    :stability: experimental
    '''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_ISubnetNetworkAclAssociationProxy"]:
        return _ISubnetNetworkAclAssociationProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetNetworkAclAssociationAssociationId")
    def subnet_network_acl_association_association_id(self) -> builtins.str:
        '''(experimental) ID for the current SubnetNetworkAclAssociation.

        :stability: experimental
        :attribute: true
        '''
        ...


class _ISubnetNetworkAclAssociationProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''(experimental) A SubnetNetworkAclAssociation.

    :stability: experimental
    '''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.ISubnetNetworkAclAssociation"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetNetworkAclAssociationAssociationId")
    def subnet_network_acl_association_association_id(self) -> builtins.str:
        '''(experimental) ID for the current SubnetNetworkAclAssociation.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetNetworkAclAssociationAssociationId"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IVolume")
class IVolume(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''An EBS Volume in AWS EC2.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IVolumeProxy"]:
        return _IVolumeProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> builtins.str:
        '''The availability zone that the EBS Volume is contained within (ex: us-west-2a).'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="volumeId")
    def volume_id(self) -> builtins.str:
        '''The EBS Volume's ID.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="encryptionKey")
    def encryption_key(self) -> typing.Optional[aws_cdk.aws_kms.IKey]:
        '''The customer-managed encryption key that is used to encrypt the Volume.

        :attribute: true
        '''
        ...

    @jsii.member(jsii_name="grantAttachVolume")
    def grant_attach_volume(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        instances: typing.Optional[typing.List[IInstance]] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to attach this Volume to an instance.

        CAUTION: Granting an instance permission to attach to itself using this method will lead to
        an unresolvable circular reference between the instance role and the instance.
        Use {@link IVolume.grantAttachVolumeToSelf} to grant an instance permission to attach this
        volume to itself.

        :param grantee: the principal being granted permission.
        :param instances: the instances to which permission is being granted to attach this volume to. If not specified, then permission is granted to attach to all instances in this account.
        '''
        ...

    @jsii.member(jsii_name="grantAttachVolumeByResourceTag")
    def grant_attach_volume_by_resource_tag(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        constructs: typing.List[constructs.Construct],
        tag_key_suffix: typing.Optional[builtins.str] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to attach the Volume by a ResourceTag condition.

        If you are looking to
        grant an Instance, AutoScalingGroup, EC2-Fleet, SpotFleet, ECS host, etc the ability to attach
        this volume to **itself** then this is the method you want to use.

        This is implemented by adding a Tag with key ``VolumeGrantAttach-<suffix>`` to the given
        constructs and this Volume, and then conditioning the Grant such that the grantee is only
        given the ability to AttachVolume if both the Volume and the destination Instance have that
        tag applied to them.

        :param grantee: the principal being granted permission.
        :param constructs: The list of constructs that will have the generated resource tag applied to them.
        :param tag_key_suffix: A suffix to use on the generated Tag key in place of the generated hash value. Defaults to a hash calculated from this volume and list of constructs. (DEPRECATED)
        '''
        ...

    @jsii.member(jsii_name="grantDetachVolume")
    def grant_detach_volume(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        instances: typing.Optional[typing.List[IInstance]] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to detach this Volume from an instance CAUTION: Granting an instance permission to detach from itself using this method will lead to an unresolvable circular reference between the instance role and the instance.

        Use {@link IVolume.grantDetachVolumeFromSelf} to grant an instance permission to detach this
        volume from itself.

        :param grantee: the principal being granted permission.
        :param instances: the instances to which permission is being granted to detach this volume from. If not specified, then permission is granted to detach from all instances in this account.
        '''
        ...

    @jsii.member(jsii_name="grantDetachVolumeByResourceTag")
    def grant_detach_volume_by_resource_tag(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        constructs: typing.List[constructs.Construct],
        tag_key_suffix: typing.Optional[builtins.str] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to detach the Volume by a ResourceTag condition.

        This is implemented via the same mechanism as {@link IVolume.grantAttachVolumeByResourceTag},
        and is subject to the same conditions.

        :param grantee: the principal being granted permission.
        :param constructs: The list of constructs that will have the generated resource tag applied to them.
        :param tag_key_suffix: A suffix to use on the generated Tag key in place of the generated hash value. Defaults to a hash calculated from this volume and list of constructs. (DEPRECATED)
        '''
        ...


class _IVolumeProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''An EBS Volume in AWS EC2.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IVolume"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> builtins.str:
        '''The availability zone that the EBS Volume is contained within (ex: us-west-2a).'''
        return typing.cast(builtins.str, jsii.get(self, "availabilityZone"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="volumeId")
    def volume_id(self) -> builtins.str:
        '''The EBS Volume's ID.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "volumeId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="encryptionKey")
    def encryption_key(self) -> typing.Optional[aws_cdk.aws_kms.IKey]:
        '''The customer-managed encryption key that is used to encrypt the Volume.

        :attribute: true
        '''
        return typing.cast(typing.Optional[aws_cdk.aws_kms.IKey], jsii.get(self, "encryptionKey"))

    @jsii.member(jsii_name="grantAttachVolume")
    def grant_attach_volume(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        instances: typing.Optional[typing.List[IInstance]] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to attach this Volume to an instance.

        CAUTION: Granting an instance permission to attach to itself using this method will lead to
        an unresolvable circular reference between the instance role and the instance.
        Use {@link IVolume.grantAttachVolumeToSelf} to grant an instance permission to attach this
        volume to itself.

        :param grantee: the principal being granted permission.
        :param instances: the instances to which permission is being granted to attach this volume to. If not specified, then permission is granted to attach to all instances in this account.
        '''
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantAttachVolume", [grantee, instances]))

    @jsii.member(jsii_name="grantAttachVolumeByResourceTag")
    def grant_attach_volume_by_resource_tag(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        constructs: typing.List[constructs.Construct],
        tag_key_suffix: typing.Optional[builtins.str] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to attach the Volume by a ResourceTag condition.

        If you are looking to
        grant an Instance, AutoScalingGroup, EC2-Fleet, SpotFleet, ECS host, etc the ability to attach
        this volume to **itself** then this is the method you want to use.

        This is implemented by adding a Tag with key ``VolumeGrantAttach-<suffix>`` to the given
        constructs and this Volume, and then conditioning the Grant such that the grantee is only
        given the ability to AttachVolume if both the Volume and the destination Instance have that
        tag applied to them.

        :param grantee: the principal being granted permission.
        :param constructs: The list of constructs that will have the generated resource tag applied to them.
        :param tag_key_suffix: A suffix to use on the generated Tag key in place of the generated hash value. Defaults to a hash calculated from this volume and list of constructs. (DEPRECATED)
        '''
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantAttachVolumeByResourceTag", [grantee, constructs, tag_key_suffix]))

    @jsii.member(jsii_name="grantDetachVolume")
    def grant_detach_volume(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        instances: typing.Optional[typing.List[IInstance]] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to detach this Volume from an instance CAUTION: Granting an instance permission to detach from itself using this method will lead to an unresolvable circular reference between the instance role and the instance.

        Use {@link IVolume.grantDetachVolumeFromSelf} to grant an instance permission to detach this
        volume from itself.

        :param grantee: the principal being granted permission.
        :param instances: the instances to which permission is being granted to detach this volume from. If not specified, then permission is granted to detach from all instances in this account.
        '''
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantDetachVolume", [grantee, instances]))

    @jsii.member(jsii_name="grantDetachVolumeByResourceTag")
    def grant_detach_volume_by_resource_tag(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        constructs: typing.List[constructs.Construct],
        tag_key_suffix: typing.Optional[builtins.str] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to detach the Volume by a ResourceTag condition.

        This is implemented via the same mechanism as {@link IVolume.grantAttachVolumeByResourceTag},
        and is subject to the same conditions.

        :param grantee: the principal being granted permission.
        :param constructs: The list of constructs that will have the generated resource tag applied to them.
        :param tag_key_suffix: A suffix to use on the generated Tag key in place of the generated hash value. Defaults to a hash calculated from this volume and list of constructs. (DEPRECATED)
        '''
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantDetachVolumeByResourceTag", [grantee, constructs, tag_key_suffix]))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IVpc")
class IVpc(aws_cdk.core.IResource, typing_extensions.Protocol):
    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IVpcProxy"]:
        return _IVpcProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZones")
    def availability_zones(self) -> typing.List[builtins.str]:
        '''AZs for this VPC.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="internetConnectivityEstablished")
    def internet_connectivity_established(self) -> aws_cdk.core.IDependable:
        '''Dependable that can be depended upon to force internet connectivity established on the VPC.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="isolatedSubnets")
    def isolated_subnets(self) -> typing.List[ISubnet]:
        '''List of isolated subnets in this VPC.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateSubnets")
    def private_subnets(self) -> typing.List[ISubnet]:
        '''List of private subnets in this VPC.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="publicSubnets")
    def public_subnets(self) -> typing.List[ISubnet]:
        '''List of public subnets in this VPC.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcCidrBlock")
    def vpc_cidr_block(self) -> builtins.str:
        '''CIDR range for this VPC.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''Identifier for this VPC.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnGatewayId")
    def vpn_gateway_id(self) -> typing.Optional[builtins.str]:
        '''Identifier for the VPN gateway.'''
        ...

    @jsii.member(jsii_name="addFlowLog")
    def add_flow_log(
        self,
        id: builtins.str,
        *,
        destination: typing.Optional[FlowLogDestination] = None,
        traffic_type: typing.Optional[FlowLogTrafficType] = None,
    ) -> "FlowLog":
        '''Adds a new Flow Log to this VPC.

        :param id: -
        :param destination: (experimental) Specifies the type of destination to which the flow log data is to be published. Flow log data can be published to CloudWatch Logs or Amazon S3 Default: FlowLogDestinationType.toCloudWatchLogs()
        :param traffic_type: (experimental) The type of traffic to log. You can log traffic that the resource accepts or rejects, or all traffic. Default: ALL
        '''
        ...

    @jsii.member(jsii_name="addGatewayEndpoint")
    def add_gateway_endpoint(
        self,
        id: builtins.str,
        *,
        service: IGatewayVpcEndpointService,
        subnets: typing.Optional[typing.List["SubnetSelection"]] = None,
    ) -> "GatewayVpcEndpoint":
        '''Adds a new gateway endpoint to this VPC.

        :param id: -
        :param service: The service to use for this gateway VPC endpoint.
        :param subnets: Where to add endpoint routing. By default, this endpoint will be routable from all subnets in the VPC. Specify a list of subnet selection objects here to be more specific. Default: - All subnets in the VPC
        '''
        ...

    @jsii.member(jsii_name="addInterfaceEndpoint")
    def add_interface_endpoint(
        self,
        id: builtins.str,
        *,
        service: IInterfaceVpcEndpointService,
        lookup_supported_azs: typing.Optional[builtins.bool] = None,
        open: typing.Optional[builtins.bool] = None,
        private_dns_enabled: typing.Optional[builtins.bool] = None,
        security_groups: typing.Optional[typing.List[ISecurityGroup]] = None,
        subnets: typing.Optional["SubnetSelection"] = None,
    ) -> "InterfaceVpcEndpoint":
        '''Adds a new interface endpoint to this VPC.

        :param id: -
        :param service: The service to use for this interface VPC endpoint.
        :param lookup_supported_azs: Limit to only those availability zones where the endpoint service can be created. Setting this to 'true' requires a lookup to be performed at synthesis time. Account and region must be set on the containing stack for this to work. Default: false
        :param open: Whether to automatically allow VPC traffic to the endpoint. If enabled, all traffic to the endpoint from within the VPC will be automatically allowed. This is done based on the VPC's CIDR range. Default: true
        :param private_dns_enabled: Whether to associate a private hosted zone with the specified VPC. This allows you to make requests to the service using its default DNS hostname. Default: set by the instance of IInterfaceVpcEndpointService, or true if not defined by the instance of IInterfaceVpcEndpointService
        :param security_groups: The security groups to associate with this interface VPC endpoint. Default: - a new security group is created
        :param subnets: The subnets in which to create an endpoint network interface. At most one per availability zone. Default: - private subnets
        '''
        ...

    @jsii.member(jsii_name="addVpnConnection")
    def add_vpn_connection(
        self,
        id: builtins.str,
        *,
        ip: builtins.str,
        asn: typing.Optional[jsii.Number] = None,
        static_routes: typing.Optional[typing.List[builtins.str]] = None,
        tunnel_options: typing.Optional[typing.List["VpnTunnelOption"]] = None,
    ) -> "VpnConnection":
        '''Adds a new VPN connection to this VPC.

        :param id: -
        :param ip: The ip address of the customer gateway.
        :param asn: The ASN of the customer gateway. Default: 65000
        :param static_routes: The static routes to be routed from the VPN gateway to the customer gateway. Default: Dynamic routing (BGP)
        :param tunnel_options: The tunnel options for the VPN connection. At most two elements (one per tunnel). Duplicates not allowed. Default: Amazon generated tunnel options
        '''
        ...

    @jsii.member(jsii_name="enableVpnGateway")
    def enable_vpn_gateway(
        self,
        *,
        vpn_route_propagation: typing.Optional[typing.List["SubnetSelection"]] = None,
        type: builtins.str,
        amazon_side_asn: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Adds a VPN Gateway to this VPC.

        :param vpn_route_propagation: Provide an array of subnets where the route propagation should be added. Default: noPropagation
        :param type: Default type ipsec.1.
        :param amazon_side_asn: Explicitly specify an Asn or let aws pick an Asn for you. Default: 65000
        '''
        ...

    @jsii.member(jsii_name="selectSubnets")
    def select_subnets(
        self,
        *,
        availability_zones: typing.Optional[typing.List[builtins.str]] = None,
        one_per_az: typing.Optional[builtins.bool] = None,
        subnet_filters: typing.Optional[typing.List["SubnetFilter"]] = None,
        subnet_group_name: typing.Optional[builtins.str] = None,
        subnet_name: typing.Optional[builtins.str] = None,
        subnets: typing.Optional[typing.List[ISubnet]] = None,
        subnet_type: typing.Optional["SubnetType"] = None,
    ) -> "SelectedSubnets":
        '''Return information on the subnets appropriate for the given selection strategy.

        Requires that at least one subnet is matched, throws a descriptive
        error message otherwise.

        :param availability_zones: Select subnets only in the given AZs. Default: no filtering on AZs is done
        :param one_per_az: If true, return at most one subnet per AZ. Default: false
        :param subnet_filters: List of provided subnet filters. Default: - none
        :param subnet_group_name: Select the subnet group with the given name. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them. Otherwise, prefer ``subnetType``. This field does not select individual subnets, it selects all subnets that share the given subnet group name. This is the name supplied in ``subnetConfiguration``. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: - Selection by type instead of by name
        :param subnet_name: (deprecated) Alias for ``subnetGroupName``. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them.
        :param subnets: Explicitly select individual subnets. Use this if you don't want to automatically use all subnets in a group, but have a need to control selection down to individual subnets. Cannot be specified together with ``subnetType`` or ``subnetGroupName``. Default: - Use all subnets in a selected group (all private subnets by default)
        :param subnet_type: Select all subnets of the given type. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: SubnetType.PRIVATE (or ISOLATED or PUBLIC if there are no PRIVATE subnets)
        '''
        ...


class _IVpcProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IVpc"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZones")
    def availability_zones(self) -> typing.List[builtins.str]:
        '''AZs for this VPC.'''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "availabilityZones"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="internetConnectivityEstablished")
    def internet_connectivity_established(self) -> aws_cdk.core.IDependable:
        '''Dependable that can be depended upon to force internet connectivity established on the VPC.'''
        return typing.cast(aws_cdk.core.IDependable, jsii.get(self, "internetConnectivityEstablished"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="isolatedSubnets")
    def isolated_subnets(self) -> typing.List[ISubnet]:
        '''List of isolated subnets in this VPC.'''
        return typing.cast(typing.List[ISubnet], jsii.get(self, "isolatedSubnets"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateSubnets")
    def private_subnets(self) -> typing.List[ISubnet]:
        '''List of private subnets in this VPC.'''
        return typing.cast(typing.List[ISubnet], jsii.get(self, "privateSubnets"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="publicSubnets")
    def public_subnets(self) -> typing.List[ISubnet]:
        '''List of public subnets in this VPC.'''
        return typing.cast(typing.List[ISubnet], jsii.get(self, "publicSubnets"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcCidrBlock")
    def vpc_cidr_block(self) -> builtins.str:
        '''CIDR range for this VPC.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcCidrBlock"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''Identifier for this VPC.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnGatewayId")
    def vpn_gateway_id(self) -> typing.Optional[builtins.str]:
        '''Identifier for the VPN gateway.'''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "vpnGatewayId"))

    @jsii.member(jsii_name="addFlowLog")
    def add_flow_log(
        self,
        id: builtins.str,
        *,
        destination: typing.Optional[FlowLogDestination] = None,
        traffic_type: typing.Optional[FlowLogTrafficType] = None,
    ) -> "FlowLog":
        '''Adds a new Flow Log to this VPC.

        :param id: -
        :param destination: (experimental) Specifies the type of destination to which the flow log data is to be published. Flow log data can be published to CloudWatch Logs or Amazon S3 Default: FlowLogDestinationType.toCloudWatchLogs()
        :param traffic_type: (experimental) The type of traffic to log. You can log traffic that the resource accepts or rejects, or all traffic. Default: ALL
        '''
        options = FlowLogOptions(destination=destination, traffic_type=traffic_type)

        return typing.cast("FlowLog", jsii.invoke(self, "addFlowLog", [id, options]))

    @jsii.member(jsii_name="addGatewayEndpoint")
    def add_gateway_endpoint(
        self,
        id: builtins.str,
        *,
        service: IGatewayVpcEndpointService,
        subnets: typing.Optional[typing.List["SubnetSelection"]] = None,
    ) -> "GatewayVpcEndpoint":
        '''Adds a new gateway endpoint to this VPC.

        :param id: -
        :param service: The service to use for this gateway VPC endpoint.
        :param subnets: Where to add endpoint routing. By default, this endpoint will be routable from all subnets in the VPC. Specify a list of subnet selection objects here to be more specific. Default: - All subnets in the VPC
        '''
        options = GatewayVpcEndpointOptions(service=service, subnets=subnets)

        return typing.cast("GatewayVpcEndpoint", jsii.invoke(self, "addGatewayEndpoint", [id, options]))

    @jsii.member(jsii_name="addInterfaceEndpoint")
    def add_interface_endpoint(
        self,
        id: builtins.str,
        *,
        service: IInterfaceVpcEndpointService,
        lookup_supported_azs: typing.Optional[builtins.bool] = None,
        open: typing.Optional[builtins.bool] = None,
        private_dns_enabled: typing.Optional[builtins.bool] = None,
        security_groups: typing.Optional[typing.List[ISecurityGroup]] = None,
        subnets: typing.Optional["SubnetSelection"] = None,
    ) -> "InterfaceVpcEndpoint":
        '''Adds a new interface endpoint to this VPC.

        :param id: -
        :param service: The service to use for this interface VPC endpoint.
        :param lookup_supported_azs: Limit to only those availability zones where the endpoint service can be created. Setting this to 'true' requires a lookup to be performed at synthesis time. Account and region must be set on the containing stack for this to work. Default: false
        :param open: Whether to automatically allow VPC traffic to the endpoint. If enabled, all traffic to the endpoint from within the VPC will be automatically allowed. This is done based on the VPC's CIDR range. Default: true
        :param private_dns_enabled: Whether to associate a private hosted zone with the specified VPC. This allows you to make requests to the service using its default DNS hostname. Default: set by the instance of IInterfaceVpcEndpointService, or true if not defined by the instance of IInterfaceVpcEndpointService
        :param security_groups: The security groups to associate with this interface VPC endpoint. Default: - a new security group is created
        :param subnets: The subnets in which to create an endpoint network interface. At most one per availability zone. Default: - private subnets
        '''
        options = InterfaceVpcEndpointOptions(
            service=service,
            lookup_supported_azs=lookup_supported_azs,
            open=open,
            private_dns_enabled=private_dns_enabled,
            security_groups=security_groups,
            subnets=subnets,
        )

        return typing.cast("InterfaceVpcEndpoint", jsii.invoke(self, "addInterfaceEndpoint", [id, options]))

    @jsii.member(jsii_name="addVpnConnection")
    def add_vpn_connection(
        self,
        id: builtins.str,
        *,
        ip: builtins.str,
        asn: typing.Optional[jsii.Number] = None,
        static_routes: typing.Optional[typing.List[builtins.str]] = None,
        tunnel_options: typing.Optional[typing.List["VpnTunnelOption"]] = None,
    ) -> "VpnConnection":
        '''Adds a new VPN connection to this VPC.

        :param id: -
        :param ip: The ip address of the customer gateway.
        :param asn: The ASN of the customer gateway. Default: 65000
        :param static_routes: The static routes to be routed from the VPN gateway to the customer gateway. Default: Dynamic routing (BGP)
        :param tunnel_options: The tunnel options for the VPN connection. At most two elements (one per tunnel). Duplicates not allowed. Default: Amazon generated tunnel options
        '''
        options = VpnConnectionOptions(
            ip=ip, asn=asn, static_routes=static_routes, tunnel_options=tunnel_options
        )

        return typing.cast("VpnConnection", jsii.invoke(self, "addVpnConnection", [id, options]))

    @jsii.member(jsii_name="enableVpnGateway")
    def enable_vpn_gateway(
        self,
        *,
        vpn_route_propagation: typing.Optional[typing.List["SubnetSelection"]] = None,
        type: builtins.str,
        amazon_side_asn: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Adds a VPN Gateway to this VPC.

        :param vpn_route_propagation: Provide an array of subnets where the route propagation should be added. Default: noPropagation
        :param type: Default type ipsec.1.
        :param amazon_side_asn: Explicitly specify an Asn or let aws pick an Asn for you. Default: 65000
        '''
        options = EnableVpnGatewayOptions(
            vpn_route_propagation=vpn_route_propagation,
            type=type,
            amazon_side_asn=amazon_side_asn,
        )

        return typing.cast(None, jsii.invoke(self, "enableVpnGateway", [options]))

    @jsii.member(jsii_name="selectSubnets")
    def select_subnets(
        self,
        *,
        availability_zones: typing.Optional[typing.List[builtins.str]] = None,
        one_per_az: typing.Optional[builtins.bool] = None,
        subnet_filters: typing.Optional[typing.List["SubnetFilter"]] = None,
        subnet_group_name: typing.Optional[builtins.str] = None,
        subnet_name: typing.Optional[builtins.str] = None,
        subnets: typing.Optional[typing.List[ISubnet]] = None,
        subnet_type: typing.Optional["SubnetType"] = None,
    ) -> "SelectedSubnets":
        '''Return information on the subnets appropriate for the given selection strategy.

        Requires that at least one subnet is matched, throws a descriptive
        error message otherwise.

        :param availability_zones: Select subnets only in the given AZs. Default: no filtering on AZs is done
        :param one_per_az: If true, return at most one subnet per AZ. Default: false
        :param subnet_filters: List of provided subnet filters. Default: - none
        :param subnet_group_name: Select the subnet group with the given name. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them. Otherwise, prefer ``subnetType``. This field does not select individual subnets, it selects all subnets that share the given subnet group name. This is the name supplied in ``subnetConfiguration``. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: - Selection by type instead of by name
        :param subnet_name: (deprecated) Alias for ``subnetGroupName``. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them.
        :param subnets: Explicitly select individual subnets. Use this if you don't want to automatically use all subnets in a group, but have a need to control selection down to individual subnets. Cannot be specified together with ``subnetType`` or ``subnetGroupName``. Default: - Use all subnets in a selected group (all private subnets by default)
        :param subnet_type: Select all subnets of the given type. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: SubnetType.PRIVATE (or ISOLATED or PUBLIC if there are no PRIVATE subnets)
        '''
        selection = SubnetSelection(
            availability_zones=availability_zones,
            one_per_az=one_per_az,
            subnet_filters=subnet_filters,
            subnet_group_name=subnet_group_name,
            subnet_name=subnet_name,
            subnets=subnets,
            subnet_type=subnet_type,
        )

        return typing.cast("SelectedSubnets", jsii.invoke(self, "selectSubnets", [selection]))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IVpcEndpoint")
class IVpcEndpoint(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''A VPC endpoint.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IVpcEndpointProxy"]:
        return _IVpcEndpointProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointId")
    def vpc_endpoint_id(self) -> builtins.str:
        '''The VPC endpoint identifier.

        :attribute: true
        '''
        ...


class _IVpcEndpointProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''A VPC endpoint.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IVpcEndpoint"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointId")
    def vpc_endpoint_id(self) -> builtins.str:
        '''The VPC endpoint identifier.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcEndpointId"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IVpcEndpointService")
class IVpcEndpointService(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''(experimental) A VPC endpoint service.

    :stability: experimental
    '''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IVpcEndpointServiceProxy"]:
        return _IVpcEndpointServiceProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointServiceId")
    def vpc_endpoint_service_id(self) -> builtins.str:
        '''(experimental) The id of the VPC Endpoint Service that clients use to connect to, like vpce-svc-xxxxxxxxxxxxxxxx.

        :stability: experimental
        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointServiceName")
    def vpc_endpoint_service_name(self) -> builtins.str:
        '''(experimental) The service name of the VPC Endpoint Service that clients use to connect to, like com.amazonaws.vpce..vpce-svc-xxxxxxxxxxxxxxxx.

        :stability: experimental
        :attribute: true
        '''
        ...


class _IVpcEndpointServiceProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''(experimental) A VPC endpoint service.

    :stability: experimental
    '''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IVpcEndpointService"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointServiceId")
    def vpc_endpoint_service_id(self) -> builtins.str:
        '''(experimental) The id of the VPC Endpoint Service that clients use to connect to, like vpce-svc-xxxxxxxxxxxxxxxx.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcEndpointServiceId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointServiceName")
    def vpc_endpoint_service_name(self) -> builtins.str:
        '''(experimental) The service name of the VPC Endpoint Service that clients use to connect to, like com.amazonaws.vpce..vpce-svc-xxxxxxxxxxxxxxxx.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcEndpointServiceName"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IVpcEndpointServiceLoadBalancer")
class IVpcEndpointServiceLoadBalancer(typing_extensions.Protocol):
    '''A load balancer that can host a VPC Endpoint Service.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IVpcEndpointServiceLoadBalancerProxy"]:
        return _IVpcEndpointServiceLoadBalancerProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="loadBalancerArn")
    def load_balancer_arn(self) -> builtins.str:
        '''The ARN of the load balancer that hosts the VPC Endpoint Service.'''
        ...


class _IVpcEndpointServiceLoadBalancerProxy:
    '''A load balancer that can host a VPC Endpoint Service.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IVpcEndpointServiceLoadBalancer"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="loadBalancerArn")
    def load_balancer_arn(self) -> builtins.str:
        '''The ARN of the load balancer that hosts the VPC Endpoint Service.'''
        return typing.cast(builtins.str, jsii.get(self, "loadBalancerArn"))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IVpnConnection")
class IVpnConnection(aws_cdk.core.IResource, typing_extensions.Protocol):
    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IVpnConnectionProxy"]:
        return _IVpnConnectionProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="customerGatewayAsn")
    def customer_gateway_asn(self) -> jsii.Number:
        '''The ASN of the customer gateway.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="customerGatewayId")
    def customer_gateway_id(self) -> builtins.str:
        '''The id of the customer gateway.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="customerGatewayIp")
    def customer_gateway_ip(self) -> builtins.str:
        '''The ip address of the customer gateway.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnId")
    def vpn_id(self) -> builtins.str:
        '''The id of the VPN connection.'''
        ...

    @jsii.member(jsii_name="metric")
    def metric(
        self,
        metric_name: builtins.str,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''Return the given named metric for this VPNConnection.

        :param metric_name: -
        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        ...

    @jsii.member(jsii_name="metricTunnelDataIn")
    def metric_tunnel_data_in(
        self,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''The bytes received through the VPN tunnel.

        Sum over 5 minutes

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        ...

    @jsii.member(jsii_name="metricTunnelDataOut")
    def metric_tunnel_data_out(
        self,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''The bytes sent through the VPN tunnel.

        Sum over 5 minutes

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        ...

    @jsii.member(jsii_name="metricTunnelState")
    def metric_tunnel_state(
        self,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''The state of the tunnel. 0 indicates DOWN and 1 indicates UP.

        Average over 5 minutes

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        ...


class _IVpnConnectionProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IVpnConnection"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="customerGatewayAsn")
    def customer_gateway_asn(self) -> jsii.Number:
        '''The ASN of the customer gateway.'''
        return typing.cast(jsii.Number, jsii.get(self, "customerGatewayAsn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="customerGatewayId")
    def customer_gateway_id(self) -> builtins.str:
        '''The id of the customer gateway.'''
        return typing.cast(builtins.str, jsii.get(self, "customerGatewayId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="customerGatewayIp")
    def customer_gateway_ip(self) -> builtins.str:
        '''The ip address of the customer gateway.'''
        return typing.cast(builtins.str, jsii.get(self, "customerGatewayIp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnId")
    def vpn_id(self) -> builtins.str:
        '''The id of the VPN connection.'''
        return typing.cast(builtins.str, jsii.get(self, "vpnId"))

    @jsii.member(jsii_name="metric")
    def metric(
        self,
        metric_name: builtins.str,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''Return the given named metric for this VPNConnection.

        :param metric_name: -
        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.invoke(self, "metric", [metric_name, props]))

    @jsii.member(jsii_name="metricTunnelDataIn")
    def metric_tunnel_data_in(
        self,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''The bytes received through the VPN tunnel.

        Sum over 5 minutes

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.invoke(self, "metricTunnelDataIn", [props]))

    @jsii.member(jsii_name="metricTunnelDataOut")
    def metric_tunnel_data_out(
        self,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''The bytes sent through the VPN tunnel.

        Sum over 5 minutes

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.invoke(self, "metricTunnelDataOut", [props]))

    @jsii.member(jsii_name="metricTunnelState")
    def metric_tunnel_state(
        self,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''The state of the tunnel. 0 indicates DOWN and 1 indicates UP.

        Average over 5 minutes

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.invoke(self, "metricTunnelState", [props]))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IVpnGateway")
class IVpnGateway(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''The virtual private gateway interface.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IVpnGatewayProxy"]:
        return _IVpnGatewayProxy

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="gatewayId")
    def gateway_id(self) -> builtins.str:
        '''The virtual private gateway Id.'''
        ...


class _IVpnGatewayProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''The virtual private gateway interface.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IVpnGateway"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="gatewayId")
    def gateway_id(self) -> builtins.str:
        '''The virtual private gateway Id.'''
        return typing.cast(builtins.str, jsii.get(self, "gatewayId"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.InitCommandOptions",
    jsii_struct_bases=[],
    name_mapping={
        "cwd": "cwd",
        "env": "env",
        "ignore_errors": "ignoreErrors",
        "key": "key",
        "service_restart_handles": "serviceRestartHandles",
        "test_cmd": "testCmd",
        "wait_after_completion": "waitAfterCompletion",
    },
)
class InitCommandOptions:
    def __init__(
        self,
        *,
        cwd: typing.Optional[builtins.str] = None,
        env: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        ignore_errors: typing.Optional[builtins.bool] = None,
        key: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
        test_cmd: typing.Optional[builtins.str] = None,
        wait_after_completion: typing.Optional["InitCommandWaitDuration"] = None,
    ) -> None:
        '''Options for InitCommand.

        :param cwd: The working directory. Default: - Use default working directory
        :param env: Sets environment variables for the command. This property overwrites, rather than appends, the existing environment. Default: - Use current environment
        :param ignore_errors: Continue running if this command fails. Default: false
        :param key: Identifier key for this command. Commands are executed in lexicographical order of their key names. Default: - Automatically generated based on index
        :param service_restart_handles: Restart the given service(s) after this command has run. Default: - Do not restart any service
        :param test_cmd: Command to determine whether this command should be run. If the test passes (exits with error code of 0), the command is run. Default: - Always run the command
        :param wait_after_completion: The duration to wait after a command has finished in case the command causes a reboot. Set this value to ``InitCommandWaitDuration.none()`` if you do not want to wait for every command; ``InitCommandWaitDuration.forever()`` directs cfn-init to exit and resume only after the reboot is complete. For Windows systems only. Default: - 60 seconds
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if cwd is not None:
            self._values["cwd"] = cwd
        if env is not None:
            self._values["env"] = env
        if ignore_errors is not None:
            self._values["ignore_errors"] = ignore_errors
        if key is not None:
            self._values["key"] = key
        if service_restart_handles is not None:
            self._values["service_restart_handles"] = service_restart_handles
        if test_cmd is not None:
            self._values["test_cmd"] = test_cmd
        if wait_after_completion is not None:
            self._values["wait_after_completion"] = wait_after_completion

    @builtins.property
    def cwd(self) -> typing.Optional[builtins.str]:
        '''The working directory.

        :default: - Use default working directory
        '''
        result = self._values.get("cwd")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def env(self) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Sets environment variables for the command.

        This property overwrites, rather than appends, the existing environment.

        :default: - Use current environment
        '''
        result = self._values.get("env")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def ignore_errors(self) -> typing.Optional[builtins.bool]:
        '''Continue running if this command fails.

        :default: false
        '''
        result = self._values.get("ignore_errors")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def key(self) -> typing.Optional[builtins.str]:
        '''Identifier key for this command.

        Commands are executed in lexicographical order of their key names.

        :default: - Automatically generated based on index
        '''
        result = self._values.get("key")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def service_restart_handles(
        self,
    ) -> typing.Optional[typing.List["InitServiceRestartHandle"]]:
        '''Restart the given service(s) after this command has run.

        :default: - Do not restart any service
        '''
        result = self._values.get("service_restart_handles")
        return typing.cast(typing.Optional[typing.List["InitServiceRestartHandle"]], result)

    @builtins.property
    def test_cmd(self) -> typing.Optional[builtins.str]:
        '''Command to determine whether this command should be run.

        If the test passes (exits with error code of 0), the command is run.

        :default: - Always run the command
        '''
        result = self._values.get("test_cmd")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def wait_after_completion(self) -> typing.Optional["InitCommandWaitDuration"]:
        '''The duration to wait after a command has finished in case the command causes a reboot.

        Set this value to ``InitCommandWaitDuration.none()`` if you do not want to wait for every command;
        ``InitCommandWaitDuration.forever()`` directs cfn-init to exit and resume only after the reboot is complete.

        For Windows systems only.

        :default: - 60 seconds
        '''
        result = self._values.get("wait_after_completion")
        return typing.cast(typing.Optional["InitCommandWaitDuration"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "InitCommandOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class InitCommandWaitDuration(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-ec2.InitCommandWaitDuration",
):
    '''Represents a duration to wait after a command has finished, in case of a reboot (Windows only).'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_InitCommandWaitDurationProxy"]:
        return _InitCommandWaitDurationProxy

    def __init__(self) -> None:
        jsii.create(InitCommandWaitDuration, self, [])

    @jsii.member(jsii_name="forever") # type: ignore[misc]
    @builtins.classmethod
    def forever(cls) -> "InitCommandWaitDuration":
        '''cfn-init will exit and resume only after a reboot.'''
        return typing.cast("InitCommandWaitDuration", jsii.sinvoke(cls, "forever", []))

    @jsii.member(jsii_name="none") # type: ignore[misc]
    @builtins.classmethod
    def none(cls) -> "InitCommandWaitDuration":
        '''Do not wait for this command.'''
        return typing.cast("InitCommandWaitDuration", jsii.sinvoke(cls, "none", []))

    @jsii.member(jsii_name="of") # type: ignore[misc]
    @builtins.classmethod
    def of(cls, duration: aws_cdk.core.Duration) -> "InitCommandWaitDuration":
        '''Wait for a specified duration after a command.

        :param duration: -
        '''
        return typing.cast("InitCommandWaitDuration", jsii.sinvoke(cls, "of", [duration]))


class _InitCommandWaitDurationProxy(InitCommandWaitDuration):
    pass


class InitConfig(metaclass=jsii.JSIIMeta, jsii_type="@aws-cdk/aws-ec2.InitConfig"):
    '''A collection of configuration elements.'''

    def __init__(self, elements: typing.List["InitElement"]) -> None:
        '''
        :param elements: -
        '''
        jsii.create(InitConfig, self, [elements])

    @jsii.member(jsii_name="add")
    def add(self, *elements: "InitElement") -> None:
        '''Add one or more elements to the config.

        :param elements: -
        '''
        return typing.cast(None, jsii.invoke(self, "add", [*elements]))

    @jsii.member(jsii_name="isEmpty")
    def is_empty(self) -> builtins.bool:
        '''Whether this configset has elements or not.'''
        return typing.cast(builtins.bool, jsii.invoke(self, "isEmpty", []))


class InitElement(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-ec2.InitElement",
):
    '''Base class for all CloudFormation Init elements.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_InitElementProxy"]:
        return _InitElementProxy

    def __init__(self) -> None:
        jsii.create(InitElement, self, [])

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elementType")
    @abc.abstractmethod
    def element_type(self) -> builtins.str:
        '''Returns the init element type for this element.'''
        ...


class _InitElementProxy(InitElement):
    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elementType")
    def element_type(self) -> builtins.str:
        '''Returns the init element type for this element.'''
        return typing.cast(builtins.str, jsii.get(self, "elementType"))


class InitFile(
    InitElement,
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-ec2.InitFile",
):
    '''Create files on the EC2 instance.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_InitFileProxy"]:
        return _InitFileProxy

    def __init__(
        self,
        file_name: builtins.str,
        *,
        base64_encoded: typing.Optional[builtins.bool] = None,
        group: typing.Optional[builtins.str] = None,
        mode: typing.Optional[builtins.str] = None,
        owner: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> None:
        '''
        :param file_name: -
        :param base64_encoded: True if the inlined content (from a string or file) should be treated as base64 encoded. Only applicable for inlined string and file content. Default: false
        :param group: The name of the owning group for this file. Not supported for Windows systems. Default: 'root'
        :param mode: A six-digit octal value representing the mode for this file. Use the first three digits for symlinks and the last three digits for setting permissions. To create a symlink, specify 120xxx, where xxx defines the permissions of the target file. To specify permissions for a file, use the last three digits, such as 000644. Not supported for Windows systems. Default: '000644'
        :param owner: The name of the owning user for this file. Not supported for Windows systems. Default: 'root'
        :param service_restart_handles: Restart the given service after this file has been written. Default: - Do not restart any service
        '''
        options = InitFileOptions(
            base64_encoded=base64_encoded,
            group=group,
            mode=mode,
            owner=owner,
            service_restart_handles=service_restart_handles,
        )

        jsii.create(InitFile, self, [file_name, options])

    @jsii.member(jsii_name="fromAsset") # type: ignore[misc]
    @builtins.classmethod
    def from_asset(
        cls,
        target_file_name: builtins.str,
        path: builtins.str,
        *,
        base64_encoded: typing.Optional[builtins.bool] = None,
        group: typing.Optional[builtins.str] = None,
        mode: typing.Optional[builtins.str] = None,
        owner: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
        readers: typing.Optional[typing.List[aws_cdk.aws_iam.IGrantable]] = None,
        source_hash: typing.Optional[builtins.str] = None,
        exclude: typing.Optional[typing.List[builtins.str]] = None,
        follow: typing.Optional[aws_cdk.assets.FollowMode] = None,
        ignore_mode: typing.Optional[aws_cdk.core.IgnoreMode] = None,
        asset_hash: typing.Optional[builtins.str] = None,
        asset_hash_type: typing.Optional[aws_cdk.core.AssetHashType] = None,
        bundling: typing.Optional[aws_cdk.core.BundlingOptions] = None,
    ) -> "InitFile":
        '''Create an asset from the given file.

        This is appropriate for files that are too large to embed into the template.

        :param target_file_name: -
        :param path: -
        :param base64_encoded: True if the inlined content (from a string or file) should be treated as base64 encoded. Only applicable for inlined string and file content. Default: false
        :param group: The name of the owning group for this file. Not supported for Windows systems. Default: 'root'
        :param mode: A six-digit octal value representing the mode for this file. Use the first three digits for symlinks and the last three digits for setting permissions. To create a symlink, specify 120xxx, where xxx defines the permissions of the target file. To specify permissions for a file, use the last three digits, such as 000644. Not supported for Windows systems. Default: '000644'
        :param owner: The name of the owning user for this file. Not supported for Windows systems. Default: 'root'
        :param service_restart_handles: Restart the given service after this file has been written. Default: - Do not restart any service
        :param readers: (experimental) A list of principals that should be able to read this asset from S3. You can use ``asset.grantRead(principal)`` to grant read permissions later. Default: - No principals that can read file asset.
        :param source_hash: (deprecated) Custom hash to use when identifying the specific version of the asset. For consistency, this custom hash will be SHA256 hashed and encoded as hex. The resulting hash will be the asset hash. NOTE: the source hash is used in order to identify a specific revision of the asset, and used for optimizing and caching deployment activities related to this asset such as packaging, uploading to Amazon S3, etc. If you chose to customize the source hash, you will need to make sure it is updated every time the source changes, or otherwise it is possible that some deployments will not be invalidated. Default: - automatically calculate source hash based on the contents of the source file or directory.
        :param exclude: (deprecated) Glob patterns to exclude from the copy. Default: nothing is excluded
        :param follow: (deprecated) A strategy for how to handle symlinks. Default: Never
        :param ignore_mode: (deprecated) The ignore behavior to use for exclude patterns. Default: - GLOB for file assets, DOCKER or GLOB for docker assets depending on whether the '
        :param asset_hash: Specify a custom hash for this asset. If ``assetHashType`` is set it must be set to ``AssetHashType.CUSTOM``. For consistency, this custom hash will be SHA256 hashed and encoded as hex. The resulting hash will be the asset hash. NOTE: the hash is used in order to identify a specific revision of the asset, and used for optimizing and caching deployment activities related to this asset such as packaging, uploading to Amazon S3, etc. If you chose to customize the hash, you will need to make sure it is updated every time the asset changes, or otherwise it is possible that some deployments will not be invalidated. Default: - based on ``assetHashType``
        :param asset_hash_type: Specifies the type of hash to calculate for this asset. If ``assetHash`` is configured, this option must be ``undefined`` or ``AssetHashType.CUSTOM``. Default: - the default is ``AssetHashType.SOURCE``, but if ``assetHash`` is explicitly specified this value defaults to ``AssetHashType.CUSTOM``.
        :param bundling: (experimental) Bundle the asset by executing a command in a Docker container. The asset path will be mounted at ``/asset-input``. The Docker container is responsible for putting content at ``/asset-output``. The content at ``/asset-output`` will be zipped and used as the final asset. Default: - uploaded as-is to S3 if the asset is a regular file or a .zip file, archived into a .zip file and uploaded to S3 otherwise
        '''
        options = InitFileAssetOptions(
            base64_encoded=base64_encoded,
            group=group,
            mode=mode,
            owner=owner,
            service_restart_handles=service_restart_handles,
            readers=readers,
            source_hash=source_hash,
            exclude=exclude,
            follow=follow,
            ignore_mode=ignore_mode,
            asset_hash=asset_hash,
            asset_hash_type=asset_hash_type,
            bundling=bundling,
        )

        return typing.cast("InitFile", jsii.sinvoke(cls, "fromAsset", [target_file_name, path, options]))

    @jsii.member(jsii_name="fromExistingAsset") # type: ignore[misc]
    @builtins.classmethod
    def from_existing_asset(
        cls,
        target_file_name: builtins.str,
        asset: aws_cdk.aws_s3_assets.Asset,
        *,
        base64_encoded: typing.Optional[builtins.bool] = None,
        group: typing.Optional[builtins.str] = None,
        mode: typing.Optional[builtins.str] = None,
        owner: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> "InitFile":
        '''Use a file from an asset at instance startup time.

        :param target_file_name: -
        :param asset: -
        :param base64_encoded: True if the inlined content (from a string or file) should be treated as base64 encoded. Only applicable for inlined string and file content. Default: false
        :param group: The name of the owning group for this file. Not supported for Windows systems. Default: 'root'
        :param mode: A six-digit octal value representing the mode for this file. Use the first three digits for symlinks and the last three digits for setting permissions. To create a symlink, specify 120xxx, where xxx defines the permissions of the target file. To specify permissions for a file, use the last three digits, such as 000644. Not supported for Windows systems. Default: '000644'
        :param owner: The name of the owning user for this file. Not supported for Windows systems. Default: 'root'
        :param service_restart_handles: Restart the given service after this file has been written. Default: - Do not restart any service
        '''
        options = InitFileOptions(
            base64_encoded=base64_encoded,
            group=group,
            mode=mode,
            owner=owner,
            service_restart_handles=service_restart_handles,
        )

        return typing.cast("InitFile", jsii.sinvoke(cls, "fromExistingAsset", [target_file_name, asset, options]))

    @jsii.member(jsii_name="fromFileInline") # type: ignore[misc]
    @builtins.classmethod
    def from_file_inline(
        cls,
        target_file_name: builtins.str,
        source_file_name: builtins.str,
        *,
        base64_encoded: typing.Optional[builtins.bool] = None,
        group: typing.Optional[builtins.str] = None,
        mode: typing.Optional[builtins.str] = None,
        owner: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> "InitFile":
        '''Read a file from disk and use its contents.

        The file will be embedded in the template, so care should be taken to not
        exceed the template size.

        If options.base64encoded is set to true, this will base64-encode the file's contents.

        :param target_file_name: -
        :param source_file_name: -
        :param base64_encoded: True if the inlined content (from a string or file) should be treated as base64 encoded. Only applicable for inlined string and file content. Default: false
        :param group: The name of the owning group for this file. Not supported for Windows systems. Default: 'root'
        :param mode: A six-digit octal value representing the mode for this file. Use the first three digits for symlinks and the last three digits for setting permissions. To create a symlink, specify 120xxx, where xxx defines the permissions of the target file. To specify permissions for a file, use the last three digits, such as 000644. Not supported for Windows systems. Default: '000644'
        :param owner: The name of the owning user for this file. Not supported for Windows systems. Default: 'root'
        :param service_restart_handles: Restart the given service after this file has been written. Default: - Do not restart any service
        '''
        options = InitFileOptions(
            base64_encoded=base64_encoded,
            group=group,
            mode=mode,
            owner=owner,
            service_restart_handles=service_restart_handles,
        )

        return typing.cast("InitFile", jsii.sinvoke(cls, "fromFileInline", [target_file_name, source_file_name, options]))

    @jsii.member(jsii_name="fromObject") # type: ignore[misc]
    @builtins.classmethod
    def from_object(
        cls,
        file_name: builtins.str,
        obj: typing.Mapping[builtins.str, typing.Any],
        *,
        base64_encoded: typing.Optional[builtins.bool] = None,
        group: typing.Optional[builtins.str] = None,
        mode: typing.Optional[builtins.str] = None,
        owner: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> "InitFile":
        '''Use a JSON-compatible object as the file content, write it to a JSON file.

        May contain tokens.

        :param file_name: -
        :param obj: -
        :param base64_encoded: True if the inlined content (from a string or file) should be treated as base64 encoded. Only applicable for inlined string and file content. Default: false
        :param group: The name of the owning group for this file. Not supported for Windows systems. Default: 'root'
        :param mode: A six-digit octal value representing the mode for this file. Use the first three digits for symlinks and the last three digits for setting permissions. To create a symlink, specify 120xxx, where xxx defines the permissions of the target file. To specify permissions for a file, use the last three digits, such as 000644. Not supported for Windows systems. Default: '000644'
        :param owner: The name of the owning user for this file. Not supported for Windows systems. Default: 'root'
        :param service_restart_handles: Restart the given service after this file has been written. Default: - Do not restart any service
        '''
        options = InitFileOptions(
            base64_encoded=base64_encoded,
            group=group,
            mode=mode,
            owner=owner,
            service_restart_handles=service_restart_handles,
        )

        return typing.cast("InitFile", jsii.sinvoke(cls, "fromObject", [file_name, obj, options]))

    @jsii.member(jsii_name="fromS3Object") # type: ignore[misc]
    @builtins.classmethod
    def from_s3_object(
        cls,
        file_name: builtins.str,
        bucket: aws_cdk.aws_s3.IBucket,
        key: builtins.str,
        *,
        base64_encoded: typing.Optional[builtins.bool] = None,
        group: typing.Optional[builtins.str] = None,
        mode: typing.Optional[builtins.str] = None,
        owner: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> "InitFile":
        '''Download a file from an S3 bucket at instance startup time.

        :param file_name: -
        :param bucket: -
        :param key: -
        :param base64_encoded: True if the inlined content (from a string or file) should be treated as base64 encoded. Only applicable for inlined string and file content. Default: false
        :param group: The name of the owning group for this file. Not supported for Windows systems. Default: 'root'
        :param mode: A six-digit octal value representing the mode for this file. Use the first three digits for symlinks and the last three digits for setting permissions. To create a symlink, specify 120xxx, where xxx defines the permissions of the target file. To specify permissions for a file, use the last three digits, such as 000644. Not supported for Windows systems. Default: '000644'
        :param owner: The name of the owning user for this file. Not supported for Windows systems. Default: 'root'
        :param service_restart_handles: Restart the given service after this file has been written. Default: - Do not restart any service
        '''
        options = InitFileOptions(
            base64_encoded=base64_encoded,
            group=group,
            mode=mode,
            owner=owner,
            service_restart_handles=service_restart_handles,
        )

        return typing.cast("InitFile", jsii.sinvoke(cls, "fromS3Object", [file_name, bucket, key, options]))

    @jsii.member(jsii_name="fromString") # type: ignore[misc]
    @builtins.classmethod
    def from_string(
        cls,
        file_name: builtins.str,
        content: builtins.str,
        *,
        base64_encoded: typing.Optional[builtins.bool] = None,
        group: typing.Optional[builtins.str] = None,
        mode: typing.Optional[builtins.str] = None,
        owner: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> "InitFile":
        '''Use a literal string as the file content.

        :param file_name: -
        :param content: -
        :param base64_encoded: True if the inlined content (from a string or file) should be treated as base64 encoded. Only applicable for inlined string and file content. Default: false
        :param group: The name of the owning group for this file. Not supported for Windows systems. Default: 'root'
        :param mode: A six-digit octal value representing the mode for this file. Use the first three digits for symlinks and the last three digits for setting permissions. To create a symlink, specify 120xxx, where xxx defines the permissions of the target file. To specify permissions for a file, use the last three digits, such as 000644. Not supported for Windows systems. Default: '000644'
        :param owner: The name of the owning user for this file. Not supported for Windows systems. Default: 'root'
        :param service_restart_handles: Restart the given service after this file has been written. Default: - Do not restart any service
        '''
        options = InitFileOptions(
            base64_encoded=base64_encoded,
            group=group,
            mode=mode,
            owner=owner,
            service_restart_handles=service_restart_handles,
        )

        return typing.cast("InitFile", jsii.sinvoke(cls, "fromString", [file_name, content, options]))

    @jsii.member(jsii_name="fromUrl") # type: ignore[misc]
    @builtins.classmethod
    def from_url(
        cls,
        file_name: builtins.str,
        url: builtins.str,
        *,
        base64_encoded: typing.Optional[builtins.bool] = None,
        group: typing.Optional[builtins.str] = None,
        mode: typing.Optional[builtins.str] = None,
        owner: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> "InitFile":
        '''Download from a URL at instance startup time.

        :param file_name: -
        :param url: -
        :param base64_encoded: True if the inlined content (from a string or file) should be treated as base64 encoded. Only applicable for inlined string and file content. Default: false
        :param group: The name of the owning group for this file. Not supported for Windows systems. Default: 'root'
        :param mode: A six-digit octal value representing the mode for this file. Use the first three digits for symlinks and the last three digits for setting permissions. To create a symlink, specify 120xxx, where xxx defines the permissions of the target file. To specify permissions for a file, use the last three digits, such as 000644. Not supported for Windows systems. Default: '000644'
        :param owner: The name of the owning user for this file. Not supported for Windows systems. Default: 'root'
        :param service_restart_handles: Restart the given service after this file has been written. Default: - Do not restart any service
        '''
        options = InitFileOptions(
            base64_encoded=base64_encoded,
            group=group,
            mode=mode,
            owner=owner,
            service_restart_handles=service_restart_handles,
        )

        return typing.cast("InitFile", jsii.sinvoke(cls, "fromUrl", [file_name, url, options]))

    @jsii.member(jsii_name="symlink") # type: ignore[misc]
    @builtins.classmethod
    def symlink(
        cls,
        file_name: builtins.str,
        target: builtins.str,
        *,
        base64_encoded: typing.Optional[builtins.bool] = None,
        group: typing.Optional[builtins.str] = None,
        mode: typing.Optional[builtins.str] = None,
        owner: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> "InitFile":
        '''Write a symlink with the given symlink target.

        :param file_name: -
        :param target: -
        :param base64_encoded: True if the inlined content (from a string or file) should be treated as base64 encoded. Only applicable for inlined string and file content. Default: false
        :param group: The name of the owning group for this file. Not supported for Windows systems. Default: 'root'
        :param mode: A six-digit octal value representing the mode for this file. Use the first three digits for symlinks and the last three digits for setting permissions. To create a symlink, specify 120xxx, where xxx defines the permissions of the target file. To specify permissions for a file, use the last three digits, such as 000644. Not supported for Windows systems. Default: '000644'
        :param owner: The name of the owning user for this file. Not supported for Windows systems. Default: 'root'
        :param service_restart_handles: Restart the given service after this file has been written. Default: - Do not restart any service
        '''
        options = InitFileOptions(
            base64_encoded=base64_encoded,
            group=group,
            mode=mode,
            owner=owner,
            service_restart_handles=service_restart_handles,
        )

        return typing.cast("InitFile", jsii.sinvoke(cls, "symlink", [file_name, target, options]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elementType")
    def element_type(self) -> builtins.str:
        '''Returns the init element type for this element.'''
        return typing.cast(builtins.str, jsii.get(self, "elementType"))


class _InitFileProxy(
    InitFile, jsii.proxy_for(InitElement) # type: ignore[misc]
):
    pass


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.InitFileOptions",
    jsii_struct_bases=[],
    name_mapping={
        "base64_encoded": "base64Encoded",
        "group": "group",
        "mode": "mode",
        "owner": "owner",
        "service_restart_handles": "serviceRestartHandles",
    },
)
class InitFileOptions:
    def __init__(
        self,
        *,
        base64_encoded: typing.Optional[builtins.bool] = None,
        group: typing.Optional[builtins.str] = None,
        mode: typing.Optional[builtins.str] = None,
        owner: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> None:
        '''Options for InitFile.

        :param base64_encoded: True if the inlined content (from a string or file) should be treated as base64 encoded. Only applicable for inlined string and file content. Default: false
        :param group: The name of the owning group for this file. Not supported for Windows systems. Default: 'root'
        :param mode: A six-digit octal value representing the mode for this file. Use the first three digits for symlinks and the last three digits for setting permissions. To create a symlink, specify 120xxx, where xxx defines the permissions of the target file. To specify permissions for a file, use the last three digits, such as 000644. Not supported for Windows systems. Default: '000644'
        :param owner: The name of the owning user for this file. Not supported for Windows systems. Default: 'root'
        :param service_restart_handles: Restart the given service after this file has been written. Default: - Do not restart any service
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if base64_encoded is not None:
            self._values["base64_encoded"] = base64_encoded
        if group is not None:
            self._values["group"] = group
        if mode is not None:
            self._values["mode"] = mode
        if owner is not None:
            self._values["owner"] = owner
        if service_restart_handles is not None:
            self._values["service_restart_handles"] = service_restart_handles

    @builtins.property
    def base64_encoded(self) -> typing.Optional[builtins.bool]:
        '''True if the inlined content (from a string or file) should be treated as base64 encoded.

        Only applicable for inlined string and file content.

        :default: false
        '''
        result = self._values.get("base64_encoded")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def group(self) -> typing.Optional[builtins.str]:
        '''The name of the owning group for this file.

        Not supported for Windows systems.

        :default: 'root'
        '''
        result = self._values.get("group")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def mode(self) -> typing.Optional[builtins.str]:
        '''A six-digit octal value representing the mode for this file.

        Use the first three digits for symlinks and the last three digits for
        setting permissions. To create a symlink, specify 120xxx, where xxx
        defines the permissions of the target file. To specify permissions for a
        file, use the last three digits, such as 000644.

        Not supported for Windows systems.

        :default: '000644'
        '''
        result = self._values.get("mode")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def owner(self) -> typing.Optional[builtins.str]:
        '''The name of the owning user for this file.

        Not supported for Windows systems.

        :default: 'root'
        '''
        result = self._values.get("owner")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def service_restart_handles(
        self,
    ) -> typing.Optional[typing.List["InitServiceRestartHandle"]]:
        '''Restart the given service after this file has been written.

        :default: - Do not restart any service
        '''
        result = self._values.get("service_restart_handles")
        return typing.cast(typing.Optional[typing.List["InitServiceRestartHandle"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "InitFileOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class InitGroup(
    InitElement,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.InitGroup",
):
    '''Create Linux/UNIX groups and assign group IDs.

    Not supported for Windows systems.
    '''

    def __init__(
        self,
        group_name: builtins.str,
        group_id: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''
        :param group_name: -
        :param group_id: -
        '''
        jsii.create(InitGroup, self, [group_name, group_id])

    @jsii.member(jsii_name="fromName") # type: ignore[misc]
    @builtins.classmethod
    def from_name(
        cls,
        group_name: builtins.str,
        group_id: typing.Optional[jsii.Number] = None,
    ) -> "InitGroup":
        '''Create a group from its name, and optionally, group id.

        :param group_name: -
        :param group_id: -
        '''
        return typing.cast("InitGroup", jsii.sinvoke(cls, "fromName", [group_name, group_id]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elementType")
    def element_type(self) -> builtins.str:
        '''Returns the init element type for this element.'''
        return typing.cast(builtins.str, jsii.get(self, "elementType"))


class InitPackage(
    InitElement,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.InitPackage",
):
    '''A package to be installed during cfn-init time.'''

    def __init__(
        self,
        type: builtins.str,
        versions: typing.List[builtins.str],
        package_name: typing.Optional[builtins.str] = None,
        service_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> None:
        '''
        :param type: -
        :param versions: -
        :param package_name: -
        :param service_handles: -
        '''
        jsii.create(InitPackage, self, [type, versions, package_name, service_handles])

    @jsii.member(jsii_name="apt") # type: ignore[misc]
    @builtins.classmethod
    def apt(
        cls,
        package_name: builtins.str,
        *,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
        version: typing.Optional[typing.List[builtins.str]] = None,
    ) -> "InitPackage":
        '''Install a package using APT.

        :param package_name: -
        :param service_restart_handles: Restart the given services after this command has run. Default: - Do not restart any service
        :param version: Specify the versions to install. Default: - Install the latest version
        '''
        options = NamedPackageOptions(
            service_restart_handles=service_restart_handles, version=version
        )

        return typing.cast("InitPackage", jsii.sinvoke(cls, "apt", [package_name, options]))

    @jsii.member(jsii_name="msi") # type: ignore[misc]
    @builtins.classmethod
    def msi(
        cls,
        location: builtins.str,
        *,
        key: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> "InitPackage":
        '''Install an MSI package from an HTTP URL or a location on disk.

        :param location: -
        :param key: Identifier key for this package. You can use this to order package installs. Default: - Automatically generated
        :param service_restart_handles: Restart the given service after this command has run. Default: - Do not restart any service
        '''
        options = LocationPackageOptions(
            key=key, service_restart_handles=service_restart_handles
        )

        return typing.cast("InitPackage", jsii.sinvoke(cls, "msi", [location, options]))

    @jsii.member(jsii_name="python") # type: ignore[misc]
    @builtins.classmethod
    def python(
        cls,
        package_name: builtins.str,
        *,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
        version: typing.Optional[typing.List[builtins.str]] = None,
    ) -> "InitPackage":
        '''Install a package from PyPI.

        :param package_name: -
        :param service_restart_handles: Restart the given services after this command has run. Default: - Do not restart any service
        :param version: Specify the versions to install. Default: - Install the latest version
        '''
        options = NamedPackageOptions(
            service_restart_handles=service_restart_handles, version=version
        )

        return typing.cast("InitPackage", jsii.sinvoke(cls, "python", [package_name, options]))

    @jsii.member(jsii_name="rpm") # type: ignore[misc]
    @builtins.classmethod
    def rpm(
        cls,
        location: builtins.str,
        *,
        key: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
    ) -> "InitPackage":
        '''Install an RPM from an HTTP URL or a location on disk.

        :param location: -
        :param key: Identifier key for this package. You can use this to order package installs. Default: - Automatically generated
        :param service_restart_handles: Restart the given service after this command has run. Default: - Do not restart any service
        '''
        options = LocationPackageOptions(
            key=key, service_restart_handles=service_restart_handles
        )

        return typing.cast("InitPackage", jsii.sinvoke(cls, "rpm", [location, options]))

    @jsii.member(jsii_name="rubyGem") # type: ignore[misc]
    @builtins.classmethod
    def ruby_gem(
        cls,
        gem_name: builtins.str,
        *,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
        version: typing.Optional[typing.List[builtins.str]] = None,
    ) -> "InitPackage":
        '''Install a package from RubyGems.

        :param gem_name: -
        :param service_restart_handles: Restart the given services after this command has run. Default: - Do not restart any service
        :param version: Specify the versions to install. Default: - Install the latest version
        '''
        options = NamedPackageOptions(
            service_restart_handles=service_restart_handles, version=version
        )

        return typing.cast("InitPackage", jsii.sinvoke(cls, "rubyGem", [gem_name, options]))

    @jsii.member(jsii_name="yum") # type: ignore[misc]
    @builtins.classmethod
    def yum(
        cls,
        package_name: builtins.str,
        *,
        service_restart_handles: typing.Optional[typing.List["InitServiceRestartHandle"]] = None,
        version: typing.Optional[typing.List[builtins.str]] = None,
    ) -> "InitPackage":
        '''Install a package using Yum.

        :param package_name: -
        :param service_restart_handles: Restart the given services after this command has run. Default: - Do not restart any service
        :param version: Specify the versions to install. Default: - Install the latest version
        '''
        options = NamedPackageOptions(
            service_restart_handles=service_restart_handles, version=version
        )

        return typing.cast("InitPackage", jsii.sinvoke(cls, "yum", [package_name, options]))

    @jsii.member(jsii_name="renderPackageVersions")
    def _render_package_versions(self) -> typing.Any:
        return typing.cast(typing.Any, jsii.invoke(self, "renderPackageVersions", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elementType")
    def element_type(self) -> builtins.str:
        '''Returns the init element type for this element.'''
        return typing.cast(builtins.str, jsii.get(self, "elementType"))


class InitService(
    InitElement,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.InitService",
):
    '''A services that be enabled, disabled or restarted when the instance is launched.'''

    @jsii.member(jsii_name="disable") # type: ignore[misc]
    @builtins.classmethod
    def disable(cls, service_name: builtins.str) -> "InitService":
        '''Disable and stop the given service.

        :param service_name: -
        '''
        return typing.cast("InitService", jsii.sinvoke(cls, "disable", [service_name]))

    @jsii.member(jsii_name="enable") # type: ignore[misc]
    @builtins.classmethod
    def enable(
        cls,
        service_name: builtins.str,
        *,
        enabled: typing.Optional[builtins.bool] = None,
        ensure_running: typing.Optional[builtins.bool] = None,
        service_restart_handle: typing.Optional["InitServiceRestartHandle"] = None,
    ) -> "InitService":
        '''Enable and start the given service, optionally restarting it.

        :param service_name: -
        :param enabled: Enable or disable this service. Set to true to ensure that the service will be started automatically upon boot. Set to false to ensure that the service will not be started automatically upon boot. Default: - true if used in ``InitService.enable()``, no change to service state if used in ``InitService.fromOptions()``.
        :param ensure_running: Make sure this service is running or not running after cfn-init finishes. Set to true to ensure that the service is running after cfn-init finishes. Set to false to ensure that the service is not running after cfn-init finishes. Default: - same value as ``enabled``.
        :param service_restart_handle: Restart service when the actions registered into the restartHandle have been performed. Register actions into the restartHandle by passing it to ``InitFile``, ``InitCommand``, ``InitPackage`` and ``InitSource`` objects. Default: - No files trigger restart
        '''
        options = InitServiceOptions(
            enabled=enabled,
            ensure_running=ensure_running,
            service_restart_handle=service_restart_handle,
        )

        return typing.cast("InitService", jsii.sinvoke(cls, "enable", [service_name, options]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elementType")
    def element_type(self) -> builtins.str:
        '''Returns the init element type for this element.'''
        return typing.cast(builtins.str, jsii.get(self, "elementType"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.InitServiceOptions",
    jsii_struct_bases=[],
    name_mapping={
        "enabled": "enabled",
        "ensure_running": "ensureRunning",
        "service_restart_handle": "serviceRestartHandle",
    },
)
class InitServiceOptions:
    def __init__(
        self,
        *,
        enabled: typing.Optional[builtins.bool] = None,
        ensure_running: typing.Optional[builtins.bool] = None,
        service_restart_handle: typing.Optional["InitServiceRestartHandle"] = None,
    ) -> None:
        '''Options for an InitService.

        :param enabled: Enable or disable this service. Set to true to ensure that the service will be started automatically upon boot. Set to false to ensure that the service will not be started automatically upon boot. Default: - true if used in ``InitService.enable()``, no change to service state if used in ``InitService.fromOptions()``.
        :param ensure_running: Make sure this service is running or not running after cfn-init finishes. Set to true to ensure that the service is running after cfn-init finishes. Set to false to ensure that the service is not running after cfn-init finishes. Default: - same value as ``enabled``.
        :param service_restart_handle: Restart service when the actions registered into the restartHandle have been performed. Register actions into the restartHandle by passing it to ``InitFile``, ``InitCommand``, ``InitPackage`` and ``InitSource`` objects. Default: - No files trigger restart
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if enabled is not None:
            self._values["enabled"] = enabled
        if ensure_running is not None:
            self._values["ensure_running"] = ensure_running
        if service_restart_handle is not None:
            self._values["service_restart_handle"] = service_restart_handle

    @builtins.property
    def enabled(self) -> typing.Optional[builtins.bool]:
        '''Enable or disable this service.

        Set to true to ensure that the service will be started automatically upon boot.

        Set to false to ensure that the service will not be started automatically upon boot.

        :default:

        - true if used in ``InitService.enable()``, no change to service
        state if used in ``InitService.fromOptions()``.
        '''
        result = self._values.get("enabled")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def ensure_running(self) -> typing.Optional[builtins.bool]:
        '''Make sure this service is running or not running after cfn-init finishes.

        Set to true to ensure that the service is running after cfn-init finishes.

        Set to false to ensure that the service is not running after cfn-init finishes.

        :default: - same value as ``enabled``.
        '''
        result = self._values.get("ensure_running")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def service_restart_handle(self) -> typing.Optional["InitServiceRestartHandle"]:
        '''Restart service when the actions registered into the restartHandle have been performed.

        Register actions into the restartHandle by passing it to ``InitFile``, ``InitCommand``,
        ``InitPackage`` and ``InitSource`` objects.

        :default: - No files trigger restart
        '''
        result = self._values.get("service_restart_handle")
        return typing.cast(typing.Optional["InitServiceRestartHandle"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "InitServiceOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class InitServiceRestartHandle(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.InitServiceRestartHandle",
):
    '''An object that represents reasons to restart an InitService.

    Pass an instance of this object to the ``InitFile``, ``InitCommand``,
    ``InitSource`` and ``InitPackage`` objects, and finally to an ``InitService``
    itself to cause the actions (files, commands, sources, and packages)
    to trigger a restart of the service.

    For example, the following will run a custom command to install Nginx,
    and trigger the nginx service to be restarted after the command has run::

       # Example automatically generated. See https://github.com/aws/jsii/issues/826
       handle = ec2.InitServiceRestartHandle()
       ec2.CloudFormationInit.from_elements(
           ec2.InitCommand.shell_command("/usr/bin/custom-nginx-install.sh", service_restart_handles=[handle]),
           ec2.InitService.enable("nginx", service_restart_handle=handle))
    '''

    def __init__(self) -> None:
        jsii.create(InitServiceRestartHandle, self, [])


class InitSource(
    InitElement,
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-ec2.InitSource",
):
    '''Extract an archive into a directory.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_InitSourceProxy"]:
        return _InitSourceProxy

    def __init__(
        self,
        target_directory: builtins.str,
        service_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
    ) -> None:
        '''
        :param target_directory: -
        :param service_handles: -
        '''
        jsii.create(InitSource, self, [target_directory, service_handles])

    @jsii.member(jsii_name="fromAsset") # type: ignore[misc]
    @builtins.classmethod
    def from_asset(
        cls,
        target_directory: builtins.str,
        path: builtins.str,
        *,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
        readers: typing.Optional[typing.List[aws_cdk.aws_iam.IGrantable]] = None,
        source_hash: typing.Optional[builtins.str] = None,
        exclude: typing.Optional[typing.List[builtins.str]] = None,
        follow: typing.Optional[aws_cdk.assets.FollowMode] = None,
        ignore_mode: typing.Optional[aws_cdk.core.IgnoreMode] = None,
        asset_hash: typing.Optional[builtins.str] = None,
        asset_hash_type: typing.Optional[aws_cdk.core.AssetHashType] = None,
        bundling: typing.Optional[aws_cdk.core.BundlingOptions] = None,
    ) -> "InitSource":
        '''Create an InitSource from an asset created from the given path.

        :param target_directory: -
        :param path: -
        :param service_restart_handles: Restart the given services after this archive has been extracted. Default: - Do not restart any service
        :param readers: (experimental) A list of principals that should be able to read this asset from S3. You can use ``asset.grantRead(principal)`` to grant read permissions later. Default: - No principals that can read file asset.
        :param source_hash: (deprecated) Custom hash to use when identifying the specific version of the asset. For consistency, this custom hash will be SHA256 hashed and encoded as hex. The resulting hash will be the asset hash. NOTE: the source hash is used in order to identify a specific revision of the asset, and used for optimizing and caching deployment activities related to this asset such as packaging, uploading to Amazon S3, etc. If you chose to customize the source hash, you will need to make sure it is updated every time the source changes, or otherwise it is possible that some deployments will not be invalidated. Default: - automatically calculate source hash based on the contents of the source file or directory.
        :param exclude: (deprecated) Glob patterns to exclude from the copy. Default: nothing is excluded
        :param follow: (deprecated) A strategy for how to handle symlinks. Default: Never
        :param ignore_mode: (deprecated) The ignore behavior to use for exclude patterns. Default: - GLOB for file assets, DOCKER or GLOB for docker assets depending on whether the '
        :param asset_hash: Specify a custom hash for this asset. If ``assetHashType`` is set it must be set to ``AssetHashType.CUSTOM``. For consistency, this custom hash will be SHA256 hashed and encoded as hex. The resulting hash will be the asset hash. NOTE: the hash is used in order to identify a specific revision of the asset, and used for optimizing and caching deployment activities related to this asset such as packaging, uploading to Amazon S3, etc. If you chose to customize the hash, you will need to make sure it is updated every time the asset changes, or otherwise it is possible that some deployments will not be invalidated. Default: - based on ``assetHashType``
        :param asset_hash_type: Specifies the type of hash to calculate for this asset. If ``assetHash`` is configured, this option must be ``undefined`` or ``AssetHashType.CUSTOM``. Default: - the default is ``AssetHashType.SOURCE``, but if ``assetHash`` is explicitly specified this value defaults to ``AssetHashType.CUSTOM``.
        :param bundling: (experimental) Bundle the asset by executing a command in a Docker container. The asset path will be mounted at ``/asset-input``. The Docker container is responsible for putting content at ``/asset-output``. The content at ``/asset-output`` will be zipped and used as the final asset. Default: - uploaded as-is to S3 if the asset is a regular file or a .zip file, archived into a .zip file and uploaded to S3 otherwise
        '''
        options = InitSourceAssetOptions(
            service_restart_handles=service_restart_handles,
            readers=readers,
            source_hash=source_hash,
            exclude=exclude,
            follow=follow,
            ignore_mode=ignore_mode,
            asset_hash=asset_hash,
            asset_hash_type=asset_hash_type,
            bundling=bundling,
        )

        return typing.cast("InitSource", jsii.sinvoke(cls, "fromAsset", [target_directory, path, options]))

    @jsii.member(jsii_name="fromExistingAsset") # type: ignore[misc]
    @builtins.classmethod
    def from_existing_asset(
        cls,
        target_directory: builtins.str,
        asset: aws_cdk.aws_s3_assets.Asset,
        *,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
    ) -> "InitSource":
        '''Extract a directory from an existing directory asset.

        :param target_directory: -
        :param asset: -
        :param service_restart_handles: Restart the given services after this archive has been extracted. Default: - Do not restart any service
        '''
        options = InitSourceOptions(service_restart_handles=service_restart_handles)

        return typing.cast("InitSource", jsii.sinvoke(cls, "fromExistingAsset", [target_directory, asset, options]))

    @jsii.member(jsii_name="fromGitHub") # type: ignore[misc]
    @builtins.classmethod
    def from_git_hub(
        cls,
        target_directory: builtins.str,
        owner: builtins.str,
        repo: builtins.str,
        ref_spec: typing.Optional[builtins.str] = None,
        *,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
    ) -> "InitSource":
        '''Extract a GitHub branch into a given directory.

        :param target_directory: -
        :param owner: -
        :param repo: -
        :param ref_spec: -
        :param service_restart_handles: Restart the given services after this archive has been extracted. Default: - Do not restart any service
        '''
        options = InitSourceOptions(service_restart_handles=service_restart_handles)

        return typing.cast("InitSource", jsii.sinvoke(cls, "fromGitHub", [target_directory, owner, repo, ref_spec, options]))

    @jsii.member(jsii_name="fromS3Object") # type: ignore[misc]
    @builtins.classmethod
    def from_s3_object(
        cls,
        target_directory: builtins.str,
        bucket: aws_cdk.aws_s3.IBucket,
        key: builtins.str,
        *,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
    ) -> "InitSource":
        '''Extract an archive stored in an S3 bucket into the given directory.

        :param target_directory: -
        :param bucket: -
        :param key: -
        :param service_restart_handles: Restart the given services after this archive has been extracted. Default: - Do not restart any service
        '''
        options = InitSourceOptions(service_restart_handles=service_restart_handles)

        return typing.cast("InitSource", jsii.sinvoke(cls, "fromS3Object", [target_directory, bucket, key, options]))

    @jsii.member(jsii_name="fromUrl") # type: ignore[misc]
    @builtins.classmethod
    def from_url(
        cls,
        target_directory: builtins.str,
        url: builtins.str,
        *,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
    ) -> "InitSource":
        '''Retrieve a URL and extract it into the given directory.

        :param target_directory: -
        :param url: -
        :param service_restart_handles: Restart the given services after this archive has been extracted. Default: - Do not restart any service
        '''
        options = InitSourceOptions(service_restart_handles=service_restart_handles)

        return typing.cast("InitSource", jsii.sinvoke(cls, "fromUrl", [target_directory, url, options]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elementType")
    def element_type(self) -> builtins.str:
        '''Returns the init element type for this element.'''
        return typing.cast(builtins.str, jsii.get(self, "elementType"))


class _InitSourceProxy(
    InitSource, jsii.proxy_for(InitElement) # type: ignore[misc]
):
    pass


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.InitSourceOptions",
    jsii_struct_bases=[],
    name_mapping={"service_restart_handles": "serviceRestartHandles"},
)
class InitSourceOptions:
    def __init__(
        self,
        *,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
    ) -> None:
        '''Additional options for an InitSource.

        :param service_restart_handles: Restart the given services after this archive has been extracted. Default: - Do not restart any service
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if service_restart_handles is not None:
            self._values["service_restart_handles"] = service_restart_handles

    @builtins.property
    def service_restart_handles(
        self,
    ) -> typing.Optional[typing.List[InitServiceRestartHandle]]:
        '''Restart the given services after this archive has been extracted.

        :default: - Do not restart any service
        '''
        result = self._values.get("service_restart_handles")
        return typing.cast(typing.Optional[typing.List[InitServiceRestartHandle]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "InitSourceOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class InitUser(
    InitElement,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.InitUser",
):
    '''Create Linux/UNIX users and to assign user IDs.

    Users are created as non-interactive system users with a shell of
    /sbin/nologin. This is by design and cannot be modified.

    Not supported for Windows systems.
    '''

    def __init__(
        self,
        user_name: builtins.str,
        *,
        groups: typing.Optional[typing.List[builtins.str]] = None,
        home_dir: typing.Optional[builtins.str] = None,
        user_id: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''
        :param user_name: -
        :param groups: A list of group names. The user will be added to each group in the list. Default: the user is not associated with any groups.
        :param home_dir: The user's home directory. Default: assigned by the OS
        :param user_id: A user ID. The creation process fails if the user name exists with a different user ID. If the user ID is already assigned to an existing user the operating system may reject the creation request. Default: assigned by the OS
        '''
        user_options = InitUserOptions(
            groups=groups, home_dir=home_dir, user_id=user_id
        )

        jsii.create(InitUser, self, [user_name, user_options])

    @jsii.member(jsii_name="fromName") # type: ignore[misc]
    @builtins.classmethod
    def from_name(
        cls,
        user_name: builtins.str,
        *,
        groups: typing.Optional[typing.List[builtins.str]] = None,
        home_dir: typing.Optional[builtins.str] = None,
        user_id: typing.Optional[jsii.Number] = None,
    ) -> "InitUser":
        '''Create a user from user name.

        :param user_name: -
        :param groups: A list of group names. The user will be added to each group in the list. Default: the user is not associated with any groups.
        :param home_dir: The user's home directory. Default: assigned by the OS
        :param user_id: A user ID. The creation process fails if the user name exists with a different user ID. If the user ID is already assigned to an existing user the operating system may reject the creation request. Default: assigned by the OS
        '''
        options = InitUserOptions(groups=groups, home_dir=home_dir, user_id=user_id)

        return typing.cast("InitUser", jsii.sinvoke(cls, "fromName", [user_name, options]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elementType")
    def element_type(self) -> builtins.str:
        '''Returns the init element type for this element.'''
        return typing.cast(builtins.str, jsii.get(self, "elementType"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.InitUserOptions",
    jsii_struct_bases=[],
    name_mapping={"groups": "groups", "home_dir": "homeDir", "user_id": "userId"},
)
class InitUserOptions:
    def __init__(
        self,
        *,
        groups: typing.Optional[typing.List[builtins.str]] = None,
        home_dir: typing.Optional[builtins.str] = None,
        user_id: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Optional parameters used when creating a user.

        :param groups: A list of group names. The user will be added to each group in the list. Default: the user is not associated with any groups.
        :param home_dir: The user's home directory. Default: assigned by the OS
        :param user_id: A user ID. The creation process fails if the user name exists with a different user ID. If the user ID is already assigned to an existing user the operating system may reject the creation request. Default: assigned by the OS
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if groups is not None:
            self._values["groups"] = groups
        if home_dir is not None:
            self._values["home_dir"] = home_dir
        if user_id is not None:
            self._values["user_id"] = user_id

    @builtins.property
    def groups(self) -> typing.Optional[typing.List[builtins.str]]:
        '''A list of group names.

        The user will be added to each group in the list.

        :default: the user is not associated with any groups.
        '''
        result = self._values.get("groups")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def home_dir(self) -> typing.Optional[builtins.str]:
        '''The user's home directory.

        :default: assigned by the OS
        '''
        result = self._values.get("home_dir")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def user_id(self) -> typing.Optional[jsii.Number]:
        '''A user ID.

        The creation process fails if the user name exists with a different user ID.
        If the user ID is already assigned to an existing user the operating system may
        reject the creation request.

        :default: assigned by the OS
        '''
        result = self._values.get("user_id")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "InitUserOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IInstance)
class Instance(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.Instance",
):
    '''This represents a single EC2 instance.'''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        instance_type: "InstanceType",
        machine_image: IMachineImage,
        vpc: IVpc,
        allow_all_outbound: typing.Optional[builtins.bool] = None,
        availability_zone: typing.Optional[builtins.str] = None,
        block_devices: typing.Optional[typing.List[BlockDevice]] = None,
        init: typing.Optional[CloudFormationInit] = None,
        init_options: typing.Optional[ApplyCloudFormationInitOptions] = None,
        instance_name: typing.Optional[builtins.str] = None,
        key_name: typing.Optional[builtins.str] = None,
        private_ip_address: typing.Optional[builtins.str] = None,
        resource_signal_timeout: typing.Optional[aws_cdk.core.Duration] = None,
        role: typing.Optional[aws_cdk.aws_iam.IRole] = None,
        security_group: typing.Optional[ISecurityGroup] = None,
        source_dest_check: typing.Optional[builtins.bool] = None,
        user_data: typing.Optional["UserData"] = None,
        user_data_causes_replacement: typing.Optional[builtins.bool] = None,
        vpc_subnets: typing.Optional["SubnetSelection"] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param instance_type: Type of instance to launch.
        :param machine_image: AMI to launch.
        :param vpc: VPC to launch the instance in.
        :param allow_all_outbound: Whether the instance could initiate connections to anywhere by default. This property is only used when you do not provide a security group. Default: true
        :param availability_zone: In which AZ to place the instance within the VPC. Default: - Random zone.
        :param block_devices: Specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes. Each instance that is launched has an associated root device volume, either an Amazon EBS volume or an instance store volume. You can use block device mappings to specify additional EBS volumes or instance store volumes to attach to an instance when it is launched. Default: - Uses the block device mapping of the AMI
        :param init: Apply the given CloudFormation Init configuration to the instance at startup. Default: - no CloudFormation init
        :param init_options: Use the given options for applying CloudFormation Init. Describes the configsets to use and the timeout to wait Default: - default options
        :param instance_name: The name of the instance. Default: - CDK generated name
        :param key_name: Name of SSH keypair to grant access to instance. Default: - No SSH access will be possible.
        :param private_ip_address: Defines a private IP address to associate with an instance. Private IP should be available within the VPC that the instance is build within. Default: - no association
        :param resource_signal_timeout: The length of time to wait for the resourceSignalCount. The maximum value is 43200 (12 hours). Default: Duration.minutes(5)
        :param role: An IAM role to associate with the instance profile assigned to this Auto Scaling Group. The role must be assumable by the service principal ``ec2.amazonaws.com``: Default: - A role will automatically be created, it can be accessed via the ``role`` property
        :param security_group: Security Group to assign to this instance. Default: - create new security group
        :param source_dest_check: Specifies whether to enable an instance launched in a VPC to perform NAT. This controls whether source/destination checking is enabled on the instance. A value of true means that checking is enabled, and false means that checking is disabled. The value must be false for the instance to perform NAT. Default: true
        :param user_data: Specific UserData to use. The UserData may still be mutated after creation. Default: - A UserData object appropriate for the MachineImage's Operating System is created.
        :param user_data_causes_replacement: Changes to the UserData force replacement. Depending the EC2 instance type, changing UserData either restarts the instance or replaces the instance. - Instance store-backed instances are replaced. - EBS-backed instances are restarted. By default, restarting does not execute the new UserData so you will need a different mechanism to ensure the instance is restarted. Setting this to ``true`` will make the instance's Logical ID depend on the UserData, which will cause CloudFormation to replace it if the UserData changes. Default: - true iff ``initOptions`` is specified, false otherwise.
        :param vpc_subnets: Where to place the instance within the VPC. Default: - Private subnets.
        '''
        props = InstanceProps(
            instance_type=instance_type,
            machine_image=machine_image,
            vpc=vpc,
            allow_all_outbound=allow_all_outbound,
            availability_zone=availability_zone,
            block_devices=block_devices,
            init=init,
            init_options=init_options,
            instance_name=instance_name,
            key_name=key_name,
            private_ip_address=private_ip_address,
            resource_signal_timeout=resource_signal_timeout,
            role=role,
            security_group=security_group,
            source_dest_check=source_dest_check,
            user_data=user_data,
            user_data_causes_replacement=user_data_causes_replacement,
            vpc_subnets=vpc_subnets,
        )

        jsii.create(Instance, self, [scope, id, props])

    @jsii.member(jsii_name="addSecurityGroup")
    def add_security_group(self, security_group: ISecurityGroup) -> None:
        '''Add the security group to the instance.

        :param security_group: : The security group to add.
        '''
        return typing.cast(None, jsii.invoke(self, "addSecurityGroup", [security_group]))

    @jsii.member(jsii_name="addToRolePolicy")
    def add_to_role_policy(self, statement: aws_cdk.aws_iam.PolicyStatement) -> None:
        '''Adds a statement to the IAM role assumed by the instance.

        :param statement: -
        '''
        return typing.cast(None, jsii.invoke(self, "addToRolePolicy", [statement]))

    @jsii.member(jsii_name="addUserData")
    def add_user_data(self, *commands: builtins.str) -> None:
        '''Add command to the startup script of the instance.

        The command must be in the scripting language supported by the instance's OS (i.e. Linux/Windows).

        :param commands: -
        '''
        return typing.cast(None, jsii.invoke(self, "addUserData", [*commands]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connections")
    def connections(self) -> "Connections":
        '''Allows specify security group connections for the instance.'''
        return typing.cast("Connections", jsii.get(self, "connections"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="grantPrincipal")
    def grant_principal(self) -> aws_cdk.aws_iam.IPrincipal:
        '''The principal to grant permissions to.'''
        return typing.cast(aws_cdk.aws_iam.IPrincipal, jsii.get(self, "grantPrincipal"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instance")
    def instance(self) -> CfnInstance:
        '''the underlying instance resource.'''
        return typing.cast(CfnInstance, jsii.get(self, "instance"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceAvailabilityZone")
    def instance_availability_zone(self) -> builtins.str:
        '''The availability zone the instance was launched in.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instanceAvailabilityZone"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceId")
    def instance_id(self) -> builtins.str:
        '''The instance's ID.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instanceId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePrivateDnsName")
    def instance_private_dns_name(self) -> builtins.str:
        '''Private DNS name for this instance.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePrivateDnsName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePrivateIp")
    def instance_private_ip(self) -> builtins.str:
        '''Private IP for this instance.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePrivateIp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePublicDnsName")
    def instance_public_dns_name(self) -> builtins.str:
        '''Publicly-routable DNS name for this instance.

        (May be an empty string if the instance does not have a public name).

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePublicDnsName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePublicIp")
    def instance_public_ip(self) -> builtins.str:
        '''Publicly-routable IP  address for this instance.

        (May be an empty string if the instance does not have a public IP).

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePublicIp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="osType")
    def os_type(self) -> "OperatingSystemType":
        '''The type of OS the instance is running.'''
        return typing.cast("OperatingSystemType", jsii.get(self, "osType"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="role")
    def role(self) -> aws_cdk.aws_iam.IRole:
        '''The IAM role assumed by the instance.'''
        return typing.cast(aws_cdk.aws_iam.IRole, jsii.get(self, "role"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="userData")
    def user_data(self) -> "UserData":
        '''UserData for the instance.'''
        return typing.cast("UserData", jsii.get(self, "userData"))


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.InstanceArchitecture")
class InstanceArchitecture(enum.Enum):
    '''Identifies an instance's CPU architecture.'''

    ARM_64 = "ARM_64"
    '''ARM64 architecture.'''
    X86_64 = "X86_64"
    '''x86-64 architecture.'''


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.InstanceClass")
class InstanceClass(enum.Enum):
    '''What class and generation of instance to use.

    We have both symbolic and concrete enums for every type.

    The first are for people that want to specify by purpose,
    the second one are for people who already know exactly what
    'R4' means.
    '''

    STANDARD3 = "STANDARD3"
    '''Standard instances, 3rd generation.'''
    STANDARD4 = "STANDARD4"
    '''Standard instances, 4th generation.'''
    STANDARD5 = "STANDARD5"
    '''Standard instances, 5th generation.'''
    STANDARD5_NVME_DRIVE = "STANDARD5_NVME_DRIVE"
    '''Standard instances with local NVME drive, 5th generation.'''
    STANDARD5_AMD = "STANDARD5_AMD"
    '''Standard instances based on AMD EPYC, 5th generation.'''
    STANDARD5_AMD_NVME_DRIVE = "STANDARD5_AMD_NVME_DRIVE"
    '''Standard instances based on AMD EPYC with local NVME drive, 5th generation.'''
    MEMORY3 = "MEMORY3"
    '''Memory optimized instances, 3rd generation.'''
    MEMORY4 = "MEMORY4"
    '''Memory optimized instances, 4th generation.'''
    MEMORY5 = "MEMORY5"
    '''Memory optimized instances, 5th generation.'''
    MEMORY5_HIGH_PERFORMANCE = "MEMORY5_HIGH_PERFORMANCE"
    '''Memory optimized instances for high performance computing, 5th generation.'''
    MEMORY5_NVME_DRIVE = "MEMORY5_NVME_DRIVE"
    '''Memory optimized instances with local NVME drive, 5th generation.'''
    MEMORY5_NVME_DRIVE_HIGH_PERFORMANCE = "MEMORY5_NVME_DRIVE_HIGH_PERFORMANCE"
    '''Memory optimized instances with local NVME drive for high performance computing, 5th generation.'''
    MEMORY5_AMD = "MEMORY5_AMD"
    '''Memory optimized instances based on AMD EPYC, 5th generation.'''
    MEMORY5_EBS_OPTIMIZED = "MEMORY5_EBS_OPTIMIZED"
    '''Memory optimized instances that are also EBS-optimized, 5th generation.'''
    MEMORY6_GRAVITON = "MEMORY6_GRAVITON"
    '''Memory optimized instances, 6th generation with Graviton2 processors.'''
    MEMORY6_GRAVITON2_NVME_DRIVE = "MEMORY6_GRAVITON2_NVME_DRIVE"
    '''Memory optimized instances, 6th generation with Graviton2 processors and local NVME drive.'''
    COMPUTE3 = "COMPUTE3"
    '''Compute optimized instances, 3rd generation.'''
    COMPUTE4 = "COMPUTE4"
    '''Compute optimized instances, 4th generation.'''
    COMPUTE5 = "COMPUTE5"
    '''Compute optimized instances, 5th generation.'''
    COMPUTE5_NVME_DRIVE = "COMPUTE5_NVME_DRIVE"
    '''Compute optimized instances with local NVME drive, 5th generation.'''
    COMPUTE5_AMD = "COMPUTE5_AMD"
    '''Compute optimized instances based on AMD EPYC, 5th generation.'''
    COMPUTE5_HIGH_PERFORMANCE = "COMPUTE5_HIGH_PERFORMANCE"
    '''Compute optimized instances for high performance computing, 5th generation.'''
    COMPUTE6_GRAVITON2 = "COMPUTE6_GRAVITON2"
    '''Compute optimized instances for high performance computing, 6th generation with Graviton2 processors.'''
    COMPUTE6_GRAVITON2_NVME_DRIVE = "COMPUTE6_GRAVITON2_NVME_DRIVE"
    '''Compute optimized instances for high performance computing, 6th generation with Graviton2 processors and local NVME drive.'''
    COMPUTE6_GRAVITON2_HIGH_NETWORK_BANDWITH = "COMPUTE6_GRAVITON2_HIGH_NETWORK_BANDWITH"
    '''Compute optimized instances for high performance computing, 6th generation with Graviton2 processors and high network bandwidth capabilities.'''
    STORAGE2 = "STORAGE2"
    '''Storage-optimized instances, 2nd generation.'''
    STORAGE_COMPUTE_1 = "STORAGE_COMPUTE_1"
    '''Storage/compute balanced instances, 1st generation.'''
    IO3 = "IO3"
    '''I/O-optimized instances, 3rd generation.'''
    IO3_DENSE_NVME_DRIVE = "IO3_DENSE_NVME_DRIVE"
    '''I/O-optimized instances with local NVME drive, 3rd generation.'''
    BURSTABLE2 = "BURSTABLE2"
    '''Burstable instances, 2nd generation.'''
    BURSTABLE3 = "BURSTABLE3"
    '''Burstable instances, 3rd generation.'''
    BURSTABLE3_AMD = "BURSTABLE3_AMD"
    '''Burstable instances based on AMD EPYC, 3rd generation.'''
    BURSTABLE4_GRAVITON = "BURSTABLE4_GRAVITON"
    '''Burstable instances, 4th generation with Graviton2 processors.'''
    MEMORY_INTENSIVE_1 = "MEMORY_INTENSIVE_1"
    '''Memory-intensive instances, 1st generation.'''
    MEMORY_INTENSIVE_1_EXTENDED = "MEMORY_INTENSIVE_1_EXTENDED"
    '''Memory-intensive instances, extended, 1st generation.'''
    FPGA1 = "FPGA1"
    '''Instances with customizable hardware acceleration, 1st generation.'''
    GRAPHICS3 = "GRAPHICS3"
    '''Graphics-optimized instances, 3rd generation.'''
    GRAPHICS4_NVME_DRIVE_HIGH_PERFORMANCE = "GRAPHICS4_NVME_DRIVE_HIGH_PERFORMANCE"
    '''Graphics-optimized instances with NVME drive for high performance computing, 4th generation.'''
    PARALLEL2 = "PARALLEL2"
    '''Parallel-processing optimized instances, 2nd generation.'''
    PARALLEL3 = "PARALLEL3"
    '''Parallel-processing optimized instances, 3nd generation.'''
    ARM1 = "ARM1"
    '''Arm processor based instances, 1st generation.'''
    STANDARD6_GRAVITON = "STANDARD6_GRAVITON"
    '''Arm processor based instances, 2nd generation.'''
    STANDARD6_GRAVITON2_NVME_DRIVE = "STANDARD6_GRAVITON2_NVME_DRIVE"
    '''Standard instances, 6th generation with Graviton2 processors and local NVME drive.'''
    HIGH_COMPUTE_MEMORY1 = "HIGH_COMPUTE_MEMORY1"
    '''High memory and compute capacity instances, 1st generation.'''
    INFERENCE1 = "INFERENCE1"
    '''Inferentia Chips based instances for machine learning inference applications, 1st generation.'''


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.InstanceInitiatedShutdownBehavior")
class InstanceInitiatedShutdownBehavior(enum.Enum):
    '''Provides the options for specifying the instance initiated shutdown behavior.

    :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingInstanceInitiatedShutdownBehavior
    '''

    STOP = "STOP"
    '''The instance will stop when it initiates a shutdown.'''
    TERMINATE = "TERMINATE"
    '''The instance will be terminated when it initiates a shutdown.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.InstanceProps",
    jsii_struct_bases=[],
    name_mapping={
        "instance_type": "instanceType",
        "machine_image": "machineImage",
        "vpc": "vpc",
        "allow_all_outbound": "allowAllOutbound",
        "availability_zone": "availabilityZone",
        "block_devices": "blockDevices",
        "init": "init",
        "init_options": "initOptions",
        "instance_name": "instanceName",
        "key_name": "keyName",
        "private_ip_address": "privateIpAddress",
        "resource_signal_timeout": "resourceSignalTimeout",
        "role": "role",
        "security_group": "securityGroup",
        "source_dest_check": "sourceDestCheck",
        "user_data": "userData",
        "user_data_causes_replacement": "userDataCausesReplacement",
        "vpc_subnets": "vpcSubnets",
    },
)
class InstanceProps:
    def __init__(
        self,
        *,
        instance_type: "InstanceType",
        machine_image: IMachineImage,
        vpc: IVpc,
        allow_all_outbound: typing.Optional[builtins.bool] = None,
        availability_zone: typing.Optional[builtins.str] = None,
        block_devices: typing.Optional[typing.List[BlockDevice]] = None,
        init: typing.Optional[CloudFormationInit] = None,
        init_options: typing.Optional[ApplyCloudFormationInitOptions] = None,
        instance_name: typing.Optional[builtins.str] = None,
        key_name: typing.Optional[builtins.str] = None,
        private_ip_address: typing.Optional[builtins.str] = None,
        resource_signal_timeout: typing.Optional[aws_cdk.core.Duration] = None,
        role: typing.Optional[aws_cdk.aws_iam.IRole] = None,
        security_group: typing.Optional[ISecurityGroup] = None,
        source_dest_check: typing.Optional[builtins.bool] = None,
        user_data: typing.Optional["UserData"] = None,
        user_data_causes_replacement: typing.Optional[builtins.bool] = None,
        vpc_subnets: typing.Optional["SubnetSelection"] = None,
    ) -> None:
        '''Properties of an EC2 Instance.

        :param instance_type: Type of instance to launch.
        :param machine_image: AMI to launch.
        :param vpc: VPC to launch the instance in.
        :param allow_all_outbound: Whether the instance could initiate connections to anywhere by default. This property is only used when you do not provide a security group. Default: true
        :param availability_zone: In which AZ to place the instance within the VPC. Default: - Random zone.
        :param block_devices: Specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes. Each instance that is launched has an associated root device volume, either an Amazon EBS volume or an instance store volume. You can use block device mappings to specify additional EBS volumes or instance store volumes to attach to an instance when it is launched. Default: - Uses the block device mapping of the AMI
        :param init: Apply the given CloudFormation Init configuration to the instance at startup. Default: - no CloudFormation init
        :param init_options: Use the given options for applying CloudFormation Init. Describes the configsets to use and the timeout to wait Default: - default options
        :param instance_name: The name of the instance. Default: - CDK generated name
        :param key_name: Name of SSH keypair to grant access to instance. Default: - No SSH access will be possible.
        :param private_ip_address: Defines a private IP address to associate with an instance. Private IP should be available within the VPC that the instance is build within. Default: - no association
        :param resource_signal_timeout: The length of time to wait for the resourceSignalCount. The maximum value is 43200 (12 hours). Default: Duration.minutes(5)
        :param role: An IAM role to associate with the instance profile assigned to this Auto Scaling Group. The role must be assumable by the service principal ``ec2.amazonaws.com``: Default: - A role will automatically be created, it can be accessed via the ``role`` property
        :param security_group: Security Group to assign to this instance. Default: - create new security group
        :param source_dest_check: Specifies whether to enable an instance launched in a VPC to perform NAT. This controls whether source/destination checking is enabled on the instance. A value of true means that checking is enabled, and false means that checking is disabled. The value must be false for the instance to perform NAT. Default: true
        :param user_data: Specific UserData to use. The UserData may still be mutated after creation. Default: - A UserData object appropriate for the MachineImage's Operating System is created.
        :param user_data_causes_replacement: Changes to the UserData force replacement. Depending the EC2 instance type, changing UserData either restarts the instance or replaces the instance. - Instance store-backed instances are replaced. - EBS-backed instances are restarted. By default, restarting does not execute the new UserData so you will need a different mechanism to ensure the instance is restarted. Setting this to ``true`` will make the instance's Logical ID depend on the UserData, which will cause CloudFormation to replace it if the UserData changes. Default: - true iff ``initOptions`` is specified, false otherwise.
        :param vpc_subnets: Where to place the instance within the VPC. Default: - Private subnets.
        '''
        if isinstance(init_options, dict):
            init_options = ApplyCloudFormationInitOptions(**init_options)
        if isinstance(vpc_subnets, dict):
            vpc_subnets = SubnetSelection(**vpc_subnets)
        self._values: typing.Dict[str, typing.Any] = {
            "instance_type": instance_type,
            "machine_image": machine_image,
            "vpc": vpc,
        }
        if allow_all_outbound is not None:
            self._values["allow_all_outbound"] = allow_all_outbound
        if availability_zone is not None:
            self._values["availability_zone"] = availability_zone
        if block_devices is not None:
            self._values["block_devices"] = block_devices
        if init is not None:
            self._values["init"] = init
        if init_options is not None:
            self._values["init_options"] = init_options
        if instance_name is not None:
            self._values["instance_name"] = instance_name
        if key_name is not None:
            self._values["key_name"] = key_name
        if private_ip_address is not None:
            self._values["private_ip_address"] = private_ip_address
        if resource_signal_timeout is not None:
            self._values["resource_signal_timeout"] = resource_signal_timeout
        if role is not None:
            self._values["role"] = role
        if security_group is not None:
            self._values["security_group"] = security_group
        if source_dest_check is not None:
            self._values["source_dest_check"] = source_dest_check
        if user_data is not None:
            self._values["user_data"] = user_data
        if user_data_causes_replacement is not None:
            self._values["user_data_causes_replacement"] = user_data_causes_replacement
        if vpc_subnets is not None:
            self._values["vpc_subnets"] = vpc_subnets

    @builtins.property
    def instance_type(self) -> "InstanceType":
        '''Type of instance to launch.'''
        result = self._values.get("instance_type")
        assert result is not None, "Required property 'instance_type' is missing"
        return typing.cast("InstanceType", result)

    @builtins.property
    def machine_image(self) -> IMachineImage:
        '''AMI to launch.'''
        result = self._values.get("machine_image")
        assert result is not None, "Required property 'machine_image' is missing"
        return typing.cast(IMachineImage, result)

    @builtins.property
    def vpc(self) -> IVpc:
        '''VPC to launch the instance in.'''
        result = self._values.get("vpc")
        assert result is not None, "Required property 'vpc' is missing"
        return typing.cast(IVpc, result)

    @builtins.property
    def allow_all_outbound(self) -> typing.Optional[builtins.bool]:
        '''Whether the instance could initiate connections to anywhere by default.

        This property is only used when you do not provide a security group.

        :default: true
        '''
        result = self._values.get("allow_all_outbound")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def availability_zone(self) -> typing.Optional[builtins.str]:
        '''In which AZ to place the instance within the VPC.

        :default: - Random zone.
        '''
        result = self._values.get("availability_zone")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def block_devices(self) -> typing.Optional[typing.List[BlockDevice]]:
        '''Specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes.

        Each instance that is launched has an associated root device volume,
        either an Amazon EBS volume or an instance store volume.
        You can use block device mappings to specify additional EBS volumes or
        instance store volumes to attach to an instance when it is launched.

        :default: - Uses the block device mapping of the AMI

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html
        '''
        result = self._values.get("block_devices")
        return typing.cast(typing.Optional[typing.List[BlockDevice]], result)

    @builtins.property
    def init(self) -> typing.Optional[CloudFormationInit]:
        '''Apply the given CloudFormation Init configuration to the instance at startup.

        :default: - no CloudFormation init
        '''
        result = self._values.get("init")
        return typing.cast(typing.Optional[CloudFormationInit], result)

    @builtins.property
    def init_options(self) -> typing.Optional[ApplyCloudFormationInitOptions]:
        '''Use the given options for applying CloudFormation Init.

        Describes the configsets to use and the timeout to wait

        :default: - default options
        '''
        result = self._values.get("init_options")
        return typing.cast(typing.Optional[ApplyCloudFormationInitOptions], result)

    @builtins.property
    def instance_name(self) -> typing.Optional[builtins.str]:
        '''The name of the instance.

        :default: - CDK generated name
        '''
        result = self._values.get("instance_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def key_name(self) -> typing.Optional[builtins.str]:
        '''Name of SSH keypair to grant access to instance.

        :default: - No SSH access will be possible.
        '''
        result = self._values.get("key_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def private_ip_address(self) -> typing.Optional[builtins.str]:
        '''Defines a private IP address to associate with an instance.

        Private IP should be available within the VPC that the instance is build within.

        :default: - no association
        '''
        result = self._values.get("private_ip_address")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def resource_signal_timeout(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The length of time to wait for the resourceSignalCount.

        The maximum value is 43200 (12 hours).

        :default: Duration.minutes(5)
        '''
        result = self._values.get("resource_signal_timeout")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def role(self) -> typing.Optional[aws_cdk.aws_iam.IRole]:
        '''An IAM role to associate with the instance profile assigned to this Auto Scaling Group.

        The role must be assumable by the service principal ``ec2.amazonaws.com``:

        :default: - A role will automatically be created, it can be accessed via the ``role`` property

        Example::

            # Example automatically generated. See https://github.com/aws/jsii/issues/826
            role = iam.Role(self, "MyRole",
                assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")
            )
        '''
        result = self._values.get("role")
        return typing.cast(typing.Optional[aws_cdk.aws_iam.IRole], result)

    @builtins.property
    def security_group(self) -> typing.Optional[ISecurityGroup]:
        '''Security Group to assign to this instance.

        :default: - create new security group
        '''
        result = self._values.get("security_group")
        return typing.cast(typing.Optional[ISecurityGroup], result)

    @builtins.property
    def source_dest_check(self) -> typing.Optional[builtins.bool]:
        '''Specifies whether to enable an instance launched in a VPC to perform NAT.

        This controls whether source/destination checking is enabled on the instance.
        A value of true means that checking is enabled, and false means that checking is disabled.
        The value must be false for the instance to perform NAT.

        :default: true
        '''
        result = self._values.get("source_dest_check")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def user_data(self) -> typing.Optional["UserData"]:
        '''Specific UserData to use.

        The UserData may still be mutated after creation.

        :default:

        - A UserData object appropriate for the MachineImage's
        Operating System is created.
        '''
        result = self._values.get("user_data")
        return typing.cast(typing.Optional["UserData"], result)

    @builtins.property
    def user_data_causes_replacement(self) -> typing.Optional[builtins.bool]:
        '''Changes to the UserData force replacement.

        Depending the EC2 instance type, changing UserData either
        restarts the instance or replaces the instance.

        - Instance store-backed instances are replaced.
        - EBS-backed instances are restarted.

        By default, restarting does not execute the new UserData so you
        will need a different mechanism to ensure the instance is restarted.

        Setting this to ``true`` will make the instance's Logical ID depend on the
        UserData, which will cause CloudFormation to replace it if the UserData
        changes.

        :default: - true iff ``initOptions`` is specified, false otherwise.
        '''
        result = self._values.get("user_data_causes_replacement")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def vpc_subnets(self) -> typing.Optional["SubnetSelection"]:
        '''Where to place the instance within the VPC.

        :default: - Private subnets.
        '''
        result = self._values.get("vpc_subnets")
        return typing.cast(typing.Optional["SubnetSelection"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "InstanceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.InstanceSize")
class InstanceSize(enum.Enum):
    '''What size of instance to use.'''

    NANO = "NANO"
    '''Instance size NANO (nano).'''
    MICRO = "MICRO"
    '''Instance size MICRO (micro).'''
    SMALL = "SMALL"
    '''Instance size SMALL (small).'''
    MEDIUM = "MEDIUM"
    '''Instance size MEDIUM (medium).'''
    LARGE = "LARGE"
    '''Instance size LARGE (large).'''
    XLARGE = "XLARGE"
    '''Instance size XLARGE (xlarge).'''
    XLARGE2 = "XLARGE2"
    '''Instance size XLARGE2 (2xlarge).'''
    XLARGE4 = "XLARGE4"
    '''Instance size XLARGE4 (4xlarge).'''
    XLARGE6 = "XLARGE6"
    '''Instance size XLARGE6 (6xlarge).'''
    XLARGE8 = "XLARGE8"
    '''Instance size XLARGE8 (8xlarge).'''
    XLARGE9 = "XLARGE9"
    '''Instance size XLARGE9 (9xlarge).'''
    XLARGE10 = "XLARGE10"
    '''Instance size XLARGE10 (10xlarge).'''
    XLARGE12 = "XLARGE12"
    '''Instance size XLARGE12 (12xlarge).'''
    XLARGE16 = "XLARGE16"
    '''Instance size XLARGE16 (16xlarge).'''
    XLARGE18 = "XLARGE18"
    '''Instance size XLARGE18 (18xlarge).'''
    XLARGE24 = "XLARGE24"
    '''Instance size XLARGE24 (24xlarge).'''
    XLARGE32 = "XLARGE32"
    '''Instance size XLARGE32 (32xlarge).'''
    METAL = "METAL"
    '''Instance size METAL (metal).'''


class InstanceType(metaclass=jsii.JSIIMeta, jsii_type="@aws-cdk/aws-ec2.InstanceType"):
    '''Instance type for EC2 instances.

    This class takes a literal string, good if you already
    know the identifier of the type you want.
    '''

    def __init__(self, instance_type_identifier: builtins.str) -> None:
        '''
        :param instance_type_identifier: -
        '''
        jsii.create(InstanceType, self, [instance_type_identifier])

    @jsii.member(jsii_name="of") # type: ignore[misc]
    @builtins.classmethod
    def of(
        cls,
        instance_class: InstanceClass,
        instance_size: InstanceSize,
    ) -> "InstanceType":
        '''Instance type for EC2 instances.

        This class takes a combination of a class and size.

        Be aware that not all combinations of class and size are available, and not all
        classes are available in all regions.

        :param instance_class: -
        :param instance_size: -
        '''
        return typing.cast("InstanceType", jsii.sinvoke(cls, "of", [instance_class, instance_size]))

    @jsii.member(jsii_name="toString")
    def to_string(self) -> builtins.str:
        '''Return the instance type as a dotted string.'''
        return typing.cast(builtins.str, jsii.invoke(self, "toString", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="architecture")
    def architecture(self) -> InstanceArchitecture:
        '''The instance's CPU architecture.'''
        return typing.cast(InstanceArchitecture, jsii.get(self, "architecture"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.InterfaceVpcEndpointAttributes",
    jsii_struct_bases=[],
    name_mapping={
        "port": "port",
        "vpc_endpoint_id": "vpcEndpointId",
        "security_group_id": "securityGroupId",
        "security_groups": "securityGroups",
    },
)
class InterfaceVpcEndpointAttributes:
    def __init__(
        self,
        *,
        port: jsii.Number,
        vpc_endpoint_id: builtins.str,
        security_group_id: typing.Optional[builtins.str] = None,
        security_groups: typing.Optional[typing.List[ISecurityGroup]] = None,
    ) -> None:
        '''Construction properties for an ImportedInterfaceVpcEndpoint.

        :param port: The port of the service of the interface VPC endpoint.
        :param vpc_endpoint_id: The interface VPC endpoint identifier.
        :param security_group_id: (deprecated) The identifier of the security group associated with the interface VPC endpoint.
        :param security_groups: The security groups associated with the interface VPC endpoint.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "port": port,
            "vpc_endpoint_id": vpc_endpoint_id,
        }
        if security_group_id is not None:
            self._values["security_group_id"] = security_group_id
        if security_groups is not None:
            self._values["security_groups"] = security_groups

    @builtins.property
    def port(self) -> jsii.Number:
        '''The port of the service of the interface VPC endpoint.'''
        result = self._values.get("port")
        assert result is not None, "Required property 'port' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def vpc_endpoint_id(self) -> builtins.str:
        '''The interface VPC endpoint identifier.'''
        result = self._values.get("vpc_endpoint_id")
        assert result is not None, "Required property 'vpc_endpoint_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def security_group_id(self) -> typing.Optional[builtins.str]:
        '''(deprecated) The identifier of the security group associated with the interface VPC endpoint.

        :deprecated: use ``securityGroups`` instead

        :stability: deprecated
        '''
        result = self._values.get("security_group_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def security_groups(self) -> typing.Optional[typing.List[ISecurityGroup]]:
        '''The security groups associated with the interface VPC endpoint.'''
        result = self._values.get("security_groups")
        return typing.cast(typing.Optional[typing.List[ISecurityGroup]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "InterfaceVpcEndpointAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IInterfaceVpcEndpointService)
class InterfaceVpcEndpointAwsService(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.InterfaceVpcEndpointAwsService",
):
    '''An AWS service for an interface VPC endpoint.'''

    def __init__(
        self,
        name: builtins.str,
        prefix: typing.Optional[builtins.str] = None,
        port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''
        :param name: -
        :param prefix: -
        :param port: -
        '''
        jsii.create(InterfaceVpcEndpointAwsService, self, [name, prefix, port])

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="APIGATEWAY")
    def APIGATEWAY(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "APIGATEWAY"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ATHENA")
    def ATHENA(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "ATHENA"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CLOUDFORMATION")
    def CLOUDFORMATION(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CLOUDFORMATION"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CLOUDTRAIL")
    def CLOUDTRAIL(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CLOUDTRAIL"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CLOUDWATCH")
    def CLOUDWATCH(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CLOUDWATCH"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CLOUDWATCH_EVENTS")
    def CLOUDWATCH_EVENTS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CLOUDWATCH_EVENTS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CLOUDWATCH_LOGS")
    def CLOUDWATCH_LOGS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CLOUDWATCH_LOGS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CODEBUILD")
    def CODEBUILD(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CODEBUILD"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CODEBUILD_FIPS")
    def CODEBUILD_FIPS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CODEBUILD_FIPS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CODECOMMIT")
    def CODECOMMIT(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CODECOMMIT"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CODECOMMIT_FIPS")
    def CODECOMMIT_FIPS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CODECOMMIT_FIPS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CODECOMMIT_GIT")
    def CODECOMMIT_GIT(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CODECOMMIT_GIT"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CODECOMMIT_GIT_FIPS")
    def CODECOMMIT_GIT_FIPS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CODECOMMIT_GIT_FIPS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CODEPIPELINE")
    def CODEPIPELINE(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CODEPIPELINE"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CONFIG")
    def CONFIG(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "CONFIG"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="EC2")
    def EC2(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "EC2"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="EC2_MESSAGES")
    def EC2_MESSAGES(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "EC2_MESSAGES"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ECR")
    def ECR(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "ECR"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ECR_DOCKER")
    def ECR_DOCKER(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "ECR_DOCKER"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ECS")
    def ECS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "ECS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ECS_AGENT")
    def ECS_AGENT(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "ECS_AGENT"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ECS_TELEMETRY")
    def ECS_TELEMETRY(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "ECS_TELEMETRY"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ELASTIC_FILESYSTEM")
    def ELASTIC_FILESYSTEM(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "ELASTIC_FILESYSTEM"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ELASTIC_FILESYSTEM_FIPS")
    def ELASTIC_FILESYSTEM_FIPS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "ELASTIC_FILESYSTEM_FIPS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ELASTIC_INFERENCE_RUNTIME")
    def ELASTIC_INFERENCE_RUNTIME(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "ELASTIC_INFERENCE_RUNTIME"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ELASTIC_LOAD_BALANCING")
    def ELASTIC_LOAD_BALANCING(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "ELASTIC_LOAD_BALANCING"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="GLUE")
    def GLUE(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "GLUE"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="KINESIS_FIREHOSE")
    def KINESIS_FIREHOSE(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "KINESIS_FIREHOSE"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="KINESIS_STREAMS")
    def KINESIS_STREAMS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "KINESIS_STREAMS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="KMS")
    def KMS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "KMS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="LAMBDA")
    def LAMBDA_(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "LAMBDA"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="REKOGNITION")
    def REKOGNITION(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "REKOGNITION"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="REKOGNITION_FIPS")
    def REKOGNITION_FIPS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "REKOGNITION_FIPS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="SAGEMAKER_API")
    def SAGEMAKER_API(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "SAGEMAKER_API"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="SAGEMAKER_NOTEBOOK")
    def SAGEMAKER_NOTEBOOK(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "SAGEMAKER_NOTEBOOK"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="SAGEMAKER_RUNTIME")
    def SAGEMAKER_RUNTIME(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "SAGEMAKER_RUNTIME"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="SAGEMAKER_RUNTIME_FIPS")
    def SAGEMAKER_RUNTIME_FIPS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "SAGEMAKER_RUNTIME_FIPS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="SECRETS_MANAGER")
    def SECRETS_MANAGER(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "SECRETS_MANAGER"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="SERVICE_CATALOG")
    def SERVICE_CATALOG(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "SERVICE_CATALOG"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="SNS")
    def SNS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "SNS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="SQS")
    def SQS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "SQS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="SSM")
    def SSM(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "SSM"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="SSM_MESSAGES")
    def SSM_MESSAGES(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "SSM_MESSAGES"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="STEP_FUNCTIONS")
    def STEP_FUNCTIONS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "STEP_FUNCTIONS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="STORAGE_GATEWAY")
    def STORAGE_GATEWAY(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "STORAGE_GATEWAY"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="STS")
    def STS(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "STS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="TRANSFER")
    def TRANSFER(cls) -> "InterfaceVpcEndpointAwsService":
        return typing.cast("InterfaceVpcEndpointAwsService", jsii.sget(cls, "TRANSFER"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="name")
    def name(self) -> builtins.str:
        '''The name of the service.'''
        return typing.cast(builtins.str, jsii.get(self, "name"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="port")
    def port(self) -> jsii.Number:
        '''The port of the service.'''
        return typing.cast(jsii.Number, jsii.get(self, "port"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateDnsDefault")
    def private_dns_default(self) -> typing.Optional[builtins.bool]:
        '''Whether Private DNS is supported by default.'''
        return typing.cast(typing.Optional[builtins.bool], jsii.get(self, "privateDnsDefault"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.InterfaceVpcEndpointOptions",
    jsii_struct_bases=[],
    name_mapping={
        "service": "service",
        "lookup_supported_azs": "lookupSupportedAzs",
        "open": "open",
        "private_dns_enabled": "privateDnsEnabled",
        "security_groups": "securityGroups",
        "subnets": "subnets",
    },
)
class InterfaceVpcEndpointOptions:
    def __init__(
        self,
        *,
        service: IInterfaceVpcEndpointService,
        lookup_supported_azs: typing.Optional[builtins.bool] = None,
        open: typing.Optional[builtins.bool] = None,
        private_dns_enabled: typing.Optional[builtins.bool] = None,
        security_groups: typing.Optional[typing.List[ISecurityGroup]] = None,
        subnets: typing.Optional["SubnetSelection"] = None,
    ) -> None:
        '''Options to add an interface endpoint to a VPC.

        :param service: The service to use for this interface VPC endpoint.
        :param lookup_supported_azs: Limit to only those availability zones where the endpoint service can be created. Setting this to 'true' requires a lookup to be performed at synthesis time. Account and region must be set on the containing stack for this to work. Default: false
        :param open: Whether to automatically allow VPC traffic to the endpoint. If enabled, all traffic to the endpoint from within the VPC will be automatically allowed. This is done based on the VPC's CIDR range. Default: true
        :param private_dns_enabled: Whether to associate a private hosted zone with the specified VPC. This allows you to make requests to the service using its default DNS hostname. Default: set by the instance of IInterfaceVpcEndpointService, or true if not defined by the instance of IInterfaceVpcEndpointService
        :param security_groups: The security groups to associate with this interface VPC endpoint. Default: - a new security group is created
        :param subnets: The subnets in which to create an endpoint network interface. At most one per availability zone. Default: - private subnets
        '''
        if isinstance(subnets, dict):
            subnets = SubnetSelection(**subnets)
        self._values: typing.Dict[str, typing.Any] = {
            "service": service,
        }
        if lookup_supported_azs is not None:
            self._values["lookup_supported_azs"] = lookup_supported_azs
        if open is not None:
            self._values["open"] = open
        if private_dns_enabled is not None:
            self._values["private_dns_enabled"] = private_dns_enabled
        if security_groups is not None:
            self._values["security_groups"] = security_groups
        if subnets is not None:
            self._values["subnets"] = subnets

    @builtins.property
    def service(self) -> IInterfaceVpcEndpointService:
        '''The service to use for this interface VPC endpoint.'''
        result = self._values.get("service")
        assert result is not None, "Required property 'service' is missing"
        return typing.cast(IInterfaceVpcEndpointService, result)

    @builtins.property
    def lookup_supported_azs(self) -> typing.Optional[builtins.bool]:
        '''Limit to only those availability zones where the endpoint service can be created.

        Setting this to 'true' requires a lookup to be performed at synthesis time. Account
        and region must be set on the containing stack for this to work.

        :default: false
        '''
        result = self._values.get("lookup_supported_azs")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def open(self) -> typing.Optional[builtins.bool]:
        '''Whether to automatically allow VPC traffic to the endpoint.

        If enabled, all traffic to the endpoint from within the VPC will be
        automatically allowed. This is done based on the VPC's CIDR range.

        :default: true
        '''
        result = self._values.get("open")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def private_dns_enabled(self) -> typing.Optional[builtins.bool]:
        '''Whether to associate a private hosted zone with the specified VPC.

        This
        allows you to make requests to the service using its default DNS hostname.

        :default:

        set by the instance of IInterfaceVpcEndpointService, or true if
        not defined by the instance of IInterfaceVpcEndpointService
        '''
        result = self._values.get("private_dns_enabled")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def security_groups(self) -> typing.Optional[typing.List[ISecurityGroup]]:
        '''The security groups to associate with this interface VPC endpoint.

        :default: - a new security group is created
        '''
        result = self._values.get("security_groups")
        return typing.cast(typing.Optional[typing.List[ISecurityGroup]], result)

    @builtins.property
    def subnets(self) -> typing.Optional["SubnetSelection"]:
        '''The subnets in which to create an endpoint network interface.

        At most one
        per availability zone.

        :default: - private subnets
        '''
        result = self._values.get("subnets")
        return typing.cast(typing.Optional["SubnetSelection"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "InterfaceVpcEndpointOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.InterfaceVpcEndpointProps",
    jsii_struct_bases=[InterfaceVpcEndpointOptions],
    name_mapping={
        "service": "service",
        "lookup_supported_azs": "lookupSupportedAzs",
        "open": "open",
        "private_dns_enabled": "privateDnsEnabled",
        "security_groups": "securityGroups",
        "subnets": "subnets",
        "vpc": "vpc",
    },
)
class InterfaceVpcEndpointProps(InterfaceVpcEndpointOptions):
    def __init__(
        self,
        *,
        service: IInterfaceVpcEndpointService,
        lookup_supported_azs: typing.Optional[builtins.bool] = None,
        open: typing.Optional[builtins.bool] = None,
        private_dns_enabled: typing.Optional[builtins.bool] = None,
        security_groups: typing.Optional[typing.List[ISecurityGroup]] = None,
        subnets: typing.Optional["SubnetSelection"] = None,
        vpc: IVpc,
    ) -> None:
        '''Construction properties for an InterfaceVpcEndpoint.

        :param service: The service to use for this interface VPC endpoint.
        :param lookup_supported_azs: Limit to only those availability zones where the endpoint service can be created. Setting this to 'true' requires a lookup to be performed at synthesis time. Account and region must be set on the containing stack for this to work. Default: false
        :param open: Whether to automatically allow VPC traffic to the endpoint. If enabled, all traffic to the endpoint from within the VPC will be automatically allowed. This is done based on the VPC's CIDR range. Default: true
        :param private_dns_enabled: Whether to associate a private hosted zone with the specified VPC. This allows you to make requests to the service using its default DNS hostname. Default: set by the instance of IInterfaceVpcEndpointService, or true if not defined by the instance of IInterfaceVpcEndpointService
        :param security_groups: The security groups to associate with this interface VPC endpoint. Default: - a new security group is created
        :param subnets: The subnets in which to create an endpoint network interface. At most one per availability zone. Default: - private subnets
        :param vpc: The VPC network in which the interface endpoint will be used.
        '''
        if isinstance(subnets, dict):
            subnets = SubnetSelection(**subnets)
        self._values: typing.Dict[str, typing.Any] = {
            "service": service,
            "vpc": vpc,
        }
        if lookup_supported_azs is not None:
            self._values["lookup_supported_azs"] = lookup_supported_azs
        if open is not None:
            self._values["open"] = open
        if private_dns_enabled is not None:
            self._values["private_dns_enabled"] = private_dns_enabled
        if security_groups is not None:
            self._values["security_groups"] = security_groups
        if subnets is not None:
            self._values["subnets"] = subnets

    @builtins.property
    def service(self) -> IInterfaceVpcEndpointService:
        '''The service to use for this interface VPC endpoint.'''
        result = self._values.get("service")
        assert result is not None, "Required property 'service' is missing"
        return typing.cast(IInterfaceVpcEndpointService, result)

    @builtins.property
    def lookup_supported_azs(self) -> typing.Optional[builtins.bool]:
        '''Limit to only those availability zones where the endpoint service can be created.

        Setting this to 'true' requires a lookup to be performed at synthesis time. Account
        and region must be set on the containing stack for this to work.

        :default: false
        '''
        result = self._values.get("lookup_supported_azs")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def open(self) -> typing.Optional[builtins.bool]:
        '''Whether to automatically allow VPC traffic to the endpoint.

        If enabled, all traffic to the endpoint from within the VPC will be
        automatically allowed. This is done based on the VPC's CIDR range.

        :default: true
        '''
        result = self._values.get("open")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def private_dns_enabled(self) -> typing.Optional[builtins.bool]:
        '''Whether to associate a private hosted zone with the specified VPC.

        This
        allows you to make requests to the service using its default DNS hostname.

        :default:

        set by the instance of IInterfaceVpcEndpointService, or true if
        not defined by the instance of IInterfaceVpcEndpointService
        '''
        result = self._values.get("private_dns_enabled")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def security_groups(self) -> typing.Optional[typing.List[ISecurityGroup]]:
        '''The security groups to associate with this interface VPC endpoint.

        :default: - a new security group is created
        '''
        result = self._values.get("security_groups")
        return typing.cast(typing.Optional[typing.List[ISecurityGroup]], result)

    @builtins.property
    def subnets(self) -> typing.Optional["SubnetSelection"]:
        '''The subnets in which to create an endpoint network interface.

        At most one
        per availability zone.

        :default: - private subnets
        '''
        result = self._values.get("subnets")
        return typing.cast(typing.Optional["SubnetSelection"], result)

    @builtins.property
    def vpc(self) -> IVpc:
        '''The VPC network in which the interface endpoint will be used.'''
        result = self._values.get("vpc")
        assert result is not None, "Required property 'vpc' is missing"
        return typing.cast(IVpc, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "InterfaceVpcEndpointProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IInterfaceVpcEndpointService)
class InterfaceVpcEndpointService(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.InterfaceVpcEndpointService",
):
    '''A custom-hosted service for an interface VPC endpoint.'''

    def __init__(
        self,
        name: builtins.str,
        port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''
        :param name: -
        :param port: -
        '''
        jsii.create(InterfaceVpcEndpointService, self, [name, port])

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="name")
    def name(self) -> builtins.str:
        '''The name of the service.'''
        return typing.cast(builtins.str, jsii.get(self, "name"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="port")
    def port(self) -> jsii.Number:
        '''The port of the service.'''
        return typing.cast(jsii.Number, jsii.get(self, "port"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateDnsDefault")
    def private_dns_default(self) -> typing.Optional[builtins.bool]:
        '''Whether Private DNS is supported by default.'''
        return typing.cast(typing.Optional[builtins.bool], jsii.get(self, "privateDnsDefault"))


@jsii.implements(ILaunchTemplate, aws_cdk.aws_iam.IGrantable, IConnectable)
class LaunchTemplate(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.LaunchTemplate",
):
    '''This represents an EC2 LaunchTemplate.

    :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        block_devices: typing.Optional[typing.List[BlockDevice]] = None,
        cpu_credits: typing.Optional[CpuCredits] = None,
        detailed_monitoring: typing.Optional[builtins.bool] = None,
        disable_api_termination: typing.Optional[builtins.bool] = None,
        ebs_optimized: typing.Optional[builtins.bool] = None,
        hibernation_configured: typing.Optional[builtins.bool] = None,
        instance_initiated_shutdown_behavior: typing.Optional[InstanceInitiatedShutdownBehavior] = None,
        instance_type: typing.Optional[InstanceType] = None,
        key_name: typing.Optional[builtins.str] = None,
        launch_template_name: typing.Optional[builtins.str] = None,
        machine_image: typing.Optional[IMachineImage] = None,
        nitro_enclave_enabled: typing.Optional[builtins.bool] = None,
        role: typing.Optional[aws_cdk.aws_iam.IRole] = None,
        security_group: typing.Optional[ISecurityGroup] = None,
        spot_options: typing.Optional["LaunchTemplateSpotOptions"] = None,
        user_data: typing.Optional["UserData"] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param block_devices: Specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes. Each instance that is launched has an associated root device volume, either an Amazon EBS volume or an instance store volume. You can use block device mappings to specify additional EBS volumes or instance store volumes to attach to an instance when it is launched. Default: - Uses the block device mapping of the AMI
        :param cpu_credits: CPU credit type for burstable EC2 instance types. Default: - No credit type is specified in the Launch Template.
        :param detailed_monitoring: If set to true, then detailed monitoring will be enabled on instances created with this launch template. Default: False - Detailed monitoring is disabled.
        :param disable_api_termination: If you set this parameter to true, you cannot terminate the instances launched with this launch template using the Amazon EC2 console, CLI, or API; otherwise, you can. Default: - The API termination setting is not specified in the Launch Template.
        :param ebs_optimized: Indicates whether the instances are optimized for Amazon EBS I/O. This optimization provides dedicated throughput to Amazon EBS and an optimized configuration stack to provide optimal Amazon EBS I/O performance. This optimization isn't available with all instance types. Additional usage charges apply when using an EBS-optimized instance. Default: - EBS optimization is not specified in the launch template.
        :param hibernation_configured: If you set this parameter to true, the instance is enabled for hibernation. Default: - Hibernation configuration is not specified in the launch template; defaulting to false.
        :param instance_initiated_shutdown_behavior: Indicates whether an instance stops or terminates when you initiate shutdown from the instance (using the operating system command for system shutdown). Default: - Shutdown behavior is not specified in the launch template; defaults to STOP.
        :param instance_type: Type of instance to launch. Default: - This Launch Template does not specify a default Instance Type.
        :param key_name: Name of SSH keypair to grant access to instance. Default: - No SSH access will be possible.
        :param launch_template_name: Name for this launch template. Default: Automatically generated name
        :param machine_image: The AMI that will be used by instances. Default: - This Launch Template does not specify a default AMI.
        :param nitro_enclave_enabled: If this parameter is set to true, the instance is enabled for AWS Nitro Enclaves; otherwise, it is not enabled for AWS Nitro Enclaves. Default: - Enablement of Nitro enclaves is not specified in the launch template; defaulting to false.
        :param role: An IAM role to associate with the instance profile that is used by instances. The role must be assumable by the service principal ``ec2.amazonaws.com``: Default: - No new role is created.
        :param security_group: Security group to assign to instances created with the launch template. Default: No security group is assigned.
        :param spot_options: If this property is defined, then the Launch Template's InstanceMarketOptions will be set to use Spot instances, and the options for the Spot instances will be as defined. Default: - Instance launched with this template will not be spot instances.
        :param user_data: The AMI that will be used by instances. Default: - This Launch Template creates a UserData based on the type of provided machineImage; no UserData is created if a machineImage is not provided
        '''
        props = LaunchTemplateProps(
            block_devices=block_devices,
            cpu_credits=cpu_credits,
            detailed_monitoring=detailed_monitoring,
            disable_api_termination=disable_api_termination,
            ebs_optimized=ebs_optimized,
            hibernation_configured=hibernation_configured,
            instance_initiated_shutdown_behavior=instance_initiated_shutdown_behavior,
            instance_type=instance_type,
            key_name=key_name,
            launch_template_name=launch_template_name,
            machine_image=machine_image,
            nitro_enclave_enabled=nitro_enclave_enabled,
            role=role,
            security_group=security_group,
            spot_options=spot_options,
            user_data=user_data,
        )

        jsii.create(LaunchTemplate, self, [scope, id, props])

    @jsii.member(jsii_name="fromLaunchTemplateAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_launch_template_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        launch_template_id: typing.Optional[builtins.str] = None,
        launch_template_name: typing.Optional[builtins.str] = None,
        version_number: typing.Optional[builtins.str] = None,
    ) -> ILaunchTemplate:
        '''Import an existing LaunchTemplate.

        :param scope: -
        :param id: -
        :param launch_template_id: The identifier of the Launch Template. Exactly one of ``launchTemplateId`` and ``launchTemplateName`` may be set. Default: None
        :param launch_template_name: The name of the Launch Template. Exactly one of ``launchTemplateId`` and ``launchTemplateName`` may be set. Default: None
        :param version_number: The version number of this launch template to use. Default: Version: "$Default"
        '''
        attrs = LaunchTemplateAttributes(
            launch_template_id=launch_template_id,
            launch_template_name=launch_template_name,
            version_number=version_number,
        )

        return typing.cast(ILaunchTemplate, jsii.sinvoke(cls, "fromLaunchTemplateAttributes", [scope, id, attrs]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connections")
    def connections(self) -> "Connections":
        '''Allows specifying security group connections for the instance.

        :note: Only available if you provide a securityGroup when constructing the LaunchTemplate.
        '''
        return typing.cast("Connections", jsii.get(self, "connections"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="defaultVersionNumber")
    def default_version_number(self) -> builtins.str:
        '''The default version for the launch template.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "defaultVersionNumber"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="grantPrincipal")
    def grant_principal(self) -> aws_cdk.aws_iam.IPrincipal:
        '''Principal to grant permissions to.

        :note: Only available if you provide a role when constructing the LaunchTemplate.
        '''
        return typing.cast(aws_cdk.aws_iam.IPrincipal, jsii.get(self, "grantPrincipal"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="latestVersionNumber")
    def latest_version_number(self) -> builtins.str:
        '''The latest version of the launch template.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "latestVersionNumber"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def _tags(self) -> aws_cdk.core.TagManager:
        '''TagManager for tagging support.'''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="versionNumber")
    def version_number(self) -> builtins.str:
        '''The version number of this launch template to use.'''
        return typing.cast(builtins.str, jsii.get(self, "versionNumber"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="launchTemplateId")
    def launch_template_id(self) -> typing.Optional[builtins.str]:
        '''The identifier of the Launch Template.

        Exactly one of ``launchTemplateId`` and ``launchTemplateName`` will be set.
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "launchTemplateId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="launchTemplateName")
    def launch_template_name(self) -> typing.Optional[builtins.str]:
        '''The name of the Launch Template.

        Exactly one of ``launchTemplateId`` and ``launchTemplateName`` will be set.
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "launchTemplateName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="osType")
    def os_type(self) -> typing.Optional["OperatingSystemType"]:
        '''The type of OS the instance is running.

        :attribute: true
        '''
        return typing.cast(typing.Optional["OperatingSystemType"], jsii.get(self, "osType"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="role")
    def role(self) -> typing.Optional[aws_cdk.aws_iam.IRole]:
        '''IAM Role assumed by instances that are launched from this template.

        :attribute: true
        '''
        return typing.cast(typing.Optional[aws_cdk.aws_iam.IRole], jsii.get(self, "role"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="userData")
    def user_data(self) -> typing.Optional["UserData"]:
        '''UserData executed by instances that are launched from this template.

        :attribute: true
        '''
        return typing.cast(typing.Optional["UserData"], jsii.get(self, "userData"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.LaunchTemplateAttributes",
    jsii_struct_bases=[],
    name_mapping={
        "launch_template_id": "launchTemplateId",
        "launch_template_name": "launchTemplateName",
        "version_number": "versionNumber",
    },
)
class LaunchTemplateAttributes:
    def __init__(
        self,
        *,
        launch_template_id: typing.Optional[builtins.str] = None,
        launch_template_name: typing.Optional[builtins.str] = None,
        version_number: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Attributes for an imported LaunchTemplate.

        :param launch_template_id: The identifier of the Launch Template. Exactly one of ``launchTemplateId`` and ``launchTemplateName`` may be set. Default: None
        :param launch_template_name: The name of the Launch Template. Exactly one of ``launchTemplateId`` and ``launchTemplateName`` may be set. Default: None
        :param version_number: The version number of this launch template to use. Default: Version: "$Default"
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if launch_template_id is not None:
            self._values["launch_template_id"] = launch_template_id
        if launch_template_name is not None:
            self._values["launch_template_name"] = launch_template_name
        if version_number is not None:
            self._values["version_number"] = version_number

    @builtins.property
    def launch_template_id(self) -> typing.Optional[builtins.str]:
        '''The identifier of the Launch Template.

        Exactly one of ``launchTemplateId`` and ``launchTemplateName`` may be set.

        :default: None
        '''
        result = self._values.get("launch_template_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def launch_template_name(self) -> typing.Optional[builtins.str]:
        '''The name of the Launch Template.

        Exactly one of ``launchTemplateId`` and ``launchTemplateName`` may be set.

        :default: None
        '''
        result = self._values.get("launch_template_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def version_number(self) -> typing.Optional[builtins.str]:
        '''The version number of this launch template to use.

        :default: Version: "$Default"
        '''
        result = self._values.get("version_number")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LaunchTemplateAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.LaunchTemplateProps",
    jsii_struct_bases=[],
    name_mapping={
        "block_devices": "blockDevices",
        "cpu_credits": "cpuCredits",
        "detailed_monitoring": "detailedMonitoring",
        "disable_api_termination": "disableApiTermination",
        "ebs_optimized": "ebsOptimized",
        "hibernation_configured": "hibernationConfigured",
        "instance_initiated_shutdown_behavior": "instanceInitiatedShutdownBehavior",
        "instance_type": "instanceType",
        "key_name": "keyName",
        "launch_template_name": "launchTemplateName",
        "machine_image": "machineImage",
        "nitro_enclave_enabled": "nitroEnclaveEnabled",
        "role": "role",
        "security_group": "securityGroup",
        "spot_options": "spotOptions",
        "user_data": "userData",
    },
)
class LaunchTemplateProps:
    def __init__(
        self,
        *,
        block_devices: typing.Optional[typing.List[BlockDevice]] = None,
        cpu_credits: typing.Optional[CpuCredits] = None,
        detailed_monitoring: typing.Optional[builtins.bool] = None,
        disable_api_termination: typing.Optional[builtins.bool] = None,
        ebs_optimized: typing.Optional[builtins.bool] = None,
        hibernation_configured: typing.Optional[builtins.bool] = None,
        instance_initiated_shutdown_behavior: typing.Optional[InstanceInitiatedShutdownBehavior] = None,
        instance_type: typing.Optional[InstanceType] = None,
        key_name: typing.Optional[builtins.str] = None,
        launch_template_name: typing.Optional[builtins.str] = None,
        machine_image: typing.Optional[IMachineImage] = None,
        nitro_enclave_enabled: typing.Optional[builtins.bool] = None,
        role: typing.Optional[aws_cdk.aws_iam.IRole] = None,
        security_group: typing.Optional[ISecurityGroup] = None,
        spot_options: typing.Optional["LaunchTemplateSpotOptions"] = None,
        user_data: typing.Optional["UserData"] = None,
    ) -> None:
        '''Properties of a LaunchTemplate.

        :param block_devices: Specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes. Each instance that is launched has an associated root device volume, either an Amazon EBS volume or an instance store volume. You can use block device mappings to specify additional EBS volumes or instance store volumes to attach to an instance when it is launched. Default: - Uses the block device mapping of the AMI
        :param cpu_credits: CPU credit type for burstable EC2 instance types. Default: - No credit type is specified in the Launch Template.
        :param detailed_monitoring: If set to true, then detailed monitoring will be enabled on instances created with this launch template. Default: False - Detailed monitoring is disabled.
        :param disable_api_termination: If you set this parameter to true, you cannot terminate the instances launched with this launch template using the Amazon EC2 console, CLI, or API; otherwise, you can. Default: - The API termination setting is not specified in the Launch Template.
        :param ebs_optimized: Indicates whether the instances are optimized for Amazon EBS I/O. This optimization provides dedicated throughput to Amazon EBS and an optimized configuration stack to provide optimal Amazon EBS I/O performance. This optimization isn't available with all instance types. Additional usage charges apply when using an EBS-optimized instance. Default: - EBS optimization is not specified in the launch template.
        :param hibernation_configured: If you set this parameter to true, the instance is enabled for hibernation. Default: - Hibernation configuration is not specified in the launch template; defaulting to false.
        :param instance_initiated_shutdown_behavior: Indicates whether an instance stops or terminates when you initiate shutdown from the instance (using the operating system command for system shutdown). Default: - Shutdown behavior is not specified in the launch template; defaults to STOP.
        :param instance_type: Type of instance to launch. Default: - This Launch Template does not specify a default Instance Type.
        :param key_name: Name of SSH keypair to grant access to instance. Default: - No SSH access will be possible.
        :param launch_template_name: Name for this launch template. Default: Automatically generated name
        :param machine_image: The AMI that will be used by instances. Default: - This Launch Template does not specify a default AMI.
        :param nitro_enclave_enabled: If this parameter is set to true, the instance is enabled for AWS Nitro Enclaves; otherwise, it is not enabled for AWS Nitro Enclaves. Default: - Enablement of Nitro enclaves is not specified in the launch template; defaulting to false.
        :param role: An IAM role to associate with the instance profile that is used by instances. The role must be assumable by the service principal ``ec2.amazonaws.com``: Default: - No new role is created.
        :param security_group: Security group to assign to instances created with the launch template. Default: No security group is assigned.
        :param spot_options: If this property is defined, then the Launch Template's InstanceMarketOptions will be set to use Spot instances, and the options for the Spot instances will be as defined. Default: - Instance launched with this template will not be spot instances.
        :param user_data: The AMI that will be used by instances. Default: - This Launch Template creates a UserData based on the type of provided machineImage; no UserData is created if a machineImage is not provided
        '''
        if isinstance(spot_options, dict):
            spot_options = LaunchTemplateSpotOptions(**spot_options)
        self._values: typing.Dict[str, typing.Any] = {}
        if block_devices is not None:
            self._values["block_devices"] = block_devices
        if cpu_credits is not None:
            self._values["cpu_credits"] = cpu_credits
        if detailed_monitoring is not None:
            self._values["detailed_monitoring"] = detailed_monitoring
        if disable_api_termination is not None:
            self._values["disable_api_termination"] = disable_api_termination
        if ebs_optimized is not None:
            self._values["ebs_optimized"] = ebs_optimized
        if hibernation_configured is not None:
            self._values["hibernation_configured"] = hibernation_configured
        if instance_initiated_shutdown_behavior is not None:
            self._values["instance_initiated_shutdown_behavior"] = instance_initiated_shutdown_behavior
        if instance_type is not None:
            self._values["instance_type"] = instance_type
        if key_name is not None:
            self._values["key_name"] = key_name
        if launch_template_name is not None:
            self._values["launch_template_name"] = launch_template_name
        if machine_image is not None:
            self._values["machine_image"] = machine_image
        if nitro_enclave_enabled is not None:
            self._values["nitro_enclave_enabled"] = nitro_enclave_enabled
        if role is not None:
            self._values["role"] = role
        if security_group is not None:
            self._values["security_group"] = security_group
        if spot_options is not None:
            self._values["spot_options"] = spot_options
        if user_data is not None:
            self._values["user_data"] = user_data

    @builtins.property
    def block_devices(self) -> typing.Optional[typing.List[BlockDevice]]:
        '''Specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes.

        Each instance that is launched has an associated root device volume,
        either an Amazon EBS volume or an instance store volume.
        You can use block device mappings to specify additional EBS volumes or
        instance store volumes to attach to an instance when it is launched.

        :default: - Uses the block device mapping of the AMI

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html
        '''
        result = self._values.get("block_devices")
        return typing.cast(typing.Optional[typing.List[BlockDevice]], result)

    @builtins.property
    def cpu_credits(self) -> typing.Optional[CpuCredits]:
        '''CPU credit type for burstable EC2 instance types.

        :default: - No credit type is specified in the Launch Template.

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable-performance-instances.html
        '''
        result = self._values.get("cpu_credits")
        return typing.cast(typing.Optional[CpuCredits], result)

    @builtins.property
    def detailed_monitoring(self) -> typing.Optional[builtins.bool]:
        '''If set to true, then detailed monitoring will be enabled on instances created with this launch template.

        :default: False - Detailed monitoring is disabled.

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-cloudwatch-new.html
        '''
        result = self._values.get("detailed_monitoring")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def disable_api_termination(self) -> typing.Optional[builtins.bool]:
        '''If you set this parameter to true, you cannot terminate the instances launched with this launch template using the Amazon EC2 console, CLI, or API;

        otherwise, you can.

        :default: - The API termination setting is not specified in the Launch Template.
        '''
        result = self._values.get("disable_api_termination")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def ebs_optimized(self) -> typing.Optional[builtins.bool]:
        '''Indicates whether the instances are optimized for Amazon EBS I/O.

        This optimization provides dedicated throughput
        to Amazon EBS and an optimized configuration stack to provide optimal Amazon EBS I/O performance. This optimization
        isn't available with all instance types. Additional usage charges apply when using an EBS-optimized instance.

        :default: - EBS optimization is not specified in the launch template.
        '''
        result = self._values.get("ebs_optimized")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def hibernation_configured(self) -> typing.Optional[builtins.bool]:
        '''If you set this parameter to true, the instance is enabled for hibernation.

        :default: - Hibernation configuration is not specified in the launch template; defaulting to false.
        '''
        result = self._values.get("hibernation_configured")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def instance_initiated_shutdown_behavior(
        self,
    ) -> typing.Optional[InstanceInitiatedShutdownBehavior]:
        '''Indicates whether an instance stops or terminates when you initiate shutdown from the instance (using the operating system command for system shutdown).

        :default: - Shutdown behavior is not specified in the launch template; defaults to STOP.

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingInstanceInitiatedShutdownBehavior
        '''
        result = self._values.get("instance_initiated_shutdown_behavior")
        return typing.cast(typing.Optional[InstanceInitiatedShutdownBehavior], result)

    @builtins.property
    def instance_type(self) -> typing.Optional[InstanceType]:
        '''Type of instance to launch.

        :default: - This Launch Template does not specify a default Instance Type.
        '''
        result = self._values.get("instance_type")
        return typing.cast(typing.Optional[InstanceType], result)

    @builtins.property
    def key_name(self) -> typing.Optional[builtins.str]:
        '''Name of SSH keypair to grant access to instance.

        :default: - No SSH access will be possible.
        '''
        result = self._values.get("key_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def launch_template_name(self) -> typing.Optional[builtins.str]:
        '''Name for this launch template.

        :default: Automatically generated name
        '''
        result = self._values.get("launch_template_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def machine_image(self) -> typing.Optional[IMachineImage]:
        '''The AMI that will be used by instances.

        :default: - This Launch Template does not specify a default AMI.
        '''
        result = self._values.get("machine_image")
        return typing.cast(typing.Optional[IMachineImage], result)

    @builtins.property
    def nitro_enclave_enabled(self) -> typing.Optional[builtins.bool]:
        '''If this parameter is set to true, the instance is enabled for AWS Nitro Enclaves;

        otherwise, it is not enabled for AWS Nitro Enclaves.

        :default: - Enablement of Nitro enclaves is not specified in the launch template; defaulting to false.
        '''
        result = self._values.get("nitro_enclave_enabled")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def role(self) -> typing.Optional[aws_cdk.aws_iam.IRole]:
        '''An IAM role to associate with the instance profile that is used by instances.

        The role must be assumable by the service principal ``ec2.amazonaws.com``:

        :default: - No new role is created.

        Example::

            # Example automatically generated. See https://github.com/aws/jsii/issues/826
            role = iam.Role(self, "MyRole",
                assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")
            )
        '''
        result = self._values.get("role")
        return typing.cast(typing.Optional[aws_cdk.aws_iam.IRole], result)

    @builtins.property
    def security_group(self) -> typing.Optional[ISecurityGroup]:
        '''Security group to assign to instances created with the launch template.

        :default: No security group is assigned.
        '''
        result = self._values.get("security_group")
        return typing.cast(typing.Optional[ISecurityGroup], result)

    @builtins.property
    def spot_options(self) -> typing.Optional["LaunchTemplateSpotOptions"]:
        '''If this property is defined, then the Launch Template's InstanceMarketOptions will be set to use Spot instances, and the options for the Spot instances will be as defined.

        :default: - Instance launched with this template will not be spot instances.
        '''
        result = self._values.get("spot_options")
        return typing.cast(typing.Optional["LaunchTemplateSpotOptions"], result)

    @builtins.property
    def user_data(self) -> typing.Optional["UserData"]:
        '''The AMI that will be used by instances.

        :default:

        - This Launch Template creates a UserData based on the type of provided
        machineImage; no UserData is created if a machineImage is not provided
        '''
        result = self._values.get("user_data")
        return typing.cast(typing.Optional["UserData"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LaunchTemplateProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class LaunchTemplateSpecialVersions(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.LaunchTemplateSpecialVersions",
):
    '''A class that provides convenient access to special version tokens for LaunchTemplate versions.'''

    def __init__(self) -> None:
        jsii.create(LaunchTemplateSpecialVersions, self, [])

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="DEFAULT_VERSION")
    def DEFAULT_VERSION(cls) -> builtins.str:
        '''The special value that denotes that users of a Launch Template should reference the DEFAULT version of the template.'''
        return typing.cast(builtins.str, jsii.sget(cls, "DEFAULT_VERSION"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="LATEST_VERSION")
    def LATEST_VERSION(cls) -> builtins.str:
        '''The special value that denotes that users of a Launch Template should reference the LATEST version of the template.'''
        return typing.cast(builtins.str, jsii.sget(cls, "LATEST_VERSION"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.LaunchTemplateSpotOptions",
    jsii_struct_bases=[],
    name_mapping={
        "block_duration": "blockDuration",
        "interruption_behavior": "interruptionBehavior",
        "max_price": "maxPrice",
        "request_type": "requestType",
        "valid_until": "validUntil",
    },
)
class LaunchTemplateSpotOptions:
    def __init__(
        self,
        *,
        block_duration: typing.Optional[aws_cdk.core.Duration] = None,
        interruption_behavior: typing.Optional["SpotInstanceInterruption"] = None,
        max_price: typing.Optional[jsii.Number] = None,
        request_type: typing.Optional["SpotRequestType"] = None,
        valid_until: typing.Optional[aws_cdk.core.Expiration] = None,
    ) -> None:
        '''Interface for the Spot market instance options provided in a LaunchTemplate.

        :param block_duration: Spot Instances with a defined duration (also known as Spot blocks) are designed not to be interrupted and will run continuously for the duration you select. You can use a duration of 1, 2, 3, 4, 5, or 6 hours. Default: Requested spot instances do not have a pre-defined duration.
        :param interruption_behavior: The behavior when a Spot Instance is interrupted. Default: Spot instances will terminate when interrupted.
        :param max_price: Maximum hourly price you're willing to pay for each Spot instance. The value is given in dollars. ex: 0.01 for 1 cent per hour, or 0.001 for one-tenth of a cent per hour. Default: Maximum hourly price will default to the on-demand price for the instance type.
        :param request_type: The Spot Instance request type. If you are using Spot Instances with an Auto Scaling group, use one-time requests, as the Amazon EC2 Auto Scaling service handles requesting new Spot Instances whenever the group is below its desired capacity. Default: One-time spot request.
        :param valid_until: The end date of the request. For a one-time request, the request remains active until all instances launch, the request is canceled, or this date is reached. If the request is persistent, it remains active until it is canceled or this date and time is reached. Default: The default end date is 7 days from the current date.
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if block_duration is not None:
            self._values["block_duration"] = block_duration
        if interruption_behavior is not None:
            self._values["interruption_behavior"] = interruption_behavior
        if max_price is not None:
            self._values["max_price"] = max_price
        if request_type is not None:
            self._values["request_type"] = request_type
        if valid_until is not None:
            self._values["valid_until"] = valid_until

    @builtins.property
    def block_duration(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''Spot Instances with a defined duration (also known as Spot blocks) are designed not to be interrupted and will run continuously for the duration you select.

        You can use a duration of 1, 2, 3, 4, 5, or 6 hours.

        :default: Requested spot instances do not have a pre-defined duration.

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html#fixed-duration-spot-instances
        '''
        result = self._values.get("block_duration")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def interruption_behavior(self) -> typing.Optional["SpotInstanceInterruption"]:
        '''The behavior when a Spot Instance is interrupted.

        :default: Spot instances will terminate when interrupted.
        '''
        result = self._values.get("interruption_behavior")
        return typing.cast(typing.Optional["SpotInstanceInterruption"], result)

    @builtins.property
    def max_price(self) -> typing.Optional[jsii.Number]:
        '''Maximum hourly price you're willing to pay for each Spot instance.

        The value is given
        in dollars. ex: 0.01 for 1 cent per hour, or 0.001 for one-tenth of a cent per hour.

        :default: Maximum hourly price will default to the on-demand price for the instance type.
        '''
        result = self._values.get("max_price")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def request_type(self) -> typing.Optional["SpotRequestType"]:
        '''The Spot Instance request type.

        If you are using Spot Instances with an Auto Scaling group, use one-time requests, as the
        Amazon EC2 Auto Scaling service handles requesting new Spot Instances whenever the group is
        below its desired capacity.

        :default: One-time spot request.
        '''
        result = self._values.get("request_type")
        return typing.cast(typing.Optional["SpotRequestType"], result)

    @builtins.property
    def valid_until(self) -> typing.Optional[aws_cdk.core.Expiration]:
        '''The end date of the request.

        For a one-time request, the request remains active until all instances
        launch, the request is canceled, or this date is reached. If the request is persistent, it remains
        active until it is canceled or this date and time is reached.

        :default: The default end date is 7 days from the current date.
        '''
        result = self._values.get("valid_until")
        return typing.cast(typing.Optional[aws_cdk.core.Expiration], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LaunchTemplateSpotOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.LinuxUserDataOptions",
    jsii_struct_bases=[],
    name_mapping={"shebang": "shebang"},
)
class LinuxUserDataOptions:
    def __init__(self, *, shebang: typing.Optional[builtins.str] = None) -> None:
        '''Options when constructing UserData for Linux.

        :param shebang: Shebang for the UserData script. Default: "#!/bin/bash"
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if shebang is not None:
            self._values["shebang"] = shebang

    @builtins.property
    def shebang(self) -> typing.Optional[builtins.str]:
        '''Shebang for the UserData script.

        :default: "#!/bin/bash"
        '''
        result = self._values.get("shebang")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LinuxUserDataOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.LocationPackageOptions",
    jsii_struct_bases=[],
    name_mapping={"key": "key", "service_restart_handles": "serviceRestartHandles"},
)
class LocationPackageOptions:
    def __init__(
        self,
        *,
        key: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
    ) -> None:
        '''Options for InitPackage.rpm/InitPackage.msi.

        :param key: Identifier key for this package. You can use this to order package installs. Default: - Automatically generated
        :param service_restart_handles: Restart the given service after this command has run. Default: - Do not restart any service
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if key is not None:
            self._values["key"] = key
        if service_restart_handles is not None:
            self._values["service_restart_handles"] = service_restart_handles

    @builtins.property
    def key(self) -> typing.Optional[builtins.str]:
        '''Identifier key for this package.

        You can use this to order package installs.

        :default: - Automatically generated
        '''
        result = self._values.get("key")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def service_restart_handles(
        self,
    ) -> typing.Optional[typing.List[InitServiceRestartHandle]]:
        '''Restart the given service after this command has run.

        :default: - Do not restart any service
        '''
        result = self._values.get("service_restart_handles")
        return typing.cast(typing.Optional[typing.List[InitServiceRestartHandle]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LocationPackageOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IMachineImage)
class LookupMachineImage(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.LookupMachineImage",
):
    '''A machine image whose AMI ID will be searched using DescribeImages.

    The most recent, available, launchable image matching the given filter
    criteria will be used. Looking up AMIs may take a long time; specify
    as many filter criteria as possible to narrow down the search.

    The AMI selected will be cached in ``cdk.context.json`` and the same value
    will be used on future runs. To refresh the AMI lookup, you will have to
    evict the value from the cache using the ``cdk context`` command. See
    https://docs.aws.amazon.com/cdk/latest/guide/context.html for more information.
    '''

    def __init__(
        self,
        *,
        name: builtins.str,
        filters: typing.Optional[typing.Mapping[builtins.str, typing.List[builtins.str]]] = None,
        owners: typing.Optional[typing.List[builtins.str]] = None,
        user_data: typing.Optional["UserData"] = None,
        windows: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''
        :param name: Name of the image (may contain wildcards).
        :param filters: Additional filters on the AMI. Default: - No additional filters
        :param owners: Owner account IDs or aliases. Default: - All owners
        :param user_data: Custom userdata for this image. Default: - Empty user data appropriate for the platform type
        :param windows: Look for Windows images. Default: false
        '''
        props = LookupMachineImageProps(
            name=name,
            filters=filters,
            owners=owners,
            user_data=user_data,
            windows=windows,
        )

        jsii.create(LookupMachineImage, self, [props])

    @jsii.member(jsii_name="getImage")
    def get_image(self, scope: aws_cdk.core.Construct) -> "MachineImageConfig":
        '''Return the image to use in the given context.

        :param scope: -
        '''
        return typing.cast("MachineImageConfig", jsii.invoke(self, "getImage", [scope]))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.LookupMachineImageProps",
    jsii_struct_bases=[],
    name_mapping={
        "name": "name",
        "filters": "filters",
        "owners": "owners",
        "user_data": "userData",
        "windows": "windows",
    },
)
class LookupMachineImageProps:
    def __init__(
        self,
        *,
        name: builtins.str,
        filters: typing.Optional[typing.Mapping[builtins.str, typing.List[builtins.str]]] = None,
        owners: typing.Optional[typing.List[builtins.str]] = None,
        user_data: typing.Optional["UserData"] = None,
        windows: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Properties for looking up an image.

        :param name: Name of the image (may contain wildcards).
        :param filters: Additional filters on the AMI. Default: - No additional filters
        :param owners: Owner account IDs or aliases. Default: - All owners
        :param user_data: Custom userdata for this image. Default: - Empty user data appropriate for the platform type
        :param windows: Look for Windows images. Default: false
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }
        if filters is not None:
            self._values["filters"] = filters
        if owners is not None:
            self._values["owners"] = owners
        if user_data is not None:
            self._values["user_data"] = user_data
        if windows is not None:
            self._values["windows"] = windows

    @builtins.property
    def name(self) -> builtins.str:
        '''Name of the image (may contain wildcards).'''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def filters(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, typing.List[builtins.str]]]:
        '''Additional filters on the AMI.

        :default: - No additional filters

        :see: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeImages.html
        '''
        result = self._values.get("filters")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, typing.List[builtins.str]]], result)

    @builtins.property
    def owners(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Owner account IDs or aliases.

        :default: - All owners
        '''
        result = self._values.get("owners")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def user_data(self) -> typing.Optional["UserData"]:
        '''Custom userdata for this image.

        :default: - Empty user data appropriate for the platform type
        '''
        result = self._values.get("user_data")
        return typing.cast(typing.Optional["UserData"], result)

    @builtins.property
    def windows(self) -> typing.Optional[builtins.bool]:
        '''Look for Windows images.

        :default: false
        '''
        result = self._values.get("windows")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LookupMachineImageProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class MachineImage(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-ec2.MachineImage",
):
    '''Factory functions for standard Amazon Machine Image objects.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_MachineImageProxy"]:
        return _MachineImageProxy

    def __init__(self) -> None:
        jsii.create(MachineImage, self, [])

    @jsii.member(jsii_name="fromSSMParameter") # type: ignore[misc]
    @builtins.classmethod
    def from_ssm_parameter(
        cls,
        parameter_name: builtins.str,
        os: "OperatingSystemType",
        user_data: typing.Optional["UserData"] = None,
    ) -> IMachineImage:
        '''An image specified in SSM parameter store that is automatically kept up-to-date.

        This Machine Image automatically updates to the latest version on every
        deployment. Be aware this will cause your instances to be replaced when a
        new version of the image becomes available. Do not store stateful information
        on the instance if you are using this image.

        :param parameter_name: The name of SSM parameter containing the AMi id.
        :param os: The operating system type of the AMI.
        :param user_data: optional user data for the given image.
        '''
        return typing.cast(IMachineImage, jsii.sinvoke(cls, "fromSSMParameter", [parameter_name, os, user_data]))

    @jsii.member(jsii_name="genericLinux") # type: ignore[misc]
    @builtins.classmethod
    def generic_linux(
        cls,
        ami_map: typing.Mapping[builtins.str, builtins.str],
        *,
        user_data: typing.Optional["UserData"] = None,
    ) -> IMachineImage:
        '''A Linux image where you specify the AMI ID for every region.

        :param ami_map: For every region where you are deploying the stack, specify the AMI ID for that region.
        :param user_data: Initial user data. Default: - Empty UserData for Linux machines
        '''
        props = GenericLinuxImageProps(user_data=user_data)

        return typing.cast(IMachineImage, jsii.sinvoke(cls, "genericLinux", [ami_map, props]))

    @jsii.member(jsii_name="genericWindows") # type: ignore[misc]
    @builtins.classmethod
    def generic_windows(
        cls,
        ami_map: typing.Mapping[builtins.str, builtins.str],
        *,
        user_data: typing.Optional["UserData"] = None,
    ) -> IMachineImage:
        '''A Windows image where you specify the AMI ID for every region.

        :param ami_map: For every region where you are deploying the stack, specify the AMI ID for that region.
        :param user_data: Initial user data. Default: - Empty UserData for Windows machines
        '''
        props = GenericWindowsImageProps(user_data=user_data)

        return typing.cast(IMachineImage, jsii.sinvoke(cls, "genericWindows", [ami_map, props]))

    @jsii.member(jsii_name="latestAmazonLinux") # type: ignore[misc]
    @builtins.classmethod
    def latest_amazon_linux(
        cls,
        *,
        cpu_type: typing.Optional[AmazonLinuxCpuType] = None,
        edition: typing.Optional[AmazonLinuxEdition] = None,
        generation: typing.Optional[AmazonLinuxGeneration] = None,
        storage: typing.Optional[AmazonLinuxStorage] = None,
        user_data: typing.Optional["UserData"] = None,
        virtualization: typing.Optional[AmazonLinuxVirt] = None,
    ) -> IMachineImage:
        '''An Amazon Linux image that is automatically kept up-to-date.

        This Machine Image automatically updates to the latest version on every
        deployment. Be aware this will cause your instances to be replaced when a
        new version of the image becomes available. Do not store stateful information
        on the instance if you are using this image.

        :param cpu_type: CPU Type. Default: X86_64
        :param edition: What edition of Amazon Linux to use. Default: Standard
        :param generation: What generation of Amazon Linux to use. Default: AmazonLinux
        :param storage: What storage backed image to use. Default: GeneralPurpose
        :param user_data: Initial user data. Default: - Empty UserData for Linux machines
        :param virtualization: Virtualization type. Default: HVM
        '''
        props = AmazonLinuxImageProps(
            cpu_type=cpu_type,
            edition=edition,
            generation=generation,
            storage=storage,
            user_data=user_data,
            virtualization=virtualization,
        )

        return typing.cast(IMachineImage, jsii.sinvoke(cls, "latestAmazonLinux", [props]))

    @jsii.member(jsii_name="latestWindows") # type: ignore[misc]
    @builtins.classmethod
    def latest_windows(
        cls,
        version: "WindowsVersion",
        *,
        user_data: typing.Optional["UserData"] = None,
    ) -> IMachineImage:
        '''A Windows image that is automatically kept up-to-date.

        This Machine Image automatically updates to the latest version on every
        deployment. Be aware this will cause your instances to be replaced when a
        new version of the image becomes available. Do not store stateful information
        on the instance if you are using this image.

        :param version: -
        :param user_data: Initial user data. Default: - Empty UserData for Windows machines
        '''
        props = WindowsImageProps(user_data=user_data)

        return typing.cast(IMachineImage, jsii.sinvoke(cls, "latestWindows", [version, props]))

    @jsii.member(jsii_name="lookup") # type: ignore[misc]
    @builtins.classmethod
    def lookup(
        cls,
        *,
        name: builtins.str,
        filters: typing.Optional[typing.Mapping[builtins.str, typing.List[builtins.str]]] = None,
        owners: typing.Optional[typing.List[builtins.str]] = None,
        user_data: typing.Optional["UserData"] = None,
        windows: typing.Optional[builtins.bool] = None,
    ) -> IMachineImage:
        '''Look up a shared Machine Image using DescribeImages.

        The most recent, available, launchable image matching the given filter
        criteria will be used. Looking up AMIs may take a long time; specify
        as many filter criteria as possible to narrow down the search.

        The AMI selected will be cached in ``cdk.context.json`` and the same value
        will be used on future runs. To refresh the AMI lookup, you will have to
        evict the value from the cache using the ``cdk context`` command. See
        https://docs.aws.amazon.com/cdk/latest/guide/context.html for more information.

        :param name: Name of the image (may contain wildcards).
        :param filters: Additional filters on the AMI. Default: - No additional filters
        :param owners: Owner account IDs or aliases. Default: - All owners
        :param user_data: Custom userdata for this image. Default: - Empty user data appropriate for the platform type
        :param windows: Look for Windows images. Default: false
        '''
        props = LookupMachineImageProps(
            name=name,
            filters=filters,
            owners=owners,
            user_data=user_data,
            windows=windows,
        )

        return typing.cast(IMachineImage, jsii.sinvoke(cls, "lookup", [props]))


class _MachineImageProxy(MachineImage):
    pass


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.MachineImageConfig",
    jsii_struct_bases=[],
    name_mapping={"image_id": "imageId", "os_type": "osType", "user_data": "userData"},
)
class MachineImageConfig:
    def __init__(
        self,
        *,
        image_id: builtins.str,
        os_type: "OperatingSystemType",
        user_data: "UserData",
    ) -> None:
        '''Configuration for a machine image.

        :param image_id: The AMI ID of the image to use.
        :param os_type: Operating system type for this image.
        :param user_data: Initial UserData for this image.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "image_id": image_id,
            "os_type": os_type,
            "user_data": user_data,
        }

    @builtins.property
    def image_id(self) -> builtins.str:
        '''The AMI ID of the image to use.'''
        result = self._values.get("image_id")
        assert result is not None, "Required property 'image_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def os_type(self) -> "OperatingSystemType":
        '''Operating system type for this image.'''
        result = self._values.get("os_type")
        assert result is not None, "Required property 'os_type' is missing"
        return typing.cast("OperatingSystemType", result)

    @builtins.property
    def user_data(self) -> "UserData":
        '''Initial UserData for this image.'''
        result = self._values.get("user_data")
        assert result is not None, "Required property 'user_data' is missing"
        return typing.cast("UserData", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "MachineImageConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.NamedPackageOptions",
    jsii_struct_bases=[],
    name_mapping={
        "service_restart_handles": "serviceRestartHandles",
        "version": "version",
    },
)
class NamedPackageOptions:
    def __init__(
        self,
        *,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
        version: typing.Optional[typing.List[builtins.str]] = None,
    ) -> None:
        '''Options for InitPackage.yum/apt/rubyGem/python.

        :param service_restart_handles: Restart the given services after this command has run. Default: - Do not restart any service
        :param version: Specify the versions to install. Default: - Install the latest version
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if service_restart_handles is not None:
            self._values["service_restart_handles"] = service_restart_handles
        if version is not None:
            self._values["version"] = version

    @builtins.property
    def service_restart_handles(
        self,
    ) -> typing.Optional[typing.List[InitServiceRestartHandle]]:
        '''Restart the given services after this command has run.

        :default: - Do not restart any service
        '''
        result = self._values.get("service_restart_handles")
        return typing.cast(typing.Optional[typing.List[InitServiceRestartHandle]], result)

    @builtins.property
    def version(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Specify the versions to install.

        :default: - Install the latest version
        '''
        result = self._values.get("version")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NamedPackageOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class NatInstanceImage(
    LookupMachineImage,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.NatInstanceImage",
):
    '''(experimental) Machine image representing the latest NAT instance image.

    :stability: experimental
    '''

    def __init__(self) -> None:
        '''
        :stability: experimental
        '''
        jsii.create(NatInstanceImage, self, [])


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.NatInstanceProps",
    jsii_struct_bases=[],
    name_mapping={
        "instance_type": "instanceType",
        "allow_all_traffic": "allowAllTraffic",
        "key_name": "keyName",
        "machine_image": "machineImage",
        "security_group": "securityGroup",
    },
)
class NatInstanceProps:
    def __init__(
        self,
        *,
        instance_type: InstanceType,
        allow_all_traffic: typing.Optional[builtins.bool] = None,
        key_name: typing.Optional[builtins.str] = None,
        machine_image: typing.Optional[IMachineImage] = None,
        security_group: typing.Optional[ISecurityGroup] = None,
    ) -> None:
        '''(experimental) Properties for a NAT instance.

        :param instance_type: (experimental) Instance type of the NAT instance.
        :param allow_all_traffic: (experimental) Allow all traffic through the NAT instance. If you set this to false, you must configure the NAT instance's security groups in another way, either by passing in a fully configured Security Group using the ``securityGroup`` property, or by configuring it using the ``.securityGroup`` or ``.connections`` members after passing the NAT Instance Provider to a Vpc. Default: true
        :param key_name: (experimental) Name of SSH keypair to grant access to instance. Default: - No SSH access will be possible.
        :param machine_image: (experimental) The machine image (AMI) to use. By default, will do an AMI lookup for the latest NAT instance image. If you have a specific AMI ID you want to use, pass a ``GenericLinuxImage``. For example:: ec2.NatProvider.instance({ instanceType: new ec2.InstanceType('t3.micro'), machineImage: new ec2.GenericLinuxImage({ 'us-east-2': 'ami-0f9c61b5a562a16af' }) }) Default: - Latest NAT instance image
        :param security_group: (experimental) Security Group for NAT instances. Default: - A new security group will be created

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "instance_type": instance_type,
        }
        if allow_all_traffic is not None:
            self._values["allow_all_traffic"] = allow_all_traffic
        if key_name is not None:
            self._values["key_name"] = key_name
        if machine_image is not None:
            self._values["machine_image"] = machine_image
        if security_group is not None:
            self._values["security_group"] = security_group

    @builtins.property
    def instance_type(self) -> InstanceType:
        '''(experimental) Instance type of the NAT instance.

        :stability: experimental
        '''
        result = self._values.get("instance_type")
        assert result is not None, "Required property 'instance_type' is missing"
        return typing.cast(InstanceType, result)

    @builtins.property
    def allow_all_traffic(self) -> typing.Optional[builtins.bool]:
        '''(experimental) Allow all traffic through the NAT instance.

        If you set this to false, you must configure the NAT instance's security
        groups in another way, either by passing in a fully configured Security
        Group using the ``securityGroup`` property, or by configuring it using the
        ``.securityGroup`` or ``.connections`` members after passing the NAT Instance
        Provider to a Vpc.

        :default: true

        :stability: experimental
        '''
        result = self._values.get("allow_all_traffic")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def key_name(self) -> typing.Optional[builtins.str]:
        '''(experimental) Name of SSH keypair to grant access to instance.

        :default: - No SSH access will be possible.

        :stability: experimental
        '''
        result = self._values.get("key_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def machine_image(self) -> typing.Optional[IMachineImage]:
        '''(experimental) The machine image (AMI) to use.

        By default, will do an AMI lookup for the latest NAT instance image.

        If you have a specific AMI ID you want to use, pass a ``GenericLinuxImage``. For example::

           # Example automatically generated. See https://github.com/aws/jsii/issues/826
           ec2.NatProvider.instance(
               instance_type=ec2.InstanceType("t3.micro"),
               machine_image=ec2.GenericLinuxImage(
                   us-east-2="ami-0f9c61b5a562a16af"
               )
           )

        :default: - Latest NAT instance image

        :stability: experimental
        '''
        result = self._values.get("machine_image")
        return typing.cast(typing.Optional[IMachineImage], result)

    @builtins.property
    def security_group(self) -> typing.Optional[ISecurityGroup]:
        '''(experimental) Security Group for NAT instances.

        :default: - A new security group will be created

        :stability: experimental
        '''
        result = self._values.get("security_group")
        return typing.cast(typing.Optional[ISecurityGroup], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NatInstanceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class NatProvider(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-ec2.NatProvider",
):
    '''(experimental) NAT providers.

    Determines what type of NAT provider to create, either NAT gateways or NAT
    instance.

    :stability: experimental
    '''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_NatProviderProxy"]:
        return _NatProviderProxy

    def __init__(self) -> None:
        jsii.create(NatProvider, self, [])

    @jsii.member(jsii_name="gateway") # type: ignore[misc]
    @builtins.classmethod
    def gateway(cls) -> "NatProvider":
        '''(experimental) Use NAT Gateways to provide NAT services for your VPC.

        NAT gateways are managed by AWS.

        :see: https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html
        :stability: experimental
        '''
        return typing.cast("NatProvider", jsii.sinvoke(cls, "gateway", []))

    @jsii.member(jsii_name="instance") # type: ignore[misc]
    @builtins.classmethod
    def instance(
        cls,
        *,
        instance_type: InstanceType,
        allow_all_traffic: typing.Optional[builtins.bool] = None,
        key_name: typing.Optional[builtins.str] = None,
        machine_image: typing.Optional[IMachineImage] = None,
        security_group: typing.Optional[ISecurityGroup] = None,
    ) -> "NatInstanceProvider":
        '''(experimental) Use NAT instances to provide NAT services for your VPC.

        NAT instances are managed by you, but in return allow more configuration.

        Be aware that instances created using this provider will not be
        automatically replaced if they are stopped for any reason. You should implement
        your own NatProvider based on AutoScaling groups if you need that.

        :param instance_type: (experimental) Instance type of the NAT instance.
        :param allow_all_traffic: (experimental) Allow all traffic through the NAT instance. If you set this to false, you must configure the NAT instance's security groups in another way, either by passing in a fully configured Security Group using the ``securityGroup`` property, or by configuring it using the ``.securityGroup`` or ``.connections`` members after passing the NAT Instance Provider to a Vpc. Default: true
        :param key_name: (experimental) Name of SSH keypair to grant access to instance. Default: - No SSH access will be possible.
        :param machine_image: (experimental) The machine image (AMI) to use. By default, will do an AMI lookup for the latest NAT instance image. If you have a specific AMI ID you want to use, pass a ``GenericLinuxImage``. For example:: ec2.NatProvider.instance({ instanceType: new ec2.InstanceType('t3.micro'), machineImage: new ec2.GenericLinuxImage({ 'us-east-2': 'ami-0f9c61b5a562a16af' }) }) Default: - Latest NAT instance image
        :param security_group: (experimental) Security Group for NAT instances. Default: - A new security group will be created

        :see: https://docs.aws.amazon.com/vpc/latest/userguide/VPC_NAT_Instance.html
        :stability: experimental
        '''
        props = NatInstanceProps(
            instance_type=instance_type,
            allow_all_traffic=allow_all_traffic,
            key_name=key_name,
            machine_image=machine_image,
            security_group=security_group,
        )

        return typing.cast("NatInstanceProvider", jsii.sinvoke(cls, "instance", [props]))

    @jsii.member(jsii_name="configureNat") # type: ignore[misc]
    @abc.abstractmethod
    def configure_nat(
        self,
        *,
        nat_subnets: typing.List["PublicSubnet"],
        private_subnets: typing.List["PrivateSubnet"],
        vpc: "Vpc",
    ) -> None:
        '''(experimental) Called by the VPC to configure NAT.

        Don't call this directly, the VPC will call it automatically.

        :param nat_subnets: (experimental) The public subnets where the NAT providers need to be placed.
        :param private_subnets: (experimental) The private subnets that need to route through the NAT providers. There may be more private subnets than public subnets with NAT providers.
        :param vpc: (experimental) The VPC we're configuring NAT for.

        :stability: experimental
        '''
        ...

    @jsii.member(jsii_name="configureSubnet") # type: ignore[misc]
    @abc.abstractmethod
    def configure_subnet(self, subnet: "PrivateSubnet") -> None:
        '''(experimental) Configures subnet with the gateway.

        Don't call this directly, the VPC will call it automatically.

        :param subnet: -

        :stability: experimental
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="configuredGateways")
    @abc.abstractmethod
    def configured_gateways(self) -> typing.List[GatewayConfig]:
        '''(experimental) Return list of gateways spawned by the provider.

        :stability: experimental
        '''
        ...


class _NatProviderProxy(NatProvider):
    @jsii.member(jsii_name="configureNat")
    def configure_nat(
        self,
        *,
        nat_subnets: typing.List["PublicSubnet"],
        private_subnets: typing.List["PrivateSubnet"],
        vpc: "Vpc",
    ) -> None:
        '''(experimental) Called by the VPC to configure NAT.

        Don't call this directly, the VPC will call it automatically.

        :param nat_subnets: (experimental) The public subnets where the NAT providers need to be placed.
        :param private_subnets: (experimental) The private subnets that need to route through the NAT providers. There may be more private subnets than public subnets with NAT providers.
        :param vpc: (experimental) The VPC we're configuring NAT for.

        :stability: experimental
        '''
        options = ConfigureNatOptions(
            nat_subnets=nat_subnets, private_subnets=private_subnets, vpc=vpc
        )

        return typing.cast(None, jsii.invoke(self, "configureNat", [options]))

    @jsii.member(jsii_name="configureSubnet")
    def configure_subnet(self, subnet: "PrivateSubnet") -> None:
        '''(experimental) Configures subnet with the gateway.

        Don't call this directly, the VPC will call it automatically.

        :param subnet: -

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "configureSubnet", [subnet]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="configuredGateways")
    def configured_gateways(self) -> typing.List[GatewayConfig]:
        '''(experimental) Return list of gateways spawned by the provider.

        :stability: experimental
        '''
        return typing.cast(typing.List[GatewayConfig], jsii.get(self, "configuredGateways"))


@jsii.implements(INetworkAcl)
class NetworkAcl(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.NetworkAcl",
):
    '''(experimental) Define a new custom network ACL.

    By default, will deny all inbound and outbound traffic unless entries are
    added explicitly allowing it.

    :stability: experimental
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        vpc: IVpc,
        network_acl_name: typing.Optional[builtins.str] = None,
        subnet_selection: typing.Optional["SubnetSelection"] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param vpc: (experimental) The VPC in which to create the NetworkACL.
        :param network_acl_name: (experimental) The name of the NetworkAcl. It is not recommended to use an explicit name. Default: If you don't specify a networkAclName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        :param subnet_selection: (experimental) Subnets in the given VPC to associate the ACL with. More subnets can always be added later by calling ``associateWithSubnets()``. Default: - No subnets associated

        :stability: experimental
        '''
        props = NetworkAclProps(
            vpc=vpc,
            network_acl_name=network_acl_name,
            subnet_selection=subnet_selection,
        )

        jsii.create(NetworkAcl, self, [scope, id, props])

    @jsii.member(jsii_name="fromNetworkAclId") # type: ignore[misc]
    @builtins.classmethod
    def from_network_acl_id(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        network_acl_id: builtins.str,
    ) -> INetworkAcl:
        '''(experimental) Import an existing NetworkAcl into this app.

        :param scope: -
        :param id: -
        :param network_acl_id: -

        :stability: experimental
        '''
        return typing.cast(INetworkAcl, jsii.sinvoke(cls, "fromNetworkAclId", [scope, id, network_acl_id]))

    @jsii.member(jsii_name="addEntry")
    def add_entry(
        self,
        id: builtins.str,
        *,
        cidr: AclCidr,
        rule_number: jsii.Number,
        traffic: AclTraffic,
        direction: typing.Optional["TrafficDirection"] = None,
        network_acl_entry_name: typing.Optional[builtins.str] = None,
        rule_action: typing.Optional[Action] = None,
    ) -> "NetworkAclEntry":
        '''(experimental) Add a new entry to the ACL.

        :param id: -
        :param cidr: (experimental) The CIDR range to allow or deny.
        :param rule_number: (experimental) Rule number to assign to the entry, such as 100. ACL entries are processed in ascending order by rule number. Entries can't use the same rule number unless one is an egress rule and the other is an ingress rule.
        :param traffic: (experimental) What kind of traffic this ACL rule applies to.
        :param direction: (experimental) Traffic direction, with respect to the subnet, this rule applies to. Default: TrafficDirection.INGRESS
        :param network_acl_entry_name: (experimental) The name of the NetworkAclEntry. It is not recommended to use an explicit group name. Default: If you don't specify a NetworkAclName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        :param rule_action: (experimental) Whether to allow or deny traffic that matches the rule; valid values are "allow" or "deny". Any traffic that is not explicitly allowed is automatically denied in a custom ACL, all traffic is automatically allowed in a default ACL. Default: ALLOW

        :stability: experimental
        '''
        options = CommonNetworkAclEntryOptions(
            cidr=cidr,
            rule_number=rule_number,
            traffic=traffic,
            direction=direction,
            network_acl_entry_name=network_acl_entry_name,
            rule_action=rule_action,
        )

        return typing.cast("NetworkAclEntry", jsii.invoke(self, "addEntry", [id, options]))

    @jsii.member(jsii_name="associateWithSubnet")
    def associate_with_subnet(
        self,
        id: builtins.str,
        *,
        availability_zones: typing.Optional[typing.List[builtins.str]] = None,
        one_per_az: typing.Optional[builtins.bool] = None,
        subnet_filters: typing.Optional[typing.List["SubnetFilter"]] = None,
        subnet_group_name: typing.Optional[builtins.str] = None,
        subnet_name: typing.Optional[builtins.str] = None,
        subnets: typing.Optional[typing.List[ISubnet]] = None,
        subnet_type: typing.Optional["SubnetType"] = None,
    ) -> None:
        '''(experimental) Associate the ACL with a given set of subnets.

        :param id: -
        :param availability_zones: Select subnets only in the given AZs. Default: no filtering on AZs is done
        :param one_per_az: If true, return at most one subnet per AZ. Default: false
        :param subnet_filters: List of provided subnet filters. Default: - none
        :param subnet_group_name: Select the subnet group with the given name. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them. Otherwise, prefer ``subnetType``. This field does not select individual subnets, it selects all subnets that share the given subnet group name. This is the name supplied in ``subnetConfiguration``. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: - Selection by type instead of by name
        :param subnet_name: (deprecated) Alias for ``subnetGroupName``. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them.
        :param subnets: Explicitly select individual subnets. Use this if you don't want to automatically use all subnets in a group, but have a need to control selection down to individual subnets. Cannot be specified together with ``subnetType`` or ``subnetGroupName``. Default: - Use all subnets in a selected group (all private subnets by default)
        :param subnet_type: Select all subnets of the given type. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: SubnetType.PRIVATE (or ISOLATED or PUBLIC if there are no PRIVATE subnets)

        :stability: experimental
        '''
        selection = SubnetSelection(
            availability_zones=availability_zones,
            one_per_az=one_per_az,
            subnet_filters=subnet_filters,
            subnet_group_name=subnet_group_name,
            subnet_name=subnet_name,
            subnets=subnets,
            subnet_type=subnet_type,
        )

        return typing.cast(None, jsii.invoke(self, "associateWithSubnet", [id, selection]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkAclId")
    def network_acl_id(self) -> builtins.str:
        '''(experimental) The ID of the NetworkACL.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "networkAclId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkAclVpcId")
    def network_acl_vpc_id(self) -> builtins.str:
        '''(experimental) The VPC ID for this NetworkACL.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "networkAclVpcId"))


@jsii.implements(INetworkAclEntry)
class NetworkAclEntry(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.NetworkAclEntry",
):
    '''(experimental) Define an entry in a Network ACL table.

    :stability: experimental
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        network_acl: INetworkAcl,
        cidr: AclCidr,
        rule_number: jsii.Number,
        traffic: AclTraffic,
        direction: typing.Optional["TrafficDirection"] = None,
        network_acl_entry_name: typing.Optional[builtins.str] = None,
        rule_action: typing.Optional[Action] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param network_acl: (experimental) The network ACL this entry applies to.
        :param cidr: (experimental) The CIDR range to allow or deny.
        :param rule_number: (experimental) Rule number to assign to the entry, such as 100. ACL entries are processed in ascending order by rule number. Entries can't use the same rule number unless one is an egress rule and the other is an ingress rule.
        :param traffic: (experimental) What kind of traffic this ACL rule applies to.
        :param direction: (experimental) Traffic direction, with respect to the subnet, this rule applies to. Default: TrafficDirection.INGRESS
        :param network_acl_entry_name: (experimental) The name of the NetworkAclEntry. It is not recommended to use an explicit group name. Default: If you don't specify a NetworkAclName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        :param rule_action: (experimental) Whether to allow or deny traffic that matches the rule; valid values are "allow" or "deny". Any traffic that is not explicitly allowed is automatically denied in a custom ACL, all traffic is automatically allowed in a default ACL. Default: ALLOW

        :stability: experimental
        '''
        props = NetworkAclEntryProps(
            network_acl=network_acl,
            cidr=cidr,
            rule_number=rule_number,
            traffic=traffic,
            direction=direction,
            network_acl_entry_name=network_acl_entry_name,
            rule_action=rule_action,
        )

        jsii.create(NetworkAclEntry, self, [scope, id, props])

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkAcl")
    def network_acl(self) -> INetworkAcl:
        '''(experimental) The network ACL.

        :stability: experimental
        '''
        return typing.cast(INetworkAcl, jsii.get(self, "networkAcl"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.NetworkAclEntryProps",
    jsii_struct_bases=[CommonNetworkAclEntryOptions],
    name_mapping={
        "cidr": "cidr",
        "rule_number": "ruleNumber",
        "traffic": "traffic",
        "direction": "direction",
        "network_acl_entry_name": "networkAclEntryName",
        "rule_action": "ruleAction",
        "network_acl": "networkAcl",
    },
)
class NetworkAclEntryProps(CommonNetworkAclEntryOptions):
    def __init__(
        self,
        *,
        cidr: AclCidr,
        rule_number: jsii.Number,
        traffic: AclTraffic,
        direction: typing.Optional["TrafficDirection"] = None,
        network_acl_entry_name: typing.Optional[builtins.str] = None,
        rule_action: typing.Optional[Action] = None,
        network_acl: INetworkAcl,
    ) -> None:
        '''(experimental) Properties to create NetworkAclEntry.

        :param cidr: (experimental) The CIDR range to allow or deny.
        :param rule_number: (experimental) Rule number to assign to the entry, such as 100. ACL entries are processed in ascending order by rule number. Entries can't use the same rule number unless one is an egress rule and the other is an ingress rule.
        :param traffic: (experimental) What kind of traffic this ACL rule applies to.
        :param direction: (experimental) Traffic direction, with respect to the subnet, this rule applies to. Default: TrafficDirection.INGRESS
        :param network_acl_entry_name: (experimental) The name of the NetworkAclEntry. It is not recommended to use an explicit group name. Default: If you don't specify a NetworkAclName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        :param rule_action: (experimental) Whether to allow or deny traffic that matches the rule; valid values are "allow" or "deny". Any traffic that is not explicitly allowed is automatically denied in a custom ACL, all traffic is automatically allowed in a default ACL. Default: ALLOW
        :param network_acl: (experimental) The network ACL this entry applies to.

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cidr": cidr,
            "rule_number": rule_number,
            "traffic": traffic,
            "network_acl": network_acl,
        }
        if direction is not None:
            self._values["direction"] = direction
        if network_acl_entry_name is not None:
            self._values["network_acl_entry_name"] = network_acl_entry_name
        if rule_action is not None:
            self._values["rule_action"] = rule_action

    @builtins.property
    def cidr(self) -> AclCidr:
        '''(experimental) The CIDR range to allow or deny.

        :stability: experimental
        '''
        result = self._values.get("cidr")
        assert result is not None, "Required property 'cidr' is missing"
        return typing.cast(AclCidr, result)

    @builtins.property
    def rule_number(self) -> jsii.Number:
        '''(experimental) Rule number to assign to the entry, such as 100.

        ACL entries are processed in ascending order by rule number.
        Entries can't use the same rule number unless one is an egress rule and the other is an ingress rule.

        :stability: experimental
        '''
        result = self._values.get("rule_number")
        assert result is not None, "Required property 'rule_number' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def traffic(self) -> AclTraffic:
        '''(experimental) What kind of traffic this ACL rule applies to.

        :stability: experimental
        '''
        result = self._values.get("traffic")
        assert result is not None, "Required property 'traffic' is missing"
        return typing.cast(AclTraffic, result)

    @builtins.property
    def direction(self) -> typing.Optional["TrafficDirection"]:
        '''(experimental) Traffic direction, with respect to the subnet, this rule applies to.

        :default: TrafficDirection.INGRESS

        :stability: experimental
        '''
        result = self._values.get("direction")
        return typing.cast(typing.Optional["TrafficDirection"], result)

    @builtins.property
    def network_acl_entry_name(self) -> typing.Optional[builtins.str]:
        '''(experimental) The name of the NetworkAclEntry.

        It is not recommended to use an explicit group name.

        :default:

        If you don't specify a NetworkAclName, AWS CloudFormation generates a
        unique physical ID and uses that ID for the group name.

        :stability: experimental
        '''
        result = self._values.get("network_acl_entry_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def rule_action(self) -> typing.Optional[Action]:
        '''(experimental) Whether to allow or deny traffic that matches the rule; valid values are "allow" or "deny".

        Any traffic that is not explicitly allowed is automatically denied in a custom
        ACL, all traffic is automatically allowed in a default ACL.

        :default: ALLOW

        :stability: experimental
        '''
        result = self._values.get("rule_action")
        return typing.cast(typing.Optional[Action], result)

    @builtins.property
    def network_acl(self) -> INetworkAcl:
        '''(experimental) The network ACL this entry applies to.

        :stability: experimental
        '''
        result = self._values.get("network_acl")
        assert result is not None, "Required property 'network_acl' is missing"
        return typing.cast(INetworkAcl, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NetworkAclEntryProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.NetworkAclProps",
    jsii_struct_bases=[],
    name_mapping={
        "vpc": "vpc",
        "network_acl_name": "networkAclName",
        "subnet_selection": "subnetSelection",
    },
)
class NetworkAclProps:
    def __init__(
        self,
        *,
        vpc: IVpc,
        network_acl_name: typing.Optional[builtins.str] = None,
        subnet_selection: typing.Optional["SubnetSelection"] = None,
    ) -> None:
        '''(experimental) Properties to create NetworkAcl.

        :param vpc: (experimental) The VPC in which to create the NetworkACL.
        :param network_acl_name: (experimental) The name of the NetworkAcl. It is not recommended to use an explicit name. Default: If you don't specify a networkAclName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        :param subnet_selection: (experimental) Subnets in the given VPC to associate the ACL with. More subnets can always be added later by calling ``associateWithSubnets()``. Default: - No subnets associated

        :stability: experimental
        '''
        if isinstance(subnet_selection, dict):
            subnet_selection = SubnetSelection(**subnet_selection)
        self._values: typing.Dict[str, typing.Any] = {
            "vpc": vpc,
        }
        if network_acl_name is not None:
            self._values["network_acl_name"] = network_acl_name
        if subnet_selection is not None:
            self._values["subnet_selection"] = subnet_selection

    @builtins.property
    def vpc(self) -> IVpc:
        '''(experimental) The VPC in which to create the NetworkACL.

        :stability: experimental
        '''
        result = self._values.get("vpc")
        assert result is not None, "Required property 'vpc' is missing"
        return typing.cast(IVpc, result)

    @builtins.property
    def network_acl_name(self) -> typing.Optional[builtins.str]:
        '''(experimental) The name of the NetworkAcl.

        It is not recommended to use an explicit name.

        :default:

        If you don't specify a networkAclName, AWS CloudFormation generates a
        unique physical ID and uses that ID for the group name.

        :stability: experimental
        '''
        result = self._values.get("network_acl_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def subnet_selection(self) -> typing.Optional["SubnetSelection"]:
        '''(experimental) Subnets in the given VPC to associate the ACL with.

        More subnets can always be added later by calling
        ``associateWithSubnets()``.

        :default: - No subnets associated

        :stability: experimental
        '''
        result = self._values.get("subnet_selection")
        return typing.cast(typing.Optional["SubnetSelection"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "NetworkAclProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.OperatingSystemType")
class OperatingSystemType(enum.Enum):
    '''The OS type of a particular image.'''

    LINUX = "LINUX"
    WINDOWS = "WINDOWS"
    UNKNOWN = "UNKNOWN"
    '''Used when the type of the operating system is not known (for example, for imported Auto-Scaling Groups).'''


class Peer(metaclass=jsii.JSIIMeta, jsii_type="@aws-cdk/aws-ec2.Peer"):
    '''Peer object factories (to be used in Security Group management).

    The static methods on this object can be used to create peer objects
    which represent a connection partner in Security Group rules.

    Use this object if you need to represent connection partners using plain IP
    addresses, or a prefix list ID.

    If you want to address a connection partner by Security Group, you can just
    use the Security Group (or the construct that contains a Security Group)
    directly, as it already implements ``IPeer``.
    '''

    def __init__(self) -> None:
        jsii.create(Peer, self, [])

    @jsii.member(jsii_name="anyIpv4") # type: ignore[misc]
    @builtins.classmethod
    def any_ipv4(cls) -> IPeer:
        '''Any IPv4 address.'''
        return typing.cast(IPeer, jsii.sinvoke(cls, "anyIpv4", []))

    @jsii.member(jsii_name="anyIpv6") # type: ignore[misc]
    @builtins.classmethod
    def any_ipv6(cls) -> IPeer:
        '''Any IPv6 address.'''
        return typing.cast(IPeer, jsii.sinvoke(cls, "anyIpv6", []))

    @jsii.member(jsii_name="ipv4") # type: ignore[misc]
    @builtins.classmethod
    def ipv4(cls, cidr_ip: builtins.str) -> IPeer:
        '''Create an IPv4 peer from a CIDR.

        :param cidr_ip: -
        '''
        return typing.cast(IPeer, jsii.sinvoke(cls, "ipv4", [cidr_ip]))

    @jsii.member(jsii_name="ipv6") # type: ignore[misc]
    @builtins.classmethod
    def ipv6(cls, cidr_ip: builtins.str) -> IPeer:
        '''Create an IPv6 peer from a CIDR.

        :param cidr_ip: -
        '''
        return typing.cast(IPeer, jsii.sinvoke(cls, "ipv6", [cidr_ip]))

    @jsii.member(jsii_name="prefixList") # type: ignore[misc]
    @builtins.classmethod
    def prefix_list(cls, prefix_list_id: builtins.str) -> IPeer:
        '''A prefix list.

        :param prefix_list_id: -
        '''
        return typing.cast(IPeer, jsii.sinvoke(cls, "prefixList", [prefix_list_id]))


class Port(metaclass=jsii.JSIIMeta, jsii_type="@aws-cdk/aws-ec2.Port"):
    '''Interface for classes that provide the connection-specification parts of a security group rule.'''

    def __init__(
        self,
        *,
        protocol: "Protocol",
        string_representation: builtins.str,
        from_port: typing.Optional[jsii.Number] = None,
        to_port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''
        :param protocol: The protocol for the range.
        :param string_representation: String representation for this object.
        :param from_port: The starting port for the range. Default: - Not included in the rule
        :param to_port: The ending port for the range. Default: - Not included in the rule
        '''
        props = PortProps(
            protocol=protocol,
            string_representation=string_representation,
            from_port=from_port,
            to_port=to_port,
        )

        jsii.create(Port, self, [props])

    @jsii.member(jsii_name="allIcmp") # type: ignore[misc]
    @builtins.classmethod
    def all_icmp(cls) -> "Port":
        '''All ICMP traffic.'''
        return typing.cast("Port", jsii.sinvoke(cls, "allIcmp", []))

    @jsii.member(jsii_name="allTcp") # type: ignore[misc]
    @builtins.classmethod
    def all_tcp(cls) -> "Port":
        '''Any TCP traffic.'''
        return typing.cast("Port", jsii.sinvoke(cls, "allTcp", []))

    @jsii.member(jsii_name="allTraffic") # type: ignore[misc]
    @builtins.classmethod
    def all_traffic(cls) -> "Port":
        '''All traffic.'''
        return typing.cast("Port", jsii.sinvoke(cls, "allTraffic", []))

    @jsii.member(jsii_name="allUdp") # type: ignore[misc]
    @builtins.classmethod
    def all_udp(cls) -> "Port":
        '''Any UDP traffic.'''
        return typing.cast("Port", jsii.sinvoke(cls, "allUdp", []))

    @jsii.member(jsii_name="icmpPing") # type: ignore[misc]
    @builtins.classmethod
    def icmp_ping(cls) -> "Port":
        '''ICMP ping (echo) traffic.'''
        return typing.cast("Port", jsii.sinvoke(cls, "icmpPing", []))

    @jsii.member(jsii_name="icmpType") # type: ignore[misc]
    @builtins.classmethod
    def icmp_type(cls, type: jsii.Number) -> "Port":
        '''All codes for a single ICMP type.

        :param type: -
        '''
        return typing.cast("Port", jsii.sinvoke(cls, "icmpType", [type]))

    @jsii.member(jsii_name="icmpTypeAndCode") # type: ignore[misc]
    @builtins.classmethod
    def icmp_type_and_code(cls, type: jsii.Number, code: jsii.Number) -> "Port":
        '''A specific combination of ICMP type and code.

        :param type: -
        :param code: -

        :see: https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
        '''
        return typing.cast("Port", jsii.sinvoke(cls, "icmpTypeAndCode", [type, code]))

    @jsii.member(jsii_name="tcp") # type: ignore[misc]
    @builtins.classmethod
    def tcp(cls, port: jsii.Number) -> "Port":
        '''A single TCP port.

        :param port: -
        '''
        return typing.cast("Port", jsii.sinvoke(cls, "tcp", [port]))

    @jsii.member(jsii_name="tcpRange") # type: ignore[misc]
    @builtins.classmethod
    def tcp_range(cls, start_port: jsii.Number, end_port: jsii.Number) -> "Port":
        '''A TCP port range.

        :param start_port: -
        :param end_port: -
        '''
        return typing.cast("Port", jsii.sinvoke(cls, "tcpRange", [start_port, end_port]))

    @jsii.member(jsii_name="udp") # type: ignore[misc]
    @builtins.classmethod
    def udp(cls, port: jsii.Number) -> "Port":
        '''A single UDP port.

        :param port: -
        '''
        return typing.cast("Port", jsii.sinvoke(cls, "udp", [port]))

    @jsii.member(jsii_name="udpRange") # type: ignore[misc]
    @builtins.classmethod
    def udp_range(cls, start_port: jsii.Number, end_port: jsii.Number) -> "Port":
        '''A UDP port range.

        :param start_port: -
        :param end_port: -
        '''
        return typing.cast("Port", jsii.sinvoke(cls, "udpRange", [start_port, end_port]))

    @jsii.member(jsii_name="toRuleJson")
    def to_rule_json(self) -> typing.Any:
        '''Produce the ingress/egress rule JSON for the given connection.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toRuleJson", []))

    @jsii.member(jsii_name="toString")
    def to_string(self) -> builtins.str:
        return typing.cast(builtins.str, jsii.invoke(self, "toString", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="canInlineRule")
    def can_inline_rule(self) -> builtins.bool:
        '''Whether the rule containing this port range can be inlined into a securitygroup or not.'''
        return typing.cast(builtins.bool, jsii.get(self, "canInlineRule"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.PortProps",
    jsii_struct_bases=[],
    name_mapping={
        "protocol": "protocol",
        "string_representation": "stringRepresentation",
        "from_port": "fromPort",
        "to_port": "toPort",
    },
)
class PortProps:
    def __init__(
        self,
        *,
        protocol: "Protocol",
        string_representation: builtins.str,
        from_port: typing.Optional[jsii.Number] = None,
        to_port: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Properties to create a port range.

        :param protocol: The protocol for the range.
        :param string_representation: String representation for this object.
        :param from_port: The starting port for the range. Default: - Not included in the rule
        :param to_port: The ending port for the range. Default: - Not included in the rule
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "protocol": protocol,
            "string_representation": string_representation,
        }
        if from_port is not None:
            self._values["from_port"] = from_port
        if to_port is not None:
            self._values["to_port"] = to_port

    @builtins.property
    def protocol(self) -> "Protocol":
        '''The protocol for the range.'''
        result = self._values.get("protocol")
        assert result is not None, "Required property 'protocol' is missing"
        return typing.cast("Protocol", result)

    @builtins.property
    def string_representation(self) -> builtins.str:
        '''String representation for this object.'''
        result = self._values.get("string_representation")
        assert result is not None, "Required property 'string_representation' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def from_port(self) -> typing.Optional[jsii.Number]:
        '''The starting port for the range.

        :default: - Not included in the rule
        '''
        result = self._values.get("from_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def to_port(self) -> typing.Optional[jsii.Number]:
        '''The ending port for the range.

        :default: - Not included in the rule
        '''
        result = self._values.get("to_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PortProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.Protocol")
class Protocol(enum.Enum):
    '''Protocol for use in Connection Rules.'''

    ALL = "ALL"
    TCP = "TCP"
    UDP = "UDP"
    ICMP = "ICMP"
    ICMPV6 = "ICMPV6"


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.RouterType")
class RouterType(enum.Enum):
    '''Type of router used in route.'''

    EGRESS_ONLY_INTERNET_GATEWAY = "EGRESS_ONLY_INTERNET_GATEWAY"
    '''Egress-only Internet Gateway.'''
    GATEWAY = "GATEWAY"
    '''Internet Gateway.'''
    INSTANCE = "INSTANCE"
    '''Instance.'''
    NAT_GATEWAY = "NAT_GATEWAY"
    '''NAT Gateway.'''
    NETWORK_INTERFACE = "NETWORK_INTERFACE"
    '''Network Interface.'''
    VPC_PEERING_CONNECTION = "VPC_PEERING_CONNECTION"
    '''VPC peering connection.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.S3DownloadOptions",
    jsii_struct_bases=[],
    name_mapping={
        "bucket": "bucket",
        "bucket_key": "bucketKey",
        "local_file": "localFile",
    },
)
class S3DownloadOptions:
    def __init__(
        self,
        *,
        bucket: aws_cdk.aws_s3.IBucket,
        bucket_key: builtins.str,
        local_file: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Options when downloading files from S3.

        :param bucket: Name of the S3 bucket to download from.
        :param bucket_key: The key of the file to download.
        :param local_file: The name of the local file. Default: Linux - /tmp/bucketKey Windows - %TEMP%/bucketKey
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "bucket": bucket,
            "bucket_key": bucket_key,
        }
        if local_file is not None:
            self._values["local_file"] = local_file

    @builtins.property
    def bucket(self) -> aws_cdk.aws_s3.IBucket:
        '''Name of the S3 bucket to download from.'''
        result = self._values.get("bucket")
        assert result is not None, "Required property 'bucket' is missing"
        return typing.cast(aws_cdk.aws_s3.IBucket, result)

    @builtins.property
    def bucket_key(self) -> builtins.str:
        '''The key of the file to download.'''
        result = self._values.get("bucket_key")
        assert result is not None, "Required property 'bucket_key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def local_file(self) -> typing.Optional[builtins.str]:
        '''The name of the local file.

        :default:

        Linux   - /tmp/bucketKey
        Windows - %TEMP%/bucketKey
        '''
        result = self._values.get("local_file")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "S3DownloadOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(ISecurityGroup)
class SecurityGroup(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.SecurityGroup",
):
    '''Creates an Amazon EC2 security group within a VPC.

    Security Groups act like a firewall with a set of rules, and are associated
    with any AWS resource that has or creates Elastic Network Interfaces (ENIs).
    A typical example of a resource that has a security group is an Instance (or
    Auto Scaling Group of instances)

    If you are defining new infrastructure in CDK, there is a good chance you
    won't have to interact with this class at all. Like IAM Roles, Security
    Groups need to exist to control access between AWS resources, but CDK will
    automatically generate and populate them with least-privilege permissions
    for you so you can concentrate on your business logic.

    All Constructs that require Security Groups will create one for you if you
    don't specify one at construction. After construction, you can selectively
    allow connections to and between constructs via--for example-- the ``instance.connections``
    object. Think of it as "allowing connections to your instance", rather than
    "adding ingress rules a security group". See the `Allowing
    Connections <https://docs.aws.amazon.com/cdk/api/latest/docs/aws-ec2-readme.html#allowing-connections>`_
    section in the library documentation for examples.

    Direct manipulation of the Security Group through ``addIngressRule`` and
    ``addEgressRule`` is possible, but mutation through the ``.connections`` object
    is recommended. If you peer two constructs with security groups this way,
    appropriate rules will be created in both.

    If you have an existing security group you want to use in your CDK application,
    you would import it like this::

       # Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
       security_group = SecurityGroup.from_security_group_id(self, "SG", "sg-12345",
           mutable=False
       )
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        vpc: IVpc,
        allow_all_outbound: typing.Optional[builtins.bool] = None,
        description: typing.Optional[builtins.str] = None,
        security_group_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param vpc: The VPC in which to create the security group.
        :param allow_all_outbound: Whether to allow all outbound traffic by default. If this is set to true, there will only be a single egress rule which allows all outbound traffic. If this is set to false, no outbound traffic will be allowed by default and all egress traffic must be explicitly authorized. Default: true
        :param description: A description of the security group. Default: The default name will be the construct's CDK path.
        :param security_group_name: The name of the security group. For valid values, see the GroupName parameter of the CreateSecurityGroup action in the Amazon EC2 API Reference. It is not recommended to use an explicit group name. Default: If you don't specify a GroupName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        '''
        props = SecurityGroupProps(
            vpc=vpc,
            allow_all_outbound=allow_all_outbound,
            description=description,
            security_group_name=security_group_name,
        )

        jsii.create(SecurityGroup, self, [scope, id, props])

    @jsii.member(jsii_name="fromLookup") # type: ignore[misc]
    @builtins.classmethod
    def from_lookup(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        security_group_id: builtins.str,
    ) -> ISecurityGroup:
        '''Look up a security group by id.

        :param scope: -
        :param id: -
        :param security_group_id: -
        '''
        return typing.cast(ISecurityGroup, jsii.sinvoke(cls, "fromLookup", [scope, id, security_group_id]))

    @jsii.member(jsii_name="fromSecurityGroupId") # type: ignore[misc]
    @builtins.classmethod
    def from_security_group_id(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        security_group_id: builtins.str,
        *,
        allow_all_outbound: typing.Optional[builtins.bool] = None,
        mutable: typing.Optional[builtins.bool] = None,
    ) -> ISecurityGroup:
        '''Import an existing security group into this app.

        This method will assume that the Security Group has a rule in it which allows
        all outbound traffic, and so will not add egress rules to the imported Security
        Group (only ingress rules).

        If your existing Security Group needs to have egress rules added, pass the
        ``allowAllOutbound: false`` option on import.

        :param scope: -
        :param id: -
        :param security_group_id: -
        :param allow_all_outbound: (experimental) Mark the SecurityGroup as having been created allowing all outbound traffic. Only if this is set to false will egress rules be added to this security group. Be aware, this would undo any potential "all outbound traffic" default. Default: true
        :param mutable: (experimental) If a SecurityGroup is mutable CDK can add rules to existing groups. Beware that making a SecurityGroup immutable might lead to issue due to missing ingress/egress rules for new resources. Default: true
        '''
        options = SecurityGroupImportOptions(
            allow_all_outbound=allow_all_outbound, mutable=mutable
        )

        return typing.cast(ISecurityGroup, jsii.sinvoke(cls, "fromSecurityGroupId", [scope, id, security_group_id, options]))

    @jsii.member(jsii_name="isSecurityGroup") # type: ignore[misc]
    @builtins.classmethod
    def is_security_group(cls, x: typing.Any) -> builtins.bool:
        '''Return whether the indicated object is a security group.

        :param x: -
        '''
        return typing.cast(builtins.bool, jsii.sinvoke(cls, "isSecurityGroup", [x]))

    @jsii.member(jsii_name="addEgressRule")
    def add_egress_rule(
        self,
        peer: IPeer,
        connection: Port,
        description: typing.Optional[builtins.str] = None,
        remote_rule: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Add an egress rule for the current security group.

        ``remoteRule`` controls where the Rule object is created if the peer is also a
        securityGroup and they are in different stack. If false (default) the
        rule object is created under the current SecurityGroup object. If true and the
        peer is also a SecurityGroup, the rule object is created under the remote
        SecurityGroup object.

        :param peer: -
        :param connection: -
        :param description: -
        :param remote_rule: -
        '''
        return typing.cast(None, jsii.invoke(self, "addEgressRule", [peer, connection, description, remote_rule]))

    @jsii.member(jsii_name="addIngressRule")
    def add_ingress_rule(
        self,
        peer: IPeer,
        connection: Port,
        description: typing.Optional[builtins.str] = None,
        remote_rule: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Add an ingress rule for the current security group.

        ``remoteRule`` controls where the Rule object is created if the peer is also a
        securityGroup and they are in different stack. If false (default) the
        rule object is created under the current SecurityGroup object. If true and the
        peer is also a SecurityGroup, the rule object is created under the remote
        SecurityGroup object.

        :param peer: -
        :param connection: -
        :param description: -
        :param remote_rule: -
        '''
        return typing.cast(None, jsii.invoke(self, "addIngressRule", [peer, connection, description, remote_rule]))

    @jsii.member(jsii_name="toEgressRuleConfig")
    def to_egress_rule_config(self) -> typing.Any:
        '''Produce the egress rule JSON for the given connection.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toEgressRuleConfig", []))

    @jsii.member(jsii_name="toIngressRuleConfig")
    def to_ingress_rule_config(self) -> typing.Any:
        '''Produce the ingress rule JSON for the given connection.'''
        return typing.cast(typing.Any, jsii.invoke(self, "toIngressRuleConfig", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="allowAllOutbound")
    def allow_all_outbound(self) -> builtins.bool:
        '''Whether the SecurityGroup has been configured to allow all outbound traffic.'''
        return typing.cast(builtins.bool, jsii.get(self, "allowAllOutbound"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="canInlineRule")
    def can_inline_rule(self) -> builtins.bool:
        '''Whether the rule can be inlined into a SecurityGroup or not.'''
        return typing.cast(builtins.bool, jsii.get(self, "canInlineRule"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connections")
    def connections(self) -> "Connections":
        return typing.cast("Connections", jsii.get(self, "connections"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroupId")
    def security_group_id(self) -> builtins.str:
        '''The ID of the security group.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "securityGroupId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroupName")
    def security_group_name(self) -> builtins.str:
        '''An attribute that represents the security group name.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "securityGroupName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroupVpcId")
    def security_group_vpc_id(self) -> builtins.str:
        '''The VPC ID this security group is part of.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "securityGroupVpcId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="uniqueId")
    def unique_id(self) -> builtins.str:
        '''A unique identifier for this connection peer.'''
        return typing.cast(builtins.str, jsii.get(self, "uniqueId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="defaultPort")
    def default_port(self) -> typing.Optional[Port]:
        return typing.cast(typing.Optional[Port], jsii.get(self, "defaultPort"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.SecurityGroupImportOptions",
    jsii_struct_bases=[],
    name_mapping={"allow_all_outbound": "allowAllOutbound", "mutable": "mutable"},
)
class SecurityGroupImportOptions:
    def __init__(
        self,
        *,
        allow_all_outbound: typing.Optional[builtins.bool] = None,
        mutable: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Additional options for imported security groups.

        :param allow_all_outbound: (experimental) Mark the SecurityGroup as having been created allowing all outbound traffic. Only if this is set to false will egress rules be added to this security group. Be aware, this would undo any potential "all outbound traffic" default. Default: true
        :param mutable: (experimental) If a SecurityGroup is mutable CDK can add rules to existing groups. Beware that making a SecurityGroup immutable might lead to issue due to missing ingress/egress rules for new resources. Default: true
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if allow_all_outbound is not None:
            self._values["allow_all_outbound"] = allow_all_outbound
        if mutable is not None:
            self._values["mutable"] = mutable

    @builtins.property
    def allow_all_outbound(self) -> typing.Optional[builtins.bool]:
        '''(experimental) Mark the SecurityGroup as having been created allowing all outbound traffic.

        Only if this is set to false will egress rules be added to this security
        group. Be aware, this would undo any potential "all outbound traffic"
        default.

        :default: true

        :stability: experimental
        '''
        result = self._values.get("allow_all_outbound")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def mutable(self) -> typing.Optional[builtins.bool]:
        '''(experimental) If a SecurityGroup is mutable CDK can add rules to existing groups.

        Beware that making a SecurityGroup immutable might lead to issue
        due to missing ingress/egress rules for new resources.

        :default: true

        :stability: experimental
        '''
        result = self._values.get("mutable")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SecurityGroupImportOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.SecurityGroupProps",
    jsii_struct_bases=[],
    name_mapping={
        "vpc": "vpc",
        "allow_all_outbound": "allowAllOutbound",
        "description": "description",
        "security_group_name": "securityGroupName",
    },
)
class SecurityGroupProps:
    def __init__(
        self,
        *,
        vpc: IVpc,
        allow_all_outbound: typing.Optional[builtins.bool] = None,
        description: typing.Optional[builtins.str] = None,
        security_group_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param vpc: The VPC in which to create the security group.
        :param allow_all_outbound: Whether to allow all outbound traffic by default. If this is set to true, there will only be a single egress rule which allows all outbound traffic. If this is set to false, no outbound traffic will be allowed by default and all egress traffic must be explicitly authorized. Default: true
        :param description: A description of the security group. Default: The default name will be the construct's CDK path.
        :param security_group_name: The name of the security group. For valid values, see the GroupName parameter of the CreateSecurityGroup action in the Amazon EC2 API Reference. It is not recommended to use an explicit group name. Default: If you don't specify a GroupName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "vpc": vpc,
        }
        if allow_all_outbound is not None:
            self._values["allow_all_outbound"] = allow_all_outbound
        if description is not None:
            self._values["description"] = description
        if security_group_name is not None:
            self._values["security_group_name"] = security_group_name

    @builtins.property
    def vpc(self) -> IVpc:
        '''The VPC in which to create the security group.'''
        result = self._values.get("vpc")
        assert result is not None, "Required property 'vpc' is missing"
        return typing.cast(IVpc, result)

    @builtins.property
    def allow_all_outbound(self) -> typing.Optional[builtins.bool]:
        '''Whether to allow all outbound traffic by default.

        If this is set to true, there will only be a single egress rule which allows all
        outbound traffic. If this is set to false, no outbound traffic will be allowed by
        default and all egress traffic must be explicitly authorized.

        :default: true
        '''
        result = self._values.get("allow_all_outbound")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def description(self) -> typing.Optional[builtins.str]:
        '''A description of the security group.

        :default: The default name will be the construct's CDK path.
        '''
        result = self._values.get("description")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def security_group_name(self) -> typing.Optional[builtins.str]:
        '''The name of the security group.

        For valid values, see the GroupName
        parameter of the CreateSecurityGroup action in the Amazon EC2 API
        Reference.

        It is not recommended to use an explicit group name.

        :default:

        If you don't specify a GroupName, AWS CloudFormation generates a
        unique physical ID and uses that ID for the group name.
        '''
        result = self._values.get("security_group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SecurityGroupProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.SelectedSubnets",
    jsii_struct_bases=[],
    name_mapping={
        "availability_zones": "availabilityZones",
        "has_public": "hasPublic",
        "internet_connectivity_established": "internetConnectivityEstablished",
        "subnet_ids": "subnetIds",
        "subnets": "subnets",
    },
)
class SelectedSubnets:
    def __init__(
        self,
        *,
        availability_zones: typing.List[builtins.str],
        has_public: builtins.bool,
        internet_connectivity_established: aws_cdk.core.IDependable,
        subnet_ids: typing.List[builtins.str],
        subnets: typing.List[ISubnet],
    ) -> None:
        '''Result of selecting a subset of subnets from a VPC.

        :param availability_zones: The respective AZs of each subnet.
        :param has_public: Whether any of the given subnets are from the VPC's public subnets.
        :param internet_connectivity_established: Dependency representing internet connectivity for these subnets.
        :param subnet_ids: The subnet IDs.
        :param subnets: Selected subnet objects.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "availability_zones": availability_zones,
            "has_public": has_public,
            "internet_connectivity_established": internet_connectivity_established,
            "subnet_ids": subnet_ids,
            "subnets": subnets,
        }

    @builtins.property
    def availability_zones(self) -> typing.List[builtins.str]:
        '''The respective AZs of each subnet.'''
        result = self._values.get("availability_zones")
        assert result is not None, "Required property 'availability_zones' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def has_public(self) -> builtins.bool:
        '''Whether any of the given subnets are from the VPC's public subnets.'''
        result = self._values.get("has_public")
        assert result is not None, "Required property 'has_public' is missing"
        return typing.cast(builtins.bool, result)

    @builtins.property
    def internet_connectivity_established(self) -> aws_cdk.core.IDependable:
        '''Dependency representing internet connectivity for these subnets.'''
        result = self._values.get("internet_connectivity_established")
        assert result is not None, "Required property 'internet_connectivity_established' is missing"
        return typing.cast(aws_cdk.core.IDependable, result)

    @builtins.property
    def subnet_ids(self) -> typing.List[builtins.str]:
        '''The subnet IDs.'''
        result = self._values.get("subnet_ids")
        assert result is not None, "Required property 'subnet_ids' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def subnets(self) -> typing.List[ISubnet]:
        '''Selected subnet objects.'''
        result = self._values.get("subnets")
        assert result is not None, "Required property 'subnets' is missing"
        return typing.cast(typing.List[ISubnet], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SelectedSubnets(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.SpotInstanceInterruption")
class SpotInstanceInterruption(enum.Enum):
    '''Provides the options for the types of interruption for spot instances.'''

    STOP = "STOP"
    '''The instance will stop when interrupted.'''
    TERMINATE = "TERMINATE"
    '''The instance will be terminated when interrupted.'''
    HIBERNATE = "HIBERNATE"
    '''The instance will hibernate when interrupted.'''


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.SpotRequestType")
class SpotRequestType(enum.Enum):
    '''The Spot Instance request type.

    :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html
    '''

    ONE_TIME = "ONE_TIME"
    '''A one-time Spot Instance request remains active until Amazon EC2 launches the Spot Instance, the request expires, or you cancel the request.

    If the Spot price exceeds your maximum price
    or capacity is not available, your Spot Instance is terminated and the Spot Instance request
    is closed.
    '''
    PERSISTENT = "PERSISTENT"
    '''A persistent Spot Instance request remains active until it expires or you cancel it, even if the request is fulfilled.

    If the Spot price exceeds your maximum price or capacity is not available,
    your Spot Instance is interrupted. After your instance is interrupted, when your maximum price exceeds
    the Spot price or capacity becomes available again, the Spot Instance is started if stopped or resumed
    if hibernated.
    '''


@jsii.implements(ISubnet)
class Subnet(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.Subnet",
):
    '''Represents a new VPC subnet resource.

    :resource: AWS::EC2::Subnet
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        availability_zone: builtins.str,
        cidr_block: builtins.str,
        vpc_id: builtins.str,
        map_public_ip_on_launch: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param availability_zone: The availability zone for the subnet.
        :param cidr_block: The CIDR notation for this subnet.
        :param vpc_id: The VPC which this subnet is part of.
        :param map_public_ip_on_launch: Controls if a public IP is associated to an instance at launch. Default: true in Subnet.Public, false in Subnet.Private or Subnet.Isolated.
        '''
        props = SubnetProps(
            availability_zone=availability_zone,
            cidr_block=cidr_block,
            vpc_id=vpc_id,
            map_public_ip_on_launch=map_public_ip_on_launch,
        )

        jsii.create(Subnet, self, [scope, id, props])

    @jsii.member(jsii_name="fromSubnetAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_subnet_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        subnet_id: builtins.str,
        availability_zone: typing.Optional[builtins.str] = None,
        ipv4_cidr_block: typing.Optional[builtins.str] = None,
        route_table_id: typing.Optional[builtins.str] = None,
    ) -> ISubnet:
        '''
        :param scope: -
        :param id: -
        :param subnet_id: The subnetId for this particular subnet.
        :param availability_zone: The Availability Zone the subnet is located in. Default: - No AZ information, cannot use AZ selection features
        :param ipv4_cidr_block: The IPv4 CIDR block associated with the subnet. Default: - No CIDR information, cannot use CIDR filter features
        :param route_table_id: The ID of the route table for this particular subnet. Default: - No route table information, cannot create VPC endpoints
        '''
        attrs = SubnetAttributes(
            subnet_id=subnet_id,
            availability_zone=availability_zone,
            ipv4_cidr_block=ipv4_cidr_block,
            route_table_id=route_table_id,
        )

        return typing.cast(ISubnet, jsii.sinvoke(cls, "fromSubnetAttributes", [scope, id, attrs]))

    @jsii.member(jsii_name="fromSubnetId") # type: ignore[misc]
    @builtins.classmethod
    def from_subnet_id(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        subnet_id: builtins.str,
    ) -> ISubnet:
        '''Import existing subnet from id.

        :param scope: -
        :param id: -
        :param subnet_id: -
        '''
        return typing.cast(ISubnet, jsii.sinvoke(cls, "fromSubnetId", [scope, id, subnet_id]))

    @jsii.member(jsii_name="isVpcSubnet") # type: ignore[misc]
    @builtins.classmethod
    def is_vpc_subnet(cls, x: typing.Any) -> builtins.bool:
        '''
        :param x: -
        '''
        return typing.cast(builtins.bool, jsii.sinvoke(cls, "isVpcSubnet", [x]))

    @jsii.member(jsii_name="addDefaultInternetRoute")
    def add_default_internet_route(
        self,
        gateway_id: builtins.str,
        gateway_attachment: aws_cdk.core.IDependable,
    ) -> None:
        '''Create a default route that points to a passed IGW, with a dependency on the IGW's attachment to the VPC.

        :param gateway_id: the logical ID (ref) of the gateway attached to your VPC.
        :param gateway_attachment: the gateway attachment construct to be added as a dependency.
        '''
        return typing.cast(None, jsii.invoke(self, "addDefaultInternetRoute", [gateway_id, gateway_attachment]))

    @jsii.member(jsii_name="addDefaultNatRoute")
    def add_default_nat_route(self, nat_gateway_id: builtins.str) -> None:
        '''Adds an entry to this subnets route table that points to the passed NATGatwayId.

        :param nat_gateway_id: The ID of the NAT gateway.
        '''
        return typing.cast(None, jsii.invoke(self, "addDefaultNatRoute", [nat_gateway_id]))

    @jsii.member(jsii_name="addRoute")
    def add_route(
        self,
        id: builtins.str,
        *,
        router_id: builtins.str,
        router_type: RouterType,
        destination_cidr_block: typing.Optional[builtins.str] = None,
        destination_ipv6_cidr_block: typing.Optional[builtins.str] = None,
        enables_internet_connectivity: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Adds an entry to this subnets route table.

        :param id: -
        :param router_id: The ID of the router. Can be an instance ID, gateway ID, etc, depending on the router type.
        :param router_type: What type of router to route this traffic to.
        :param destination_cidr_block: IPv4 range this route applies to. Default: '0.0.0.0/0'
        :param destination_ipv6_cidr_block: IPv6 range this route applies to. Default: - Uses IPv6
        :param enables_internet_connectivity: Whether this route will enable internet connectivity. If true, this route will be added before any AWS resources that depend on internet connectivity in the VPC will be created. Default: false
        '''
        options = AddRouteOptions(
            router_id=router_id,
            router_type=router_type,
            destination_cidr_block=destination_cidr_block,
            destination_ipv6_cidr_block=destination_ipv6_cidr_block,
            enables_internet_connectivity=enables_internet_connectivity,
        )

        return typing.cast(None, jsii.invoke(self, "addRoute", [id, options]))

    @jsii.member(jsii_name="associateNetworkAcl")
    def associate_network_acl(self, id: builtins.str, network_acl: INetworkAcl) -> None:
        '''Associate a Network ACL with this subnet.

        :param id: -
        :param network_acl: -
        '''
        return typing.cast(None, jsii.invoke(self, "associateNetworkAcl", [id, network_acl]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> builtins.str:
        '''The Availability Zone the subnet is located in.'''
        return typing.cast(builtins.str, jsii.get(self, "availabilityZone"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="dependencyElements")
    def dependency_elements(self) -> typing.List[aws_cdk.core.IDependable]:
        '''Parts of this VPC subnet.'''
        return typing.cast(typing.List[aws_cdk.core.IDependable], jsii.get(self, "dependencyElements"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="internetConnectivityEstablished")
    def internet_connectivity_established(self) -> aws_cdk.core.IDependable:
        '''Dependable that can be depended upon to force internet connectivity established on the VPC.'''
        return typing.cast(aws_cdk.core.IDependable, jsii.get(self, "internetConnectivityEstablished"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="ipv4CidrBlock")
    def ipv4_cidr_block(self) -> builtins.str:
        '''The IPv4 CIDR block for this subnet.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "ipv4CidrBlock"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkAcl")
    def network_acl(self) -> INetworkAcl:
        '''Network ACL associated with this Subnet.

        Upon creation, this is the default ACL which allows all traffic, except
        explicit DENY entries that you add.

        You can replace it with a custom ACL which denies all traffic except
        the explicit ALLOW entries that you add by creating a ``NetworkAcl``
        object and calling ``associateNetworkAcl()``.
        '''
        return typing.cast(INetworkAcl, jsii.get(self, "networkAcl"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="routeTable")
    def route_table(self) -> IRouteTable:
        '''The routeTableId attached to this subnet.'''
        return typing.cast(IRouteTable, jsii.get(self, "routeTable"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetAvailabilityZone")
    def subnet_availability_zone(self) -> builtins.str:
        '''
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetAvailabilityZone"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetId")
    def subnet_id(self) -> builtins.str:
        '''The subnetId for this particular subnet.'''
        return typing.cast(builtins.str, jsii.get(self, "subnetId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetIpv6CidrBlocks")
    def subnet_ipv6_cidr_blocks(self) -> typing.List[builtins.str]:
        '''
        :attribute: true
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "subnetIpv6CidrBlocks"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetNetworkAclAssociationId")
    def subnet_network_acl_association_id(self) -> builtins.str:
        '''
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetNetworkAclAssociationId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetOutpostArn")
    def subnet_outpost_arn(self) -> builtins.str:
        '''The Amazon Resource Name (ARN) of the Outpost for this subnet (if one exists).

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetOutpostArn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetVpcId")
    def subnet_vpc_id(self) -> builtins.str:
        '''
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetVpcId"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.SubnetAttributes",
    jsii_struct_bases=[],
    name_mapping={
        "subnet_id": "subnetId",
        "availability_zone": "availabilityZone",
        "ipv4_cidr_block": "ipv4CidrBlock",
        "route_table_id": "routeTableId",
    },
)
class SubnetAttributes:
    def __init__(
        self,
        *,
        subnet_id: builtins.str,
        availability_zone: typing.Optional[builtins.str] = None,
        ipv4_cidr_block: typing.Optional[builtins.str] = None,
        route_table_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param subnet_id: The subnetId for this particular subnet.
        :param availability_zone: The Availability Zone the subnet is located in. Default: - No AZ information, cannot use AZ selection features
        :param ipv4_cidr_block: The IPv4 CIDR block associated with the subnet. Default: - No CIDR information, cannot use CIDR filter features
        :param route_table_id: The ID of the route table for this particular subnet. Default: - No route table information, cannot create VPC endpoints
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "subnet_id": subnet_id,
        }
        if availability_zone is not None:
            self._values["availability_zone"] = availability_zone
        if ipv4_cidr_block is not None:
            self._values["ipv4_cidr_block"] = ipv4_cidr_block
        if route_table_id is not None:
            self._values["route_table_id"] = route_table_id

    @builtins.property
    def subnet_id(self) -> builtins.str:
        '''The subnetId for this particular subnet.'''
        result = self._values.get("subnet_id")
        assert result is not None, "Required property 'subnet_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def availability_zone(self) -> typing.Optional[builtins.str]:
        '''The Availability Zone the subnet is located in.

        :default: - No AZ information, cannot use AZ selection features
        '''
        result = self._values.get("availability_zone")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ipv4_cidr_block(self) -> typing.Optional[builtins.str]:
        '''The IPv4 CIDR block associated with the subnet.

        :default: - No CIDR information, cannot use CIDR filter features
        '''
        result = self._values.get("ipv4_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def route_table_id(self) -> typing.Optional[builtins.str]:
        '''The ID of the route table for this particular subnet.

        :default: - No route table information, cannot create VPC endpoints
        '''
        result = self._values.get("route_table_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SubnetAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.SubnetConfiguration",
    jsii_struct_bases=[],
    name_mapping={
        "name": "name",
        "subnet_type": "subnetType",
        "cidr_mask": "cidrMask",
        "reserved": "reserved",
    },
)
class SubnetConfiguration:
    def __init__(
        self,
        *,
        name: builtins.str,
        subnet_type: "SubnetType",
        cidr_mask: typing.Optional[jsii.Number] = None,
        reserved: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Specify configuration parameters for a single subnet group in a VPC.

        :param name: Logical name for the subnet group. This name can be used when selecting VPC subnets to distinguish between different subnet groups of the same type.
        :param subnet_type: The type of Subnet to configure. The Subnet type will control the ability to route and connect to the Internet.
        :param cidr_mask: The number of leading 1 bits in the routing mask. The number of available IP addresses in each subnet of this group will be equal to ``2^(32 - cidrMask) - 2``. Valid values are ``16--28``. Default: - Available IP space is evenly divided across subnets.
        :param reserved: Controls if subnet IP space needs to be reserved. When true, the IP space for the subnet is reserved but no actual resources are provisioned. This space is only dependent on the number of availability zones and on ``cidrMask`` - all other subnet properties are ignored. Default: false
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
            "subnet_type": subnet_type,
        }
        if cidr_mask is not None:
            self._values["cidr_mask"] = cidr_mask
        if reserved is not None:
            self._values["reserved"] = reserved

    @builtins.property
    def name(self) -> builtins.str:
        '''Logical name for the subnet group.

        This name can be used when selecting VPC subnets to distinguish
        between different subnet groups of the same type.
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def subnet_type(self) -> "SubnetType":
        '''The type of Subnet to configure.

        The Subnet type will control the ability to route and connect to the
        Internet.
        '''
        result = self._values.get("subnet_type")
        assert result is not None, "Required property 'subnet_type' is missing"
        return typing.cast("SubnetType", result)

    @builtins.property
    def cidr_mask(self) -> typing.Optional[jsii.Number]:
        '''The number of leading 1 bits in the routing mask.

        The number of available IP addresses in each subnet of this group
        will be equal to ``2^(32 - cidrMask) - 2``.

        Valid values are ``16--28``.

        :default: - Available IP space is evenly divided across subnets.
        '''
        result = self._values.get("cidr_mask")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def reserved(self) -> typing.Optional[builtins.bool]:
        '''Controls if subnet IP space needs to be reserved.

        When true, the IP space for the subnet is reserved but no actual
        resources are provisioned. This space is only dependent on the
        number of availability zones and on ``cidrMask`` - all other subnet
        properties are ignored.

        :default: false
        '''
        result = self._values.get("reserved")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SubnetConfiguration(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class SubnetFilter(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-ec2.SubnetFilter",
):
    '''Contains logic which chooses a set of subnets from a larger list, in conjunction with SubnetSelection, to determine where to place AWS resources such as VPC endpoints, EC2 instances, etc.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_SubnetFilterProxy"]:
        return _SubnetFilterProxy

    def __init__(self) -> None:
        jsii.create(SubnetFilter, self, [])

    @jsii.member(jsii_name="availabilityZones") # type: ignore[misc]
    @builtins.classmethod
    def availability_zones(
        cls,
        availability_zones: typing.List[builtins.str],
    ) -> "SubnetFilter":
        '''Chooses subnets which are in one of the given availability zones.

        :param availability_zones: -
        '''
        return typing.cast("SubnetFilter", jsii.sinvoke(cls, "availabilityZones", [availability_zones]))

    @jsii.member(jsii_name="containsIpAddresses") # type: ignore[misc]
    @builtins.classmethod
    def contains_ip_addresses(
        cls,
        ipv4addrs: typing.List[builtins.str],
    ) -> "SubnetFilter":
        '''Chooses subnets which contain any of the specified IP addresses.

        :param ipv4addrs: -
        '''
        return typing.cast("SubnetFilter", jsii.sinvoke(cls, "containsIpAddresses", [ipv4addrs]))

    @jsii.member(jsii_name="onePerAz") # type: ignore[misc]
    @builtins.classmethod
    def one_per_az(cls) -> "SubnetFilter":
        '''Chooses subnets such that there is at most one per availability zone.'''
        return typing.cast("SubnetFilter", jsii.sinvoke(cls, "onePerAz", []))

    @jsii.member(jsii_name="selectSubnets")
    def select_subnets(self, _subnets: typing.List[ISubnet]) -> typing.List[ISubnet]:
        '''Executes the subnet filtering logic, returning a filtered set of subnets.

        :param _subnets: -
        '''
        return typing.cast(typing.List[ISubnet], jsii.invoke(self, "selectSubnets", [_subnets]))


class _SubnetFilterProxy(SubnetFilter):
    pass


@jsii.implements(ISubnetNetworkAclAssociation)
class SubnetNetworkAclAssociation(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.SubnetNetworkAclAssociation",
):
    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        network_acl: INetworkAcl,
        subnet: ISubnet,
        subnet_network_acl_association_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param network_acl: (experimental) The Network ACL this association is defined for.
        :param subnet: (experimental) ID of the Subnet.
        :param subnet_network_acl_association_name: (experimental) The name of the SubnetNetworkAclAssociation. It is not recommended to use an explicit name. Default: If you don't specify a SubnetNetworkAclAssociationName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        '''
        props = SubnetNetworkAclAssociationProps(
            network_acl=network_acl,
            subnet=subnet,
            subnet_network_acl_association_name=subnet_network_acl_association_name,
        )

        jsii.create(SubnetNetworkAclAssociation, self, [scope, id, props])

    @jsii.member(jsii_name="fromSubnetNetworkAclAssociationAssociationId") # type: ignore[misc]
    @builtins.classmethod
    def from_subnet_network_acl_association_association_id(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        subnet_network_acl_association_association_id: builtins.str,
    ) -> ISubnetNetworkAclAssociation:
        '''
        :param scope: -
        :param id: -
        :param subnet_network_acl_association_association_id: -
        '''
        return typing.cast(ISubnetNetworkAclAssociation, jsii.sinvoke(cls, "fromSubnetNetworkAclAssociationAssociationId", [scope, id, subnet_network_acl_association_association_id]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="networkAcl")
    def network_acl(self) -> INetworkAcl:
        '''ID for the current Network ACL.

        :attribute: true
        '''
        return typing.cast(INetworkAcl, jsii.get(self, "networkAcl"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnet")
    def subnet(self) -> ISubnet:
        '''ID of the Subnet.

        :attribute: true
        '''
        return typing.cast(ISubnet, jsii.get(self, "subnet"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="subnetNetworkAclAssociationAssociationId")
    def subnet_network_acl_association_association_id(self) -> builtins.str:
        '''ID for the current SubnetNetworkAclAssociation.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "subnetNetworkAclAssociationAssociationId"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.SubnetNetworkAclAssociationProps",
    jsii_struct_bases=[],
    name_mapping={
        "network_acl": "networkAcl",
        "subnet": "subnet",
        "subnet_network_acl_association_name": "subnetNetworkAclAssociationName",
    },
)
class SubnetNetworkAclAssociationProps:
    def __init__(
        self,
        *,
        network_acl: INetworkAcl,
        subnet: ISubnet,
        subnet_network_acl_association_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''(experimental) Properties to create a SubnetNetworkAclAssociation.

        :param network_acl: (experimental) The Network ACL this association is defined for.
        :param subnet: (experimental) ID of the Subnet.
        :param subnet_network_acl_association_name: (experimental) The name of the SubnetNetworkAclAssociation. It is not recommended to use an explicit name. Default: If you don't specify a SubnetNetworkAclAssociationName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "network_acl": network_acl,
            "subnet": subnet,
        }
        if subnet_network_acl_association_name is not None:
            self._values["subnet_network_acl_association_name"] = subnet_network_acl_association_name

    @builtins.property
    def network_acl(self) -> INetworkAcl:
        '''(experimental) The Network ACL this association is defined for.

        :stability: experimental
        :attribute: true
        '''
        result = self._values.get("network_acl")
        assert result is not None, "Required property 'network_acl' is missing"
        return typing.cast(INetworkAcl, result)

    @builtins.property
    def subnet(self) -> ISubnet:
        '''(experimental) ID of the Subnet.

        :stability: experimental
        :attribute: true
        '''
        result = self._values.get("subnet")
        assert result is not None, "Required property 'subnet' is missing"
        return typing.cast(ISubnet, result)

    @builtins.property
    def subnet_network_acl_association_name(self) -> typing.Optional[builtins.str]:
        '''(experimental) The name of the SubnetNetworkAclAssociation.

        It is not recommended to use an explicit name.

        :default:

        If you don't specify a SubnetNetworkAclAssociationName, AWS CloudFormation generates a
        unique physical ID and uses that ID for the group name.

        :stability: experimental
        '''
        result = self._values.get("subnet_network_acl_association_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SubnetNetworkAclAssociationProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.SubnetProps",
    jsii_struct_bases=[],
    name_mapping={
        "availability_zone": "availabilityZone",
        "cidr_block": "cidrBlock",
        "vpc_id": "vpcId",
        "map_public_ip_on_launch": "mapPublicIpOnLaunch",
    },
)
class SubnetProps:
    def __init__(
        self,
        *,
        availability_zone: builtins.str,
        cidr_block: builtins.str,
        vpc_id: builtins.str,
        map_public_ip_on_launch: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Specify configuration parameters for a VPC subnet.

        :param availability_zone: The availability zone for the subnet.
        :param cidr_block: The CIDR notation for this subnet.
        :param vpc_id: The VPC which this subnet is part of.
        :param map_public_ip_on_launch: Controls if a public IP is associated to an instance at launch. Default: true in Subnet.Public, false in Subnet.Private or Subnet.Isolated.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "availability_zone": availability_zone,
            "cidr_block": cidr_block,
            "vpc_id": vpc_id,
        }
        if map_public_ip_on_launch is not None:
            self._values["map_public_ip_on_launch"] = map_public_ip_on_launch

    @builtins.property
    def availability_zone(self) -> builtins.str:
        '''The availability zone for the subnet.'''
        result = self._values.get("availability_zone")
        assert result is not None, "Required property 'availability_zone' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def cidr_block(self) -> builtins.str:
        '''The CIDR notation for this subnet.'''
        result = self._values.get("cidr_block")
        assert result is not None, "Required property 'cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''The VPC which this subnet is part of.'''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def map_public_ip_on_launch(self) -> typing.Optional[builtins.bool]:
        '''Controls if a public IP is associated to an instance at launch.

        :default: true in Subnet.Public, false in Subnet.Private or Subnet.Isolated.
        '''
        result = self._values.get("map_public_ip_on_launch")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SubnetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.SubnetSelection",
    jsii_struct_bases=[],
    name_mapping={
        "availability_zones": "availabilityZones",
        "one_per_az": "onePerAz",
        "subnet_filters": "subnetFilters",
        "subnet_group_name": "subnetGroupName",
        "subnet_name": "subnetName",
        "subnets": "subnets",
        "subnet_type": "subnetType",
    },
)
class SubnetSelection:
    def __init__(
        self,
        *,
        availability_zones: typing.Optional[typing.List[builtins.str]] = None,
        one_per_az: typing.Optional[builtins.bool] = None,
        subnet_filters: typing.Optional[typing.List[SubnetFilter]] = None,
        subnet_group_name: typing.Optional[builtins.str] = None,
        subnet_name: typing.Optional[builtins.str] = None,
        subnets: typing.Optional[typing.List[ISubnet]] = None,
        subnet_type: typing.Optional["SubnetType"] = None,
    ) -> None:
        '''Customize subnets that are selected for placement of ENIs.

        Constructs that allow customization of VPC placement use parameters of this
        type to provide placement settings.

        By default, the instances are placed in the private subnets.

        :param availability_zones: Select subnets only in the given AZs. Default: no filtering on AZs is done
        :param one_per_az: If true, return at most one subnet per AZ. Default: false
        :param subnet_filters: List of provided subnet filters. Default: - none
        :param subnet_group_name: Select the subnet group with the given name. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them. Otherwise, prefer ``subnetType``. This field does not select individual subnets, it selects all subnets that share the given subnet group name. This is the name supplied in ``subnetConfiguration``. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: - Selection by type instead of by name
        :param subnet_name: (deprecated) Alias for ``subnetGroupName``. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them.
        :param subnets: Explicitly select individual subnets. Use this if you don't want to automatically use all subnets in a group, but have a need to control selection down to individual subnets. Cannot be specified together with ``subnetType`` or ``subnetGroupName``. Default: - Use all subnets in a selected group (all private subnets by default)
        :param subnet_type: Select all subnets of the given type. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: SubnetType.PRIVATE (or ISOLATED or PUBLIC if there are no PRIVATE subnets)
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if availability_zones is not None:
            self._values["availability_zones"] = availability_zones
        if one_per_az is not None:
            self._values["one_per_az"] = one_per_az
        if subnet_filters is not None:
            self._values["subnet_filters"] = subnet_filters
        if subnet_group_name is not None:
            self._values["subnet_group_name"] = subnet_group_name
        if subnet_name is not None:
            self._values["subnet_name"] = subnet_name
        if subnets is not None:
            self._values["subnets"] = subnets
        if subnet_type is not None:
            self._values["subnet_type"] = subnet_type

    @builtins.property
    def availability_zones(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Select subnets only in the given AZs.

        :default: no filtering on AZs is done
        '''
        result = self._values.get("availability_zones")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def one_per_az(self) -> typing.Optional[builtins.bool]:
        '''If true, return at most one subnet per AZ.

        :default: false
        '''
        result = self._values.get("one_per_az")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def subnet_filters(self) -> typing.Optional[typing.List[SubnetFilter]]:
        '''List of provided subnet filters.

        :default: - none
        '''
        result = self._values.get("subnet_filters")
        return typing.cast(typing.Optional[typing.List[SubnetFilter]], result)

    @builtins.property
    def subnet_group_name(self) -> typing.Optional[builtins.str]:
        '''Select the subnet group with the given name.

        Select the subnet group with the given name. This only needs
        to be used if you have multiple subnet groups of the same type
        and you need to distinguish between them. Otherwise, prefer
        ``subnetType``.

        This field does not select individual subnets, it selects all subnets that
        share the given subnet group name. This is the name supplied in
        ``subnetConfiguration``.

        At most one of ``subnetType`` and ``subnetGroupName`` can be supplied.

        :default: - Selection by type instead of by name
        '''
        result = self._values.get("subnet_group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def subnet_name(self) -> typing.Optional[builtins.str]:
        '''(deprecated) Alias for ``subnetGroupName``.

        Select the subnet group with the given name. This only needs
        to be used if you have multiple subnet groups of the same type
        and you need to distinguish between them.

        :deprecated: Use ``subnetGroupName`` instead

        :stability: deprecated
        '''
        result = self._values.get("subnet_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def subnets(self) -> typing.Optional[typing.List[ISubnet]]:
        '''Explicitly select individual subnets.

        Use this if you don't want to automatically use all subnets in
        a group, but have a need to control selection down to
        individual subnets.

        Cannot be specified together with ``subnetType`` or ``subnetGroupName``.

        :default: - Use all subnets in a selected group (all private subnets by default)
        '''
        result = self._values.get("subnets")
        return typing.cast(typing.Optional[typing.List[ISubnet]], result)

    @builtins.property
    def subnet_type(self) -> typing.Optional["SubnetType"]:
        '''Select all subnets of the given type.

        At most one of ``subnetType`` and ``subnetGroupName`` can be supplied.

        :default: SubnetType.PRIVATE (or ISOLATED or PUBLIC if there are no PRIVATE subnets)
        '''
        result = self._values.get("subnet_type")
        return typing.cast(typing.Optional["SubnetType"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SubnetSelection(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.SubnetType")
class SubnetType(enum.Enum):
    '''The type of Subnet.'''

    ISOLATED = "ISOLATED"
    '''Isolated Subnets do not route traffic to the Internet (in this VPC).

    This can be good for subnets with RDS or Elasticache instances,
    or which route Internet traffic through a peer VPC.
    '''
    PRIVATE = "PRIVATE"
    '''Subnet that routes to the internet, but not vice versa.

    Instances in a private subnet can connect to the Internet, but will not
    allow connections to be initiated from the Internet. Internet traffic will
    be routed via a NAT Gateway.

    Normally a Private subnet will use a NAT gateway in the same AZ, but
    if ``natGateways`` is used to reduce the number of NAT gateways, a NAT
    gateway from another AZ will be used instead.
    '''
    PUBLIC = "PUBLIC"
    '''Subnet connected to the Internet.

    Instances in a Public subnet can connect to the Internet and can be
    connected to from the Internet as long as they are launched with public
    IPs (controlled on the AutoScalingGroup or other constructs that launch
    instances).

    Public subnets route outbound traffic via an Internet Gateway.
    '''


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.TrafficDirection")
class TrafficDirection(enum.Enum):
    '''(experimental) Direction of traffic the AclEntry applies to.

    :stability: experimental
    '''

    EGRESS = "EGRESS"
    '''(experimental) Traffic leaving the subnet.

    :stability: experimental
    '''
    INGRESS = "INGRESS"
    '''(experimental) Traffic entering the subnet.

    :stability: experimental
    '''


class UserData(metaclass=jsii.JSIIAbstractClass, jsii_type="@aws-cdk/aws-ec2.UserData"):
    '''Instance User Data.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_UserDataProxy"]:
        return _UserDataProxy

    def __init__(self) -> None:
        jsii.create(UserData, self, [])

    @jsii.member(jsii_name="custom") # type: ignore[misc]
    @builtins.classmethod
    def custom(cls, content: builtins.str) -> "UserData":
        '''Create a userdata object with custom content.

        :param content: -
        '''
        return typing.cast("UserData", jsii.sinvoke(cls, "custom", [content]))

    @jsii.member(jsii_name="forLinux") # type: ignore[misc]
    @builtins.classmethod
    def for_linux(cls, *, shebang: typing.Optional[builtins.str] = None) -> "UserData":
        '''Create a userdata object for Linux hosts.

        :param shebang: Shebang for the UserData script. Default: "#!/bin/bash"
        '''
        options = LinuxUserDataOptions(shebang=shebang)

        return typing.cast("UserData", jsii.sinvoke(cls, "forLinux", [options]))

    @jsii.member(jsii_name="forOperatingSystem") # type: ignore[misc]
    @builtins.classmethod
    def for_operating_system(cls, os: OperatingSystemType) -> "UserData":
        '''
        :param os: -
        '''
        return typing.cast("UserData", jsii.sinvoke(cls, "forOperatingSystem", [os]))

    @jsii.member(jsii_name="forWindows") # type: ignore[misc]
    @builtins.classmethod
    def for_windows(cls) -> "UserData":
        '''Create a userdata object for Windows hosts.'''
        return typing.cast("UserData", jsii.sinvoke(cls, "forWindows", []))

    @jsii.member(jsii_name="addCommands") # type: ignore[misc]
    @abc.abstractmethod
    def add_commands(self, *commands: builtins.str) -> None:
        '''Add one or more commands to the user data.

        :param commands: -
        '''
        ...

    @jsii.member(jsii_name="addExecuteFileCommand") # type: ignore[misc]
    @abc.abstractmethod
    def add_execute_file_command(
        self,
        *,
        file_path: builtins.str,
        arguments: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Adds commands to execute a file.

        :param file_path: The path to the file.
        :param arguments: The arguments to be passed to the file. Default: No arguments are passed to the file.
        '''
        ...

    @jsii.member(jsii_name="addOnExitCommands") # type: ignore[misc]
    @abc.abstractmethod
    def add_on_exit_commands(self, *commands: builtins.str) -> None:
        '''Add one or more commands to the user data that will run when the script exits.

        :param commands: -
        '''
        ...

    @jsii.member(jsii_name="addS3DownloadCommand") # type: ignore[misc]
    @abc.abstractmethod
    def add_s3_download_command(
        self,
        *,
        bucket: aws_cdk.aws_s3.IBucket,
        bucket_key: builtins.str,
        local_file: typing.Optional[builtins.str] = None,
    ) -> builtins.str:
        '''Adds commands to download a file from S3.

        :param bucket: Name of the S3 bucket to download from.
        :param bucket_key: The key of the file to download.
        :param local_file: The name of the local file. Default: Linux - /tmp/bucketKey Windows - %TEMP%/bucketKey

        :return: : The local path that the file will be downloaded to
        '''
        ...

    @jsii.member(jsii_name="addSignalOnExitCommand") # type: ignore[misc]
    @abc.abstractmethod
    def add_signal_on_exit_command(self, resource: aws_cdk.core.Resource) -> None:
        '''Adds a command which will send a cfn-signal when the user data script ends.

        :param resource: -
        '''
        ...

    @jsii.member(jsii_name="render") # type: ignore[misc]
    @abc.abstractmethod
    def render(self) -> builtins.str:
        '''Render the UserData for use in a construct.'''
        ...


class _UserDataProxy(UserData):
    @jsii.member(jsii_name="addCommands")
    def add_commands(self, *commands: builtins.str) -> None:
        '''Add one or more commands to the user data.

        :param commands: -
        '''
        return typing.cast(None, jsii.invoke(self, "addCommands", [*commands]))

    @jsii.member(jsii_name="addExecuteFileCommand")
    def add_execute_file_command(
        self,
        *,
        file_path: builtins.str,
        arguments: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Adds commands to execute a file.

        :param file_path: The path to the file.
        :param arguments: The arguments to be passed to the file. Default: No arguments are passed to the file.
        '''
        params = ExecuteFileOptions(file_path=file_path, arguments=arguments)

        return typing.cast(None, jsii.invoke(self, "addExecuteFileCommand", [params]))

    @jsii.member(jsii_name="addOnExitCommands")
    def add_on_exit_commands(self, *commands: builtins.str) -> None:
        '''Add one or more commands to the user data that will run when the script exits.

        :param commands: -
        '''
        return typing.cast(None, jsii.invoke(self, "addOnExitCommands", [*commands]))

    @jsii.member(jsii_name="addS3DownloadCommand")
    def add_s3_download_command(
        self,
        *,
        bucket: aws_cdk.aws_s3.IBucket,
        bucket_key: builtins.str,
        local_file: typing.Optional[builtins.str] = None,
    ) -> builtins.str:
        '''Adds commands to download a file from S3.

        :param bucket: Name of the S3 bucket to download from.
        :param bucket_key: The key of the file to download.
        :param local_file: The name of the local file. Default: Linux - /tmp/bucketKey Windows - %TEMP%/bucketKey

        :return: : The local path that the file will be downloaded to
        '''
        params = S3DownloadOptions(
            bucket=bucket, bucket_key=bucket_key, local_file=local_file
        )

        return typing.cast(builtins.str, jsii.invoke(self, "addS3DownloadCommand", [params]))

    @jsii.member(jsii_name="addSignalOnExitCommand")
    def add_signal_on_exit_command(self, resource: aws_cdk.core.Resource) -> None:
        '''Adds a command which will send a cfn-signal when the user data script ends.

        :param resource: -
        '''
        return typing.cast(None, jsii.invoke(self, "addSignalOnExitCommand", [resource]))

    @jsii.member(jsii_name="render")
    def render(self) -> builtins.str:
        '''Render the UserData for use in a construct.'''
        return typing.cast(builtins.str, jsii.invoke(self, "render", []))


@jsii.implements(IVolume)
class Volume(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.Volume",
):
    '''Creates a new EBS Volume in AWS EC2.'''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        availability_zone: builtins.str,
        auto_enable_io: typing.Optional[builtins.bool] = None,
        enable_multi_attach: typing.Optional[builtins.bool] = None,
        encrypted: typing.Optional[builtins.bool] = None,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
        iops: typing.Optional[jsii.Number] = None,
        removal_policy: typing.Optional[aws_cdk.core.RemovalPolicy] = None,
        size: typing.Optional[aws_cdk.core.Size] = None,
        snapshot_id: typing.Optional[builtins.str] = None,
        volume_name: typing.Optional[builtins.str] = None,
        volume_type: typing.Optional[EbsDeviceVolumeType] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param availability_zone: The Availability Zone in which to create the volume.
        :param auto_enable_io: Indicates whether the volume is auto-enabled for I/O operations. By default, Amazon EBS disables I/O to the volume from attached EC2 instances when it determines that a volume's data is potentially inconsistent. If the consistency of the volume is not a concern, and you prefer that the volume be made available immediately if it's impaired, you can configure the volume to automatically enable I/O. Default: false
        :param enable_multi_attach: Indicates whether Amazon EBS Multi-Attach is enabled. See {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volumes-multi.html#considerations|Considerations and limitations} for the constraints of multi-attach. Default: false
        :param encrypted: Specifies whether the volume should be encrypted. The effect of setting the encryption state to true depends on the volume origin (new or from a snapshot), starting encryption state, ownership, and whether encryption by default is enabled. For more information, see {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default|Encryption by Default} in the Amazon Elastic Compute Cloud User Guide. Encrypted Amazon EBS volumes must be attached to instances that support Amazon EBS encryption. For more information, see {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#EBSEncryption_supported_instances|Supported Instance Types.} Default: false
        :param encryption_key: The customer-managed encryption key that is used to encrypt the Volume. The encrypted property must be true if this is provided. Note: If using an {@link aws-kms.IKey} created from a {@link aws-kms.Key.fromKeyArn()} here, then the KMS key **must** have the following in its Key policy; otherwise, the Volume will fail to create:: { "Effect": "Allow", "Principal": { "AWS": "<arn for your account-user> ex: arn:aws:iam::00000000000:root" }, "Resource": "*", "Action": [ "kms:DescribeKey", "kms:GenerateDataKeyWithoutPlainText", ], "Condition": { "StringEquals": { "kms:ViaService": "ec2.<Region>.amazonaws.com", (eg: ec2.us-east-1.amazonaws.com) "kms:CallerAccount": "0000000000" (your account ID) } } } Default: The default KMS key for the account, region, and EC2 service is used.
        :param iops: The number of I/O operations per second (IOPS) to provision for the volume. The maximum ratio is 50 IOPS/GiB for PROVISIONED_IOPS_SSD, and 500 IOPS/GiB for both PROVISIONED_IOPS_SSD_IO2 and GENERAL_PURPOSE_SSD_GP3. See {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html} for more information. This parameter is valid only for PROVISIONED_IOPS_SSD, PROVISIONED_IOPS_SSD_IO2 and GENERAL_PURPOSE_SSD_GP3 volumes. Default: None -- Required for io1 and io2 volumes. The default for gp3 volumes is 3,000 IOPS if omitted.
        :param removal_policy: Policy to apply when the volume is removed from the stack. Default: RemovalPolicy.RETAIN
        :param size: The size of the volume, in GiBs. You must specify either a snapshot ID or a volume size. See {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html} for details on the allowable size for each type of volume. Default: If you're creating the volume from a snapshot and don't specify a volume size, the default is the snapshot size.
        :param snapshot_id: The snapshot from which to create the volume. You must specify either a snapshot ID or a volume size. Default: The EBS volume is not created from a snapshot.
        :param volume_name: The value of the physicalName property of this resource. Default: The physical name will be allocated by CloudFormation at deployment time
        :param volume_type: The type of the volume; what type of storage to use to form the EBS Volume. Default: {@link EbsDeviceVolumeType.GENERAL_PURPOSE_SSD}
        '''
        props = VolumeProps(
            availability_zone=availability_zone,
            auto_enable_io=auto_enable_io,
            enable_multi_attach=enable_multi_attach,
            encrypted=encrypted,
            encryption_key=encryption_key,
            iops=iops,
            removal_policy=removal_policy,
            size=size,
            snapshot_id=snapshot_id,
            volume_name=volume_name,
            volume_type=volume_type,
        )

        jsii.create(Volume, self, [scope, id, props])

    @jsii.member(jsii_name="fromVolumeAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_volume_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        availability_zone: builtins.str,
        volume_id: builtins.str,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
    ) -> IVolume:
        '''Import an existing EBS Volume into the Stack.

        :param scope: the scope of the import.
        :param id: the ID of the imported Volume in the construct tree.
        :param availability_zone: The availability zone that the EBS Volume is contained within (ex: us-west-2a).
        :param volume_id: The EBS Volume's ID.
        :param encryption_key: The customer-managed encryption key that is used to encrypt the Volume. Default: None -- The EBS Volume is not using a customer-managed KMS key for encryption.
        '''
        attrs = VolumeAttributes(
            availability_zone=availability_zone,
            volume_id=volume_id,
            encryption_key=encryption_key,
        )

        return typing.cast(IVolume, jsii.sinvoke(cls, "fromVolumeAttributes", [scope, id, attrs]))

    @jsii.member(jsii_name="grantAttachVolume")
    def grant_attach_volume(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        instances: typing.Optional[typing.List[IInstance]] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to attach this Volume to an instance.

        CAUTION: Granting an instance permission to attach to itself using this method will lead to
        an unresolvable circular reference between the instance role and the instance.
        Use {@link IVolume.grantAttachVolumeToSelf} to grant an instance permission to attach this
        volume to itself.

        :param grantee: -
        :param instances: -
        '''
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantAttachVolume", [grantee, instances]))

    @jsii.member(jsii_name="grantAttachVolumeByResourceTag")
    def grant_attach_volume_by_resource_tag(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        constructs: typing.List[constructs.Construct],
        tag_key_suffix: typing.Optional[builtins.str] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to attach the Volume by a ResourceTag condition.

        If you are looking to
        grant an Instance, AutoScalingGroup, EC2-Fleet, SpotFleet, ECS host, etc the ability to attach
        this volume to **itself** then this is the method you want to use.

        This is implemented by adding a Tag with key ``VolumeGrantAttach-<suffix>`` to the given
        constructs and this Volume, and then conditioning the Grant such that the grantee is only
        given the ability to AttachVolume if both the Volume and the destination Instance have that
        tag applied to them.

        :param grantee: -
        :param constructs: -
        :param tag_key_suffix: -
        '''
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantAttachVolumeByResourceTag", [grantee, constructs, tag_key_suffix]))

    @jsii.member(jsii_name="grantDetachVolume")
    def grant_detach_volume(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        instances: typing.Optional[typing.List[IInstance]] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to detach this Volume from an instance CAUTION: Granting an instance permission to detach from itself using this method will lead to an unresolvable circular reference between the instance role and the instance.

        Use {@link IVolume.grantDetachVolumeFromSelf} to grant an instance permission to detach this
        volume from itself.

        :param grantee: -
        :param instances: -
        '''
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantDetachVolume", [grantee, instances]))

    @jsii.member(jsii_name="grantDetachVolumeByResourceTag")
    def grant_detach_volume_by_resource_tag(
        self,
        grantee: aws_cdk.aws_iam.IGrantable,
        constructs: typing.List[constructs.Construct],
        tag_key_suffix: typing.Optional[builtins.str] = None,
    ) -> aws_cdk.aws_iam.Grant:
        '''Grants permission to detach the Volume by a ResourceTag condition.

        This is implemented via the same mechanism as {@link IVolume.grantAttachVolumeByResourceTag},
        and is subject to the same conditions.

        :param grantee: -
        :param constructs: -
        :param tag_key_suffix: -
        '''
        return typing.cast(aws_cdk.aws_iam.Grant, jsii.invoke(self, "grantDetachVolumeByResourceTag", [grantee, constructs, tag_key_suffix]))

    @jsii.member(jsii_name="validateProps")
    def _validate_props(
        self,
        *,
        availability_zone: builtins.str,
        auto_enable_io: typing.Optional[builtins.bool] = None,
        enable_multi_attach: typing.Optional[builtins.bool] = None,
        encrypted: typing.Optional[builtins.bool] = None,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
        iops: typing.Optional[jsii.Number] = None,
        removal_policy: typing.Optional[aws_cdk.core.RemovalPolicy] = None,
        size: typing.Optional[aws_cdk.core.Size] = None,
        snapshot_id: typing.Optional[builtins.str] = None,
        volume_name: typing.Optional[builtins.str] = None,
        volume_type: typing.Optional[EbsDeviceVolumeType] = None,
    ) -> None:
        '''
        :param availability_zone: The Availability Zone in which to create the volume.
        :param auto_enable_io: Indicates whether the volume is auto-enabled for I/O operations. By default, Amazon EBS disables I/O to the volume from attached EC2 instances when it determines that a volume's data is potentially inconsistent. If the consistency of the volume is not a concern, and you prefer that the volume be made available immediately if it's impaired, you can configure the volume to automatically enable I/O. Default: false
        :param enable_multi_attach: Indicates whether Amazon EBS Multi-Attach is enabled. See {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volumes-multi.html#considerations|Considerations and limitations} for the constraints of multi-attach. Default: false
        :param encrypted: Specifies whether the volume should be encrypted. The effect of setting the encryption state to true depends on the volume origin (new or from a snapshot), starting encryption state, ownership, and whether encryption by default is enabled. For more information, see {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default|Encryption by Default} in the Amazon Elastic Compute Cloud User Guide. Encrypted Amazon EBS volumes must be attached to instances that support Amazon EBS encryption. For more information, see {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#EBSEncryption_supported_instances|Supported Instance Types.} Default: false
        :param encryption_key: The customer-managed encryption key that is used to encrypt the Volume. The encrypted property must be true if this is provided. Note: If using an {@link aws-kms.IKey} created from a {@link aws-kms.Key.fromKeyArn()} here, then the KMS key **must** have the following in its Key policy; otherwise, the Volume will fail to create:: { "Effect": "Allow", "Principal": { "AWS": "<arn for your account-user> ex: arn:aws:iam::00000000000:root" }, "Resource": "*", "Action": [ "kms:DescribeKey", "kms:GenerateDataKeyWithoutPlainText", ], "Condition": { "StringEquals": { "kms:ViaService": "ec2.<Region>.amazonaws.com", (eg: ec2.us-east-1.amazonaws.com) "kms:CallerAccount": "0000000000" (your account ID) } } } Default: The default KMS key for the account, region, and EC2 service is used.
        :param iops: The number of I/O operations per second (IOPS) to provision for the volume. The maximum ratio is 50 IOPS/GiB for PROVISIONED_IOPS_SSD, and 500 IOPS/GiB for both PROVISIONED_IOPS_SSD_IO2 and GENERAL_PURPOSE_SSD_GP3. See {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html} for more information. This parameter is valid only for PROVISIONED_IOPS_SSD, PROVISIONED_IOPS_SSD_IO2 and GENERAL_PURPOSE_SSD_GP3 volumes. Default: None -- Required for io1 and io2 volumes. The default for gp3 volumes is 3,000 IOPS if omitted.
        :param removal_policy: Policy to apply when the volume is removed from the stack. Default: RemovalPolicy.RETAIN
        :param size: The size of the volume, in GiBs. You must specify either a snapshot ID or a volume size. See {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html} for details on the allowable size for each type of volume. Default: If you're creating the volume from a snapshot and don't specify a volume size, the default is the snapshot size.
        :param snapshot_id: The snapshot from which to create the volume. You must specify either a snapshot ID or a volume size. Default: The EBS volume is not created from a snapshot.
        :param volume_name: The value of the physicalName property of this resource. Default: The physical name will be allocated by CloudFormation at deployment time
        :param volume_type: The type of the volume; what type of storage to use to form the EBS Volume. Default: {@link EbsDeviceVolumeType.GENERAL_PURPOSE_SSD}
        '''
        props = VolumeProps(
            availability_zone=availability_zone,
            auto_enable_io=auto_enable_io,
            enable_multi_attach=enable_multi_attach,
            encrypted=encrypted,
            encryption_key=encryption_key,
            iops=iops,
            removal_policy=removal_policy,
            size=size,
            snapshot_id=snapshot_id,
            volume_name=volume_name,
            volume_type=volume_type,
        )

        return typing.cast(None, jsii.invoke(self, "validateProps", [props]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZone")
    def availability_zone(self) -> builtins.str:
        '''The availability zone that the EBS Volume is contained within (ex: us-west-2a).'''
        return typing.cast(builtins.str, jsii.get(self, "availabilityZone"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="volumeId")
    def volume_id(self) -> builtins.str:
        '''The EBS Volume's ID.'''
        return typing.cast(builtins.str, jsii.get(self, "volumeId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="encryptionKey")
    def encryption_key(self) -> typing.Optional[aws_cdk.aws_kms.IKey]:
        '''The customer-managed encryption key that is used to encrypt the Volume.'''
        return typing.cast(typing.Optional[aws_cdk.aws_kms.IKey], jsii.get(self, "encryptionKey"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.VolumeAttributes",
    jsii_struct_bases=[],
    name_mapping={
        "availability_zone": "availabilityZone",
        "volume_id": "volumeId",
        "encryption_key": "encryptionKey",
    },
)
class VolumeAttributes:
    def __init__(
        self,
        *,
        availability_zone: builtins.str,
        volume_id: builtins.str,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
    ) -> None:
        '''Attributes required to import an existing EBS Volume into the Stack.

        :param availability_zone: The availability zone that the EBS Volume is contained within (ex: us-west-2a).
        :param volume_id: The EBS Volume's ID.
        :param encryption_key: The customer-managed encryption key that is used to encrypt the Volume. Default: None -- The EBS Volume is not using a customer-managed KMS key for encryption.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "availability_zone": availability_zone,
            "volume_id": volume_id,
        }
        if encryption_key is not None:
            self._values["encryption_key"] = encryption_key

    @builtins.property
    def availability_zone(self) -> builtins.str:
        '''The availability zone that the EBS Volume is contained within (ex: us-west-2a).'''
        result = self._values.get("availability_zone")
        assert result is not None, "Required property 'availability_zone' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def volume_id(self) -> builtins.str:
        '''The EBS Volume's ID.'''
        result = self._values.get("volume_id")
        assert result is not None, "Required property 'volume_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def encryption_key(self) -> typing.Optional[aws_cdk.aws_kms.IKey]:
        '''The customer-managed encryption key that is used to encrypt the Volume.

        :default: None -- The EBS Volume is not using a customer-managed KMS key for encryption.
        '''
        result = self._values.get("encryption_key")
        return typing.cast(typing.Optional[aws_cdk.aws_kms.IKey], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VolumeAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.VolumeProps",
    jsii_struct_bases=[],
    name_mapping={
        "availability_zone": "availabilityZone",
        "auto_enable_io": "autoEnableIo",
        "enable_multi_attach": "enableMultiAttach",
        "encrypted": "encrypted",
        "encryption_key": "encryptionKey",
        "iops": "iops",
        "removal_policy": "removalPolicy",
        "size": "size",
        "snapshot_id": "snapshotId",
        "volume_name": "volumeName",
        "volume_type": "volumeType",
    },
)
class VolumeProps:
    def __init__(
        self,
        *,
        availability_zone: builtins.str,
        auto_enable_io: typing.Optional[builtins.bool] = None,
        enable_multi_attach: typing.Optional[builtins.bool] = None,
        encrypted: typing.Optional[builtins.bool] = None,
        encryption_key: typing.Optional[aws_cdk.aws_kms.IKey] = None,
        iops: typing.Optional[jsii.Number] = None,
        removal_policy: typing.Optional[aws_cdk.core.RemovalPolicy] = None,
        size: typing.Optional[aws_cdk.core.Size] = None,
        snapshot_id: typing.Optional[builtins.str] = None,
        volume_name: typing.Optional[builtins.str] = None,
        volume_type: typing.Optional[EbsDeviceVolumeType] = None,
    ) -> None:
        '''Properties of an EBS Volume.

        :param availability_zone: The Availability Zone in which to create the volume.
        :param auto_enable_io: Indicates whether the volume is auto-enabled for I/O operations. By default, Amazon EBS disables I/O to the volume from attached EC2 instances when it determines that a volume's data is potentially inconsistent. If the consistency of the volume is not a concern, and you prefer that the volume be made available immediately if it's impaired, you can configure the volume to automatically enable I/O. Default: false
        :param enable_multi_attach: Indicates whether Amazon EBS Multi-Attach is enabled. See {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volumes-multi.html#considerations|Considerations and limitations} for the constraints of multi-attach. Default: false
        :param encrypted: Specifies whether the volume should be encrypted. The effect of setting the encryption state to true depends on the volume origin (new or from a snapshot), starting encryption state, ownership, and whether encryption by default is enabled. For more information, see {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default|Encryption by Default} in the Amazon Elastic Compute Cloud User Guide. Encrypted Amazon EBS volumes must be attached to instances that support Amazon EBS encryption. For more information, see {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#EBSEncryption_supported_instances|Supported Instance Types.} Default: false
        :param encryption_key: The customer-managed encryption key that is used to encrypt the Volume. The encrypted property must be true if this is provided. Note: If using an {@link aws-kms.IKey} created from a {@link aws-kms.Key.fromKeyArn()} here, then the KMS key **must** have the following in its Key policy; otherwise, the Volume will fail to create:: { "Effect": "Allow", "Principal": { "AWS": "<arn for your account-user> ex: arn:aws:iam::00000000000:root" }, "Resource": "*", "Action": [ "kms:DescribeKey", "kms:GenerateDataKeyWithoutPlainText", ], "Condition": { "StringEquals": { "kms:ViaService": "ec2.<Region>.amazonaws.com", (eg: ec2.us-east-1.amazonaws.com) "kms:CallerAccount": "0000000000" (your account ID) } } } Default: The default KMS key for the account, region, and EC2 service is used.
        :param iops: The number of I/O operations per second (IOPS) to provision for the volume. The maximum ratio is 50 IOPS/GiB for PROVISIONED_IOPS_SSD, and 500 IOPS/GiB for both PROVISIONED_IOPS_SSD_IO2 and GENERAL_PURPOSE_SSD_GP3. See {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html} for more information. This parameter is valid only for PROVISIONED_IOPS_SSD, PROVISIONED_IOPS_SSD_IO2 and GENERAL_PURPOSE_SSD_GP3 volumes. Default: None -- Required for io1 and io2 volumes. The default for gp3 volumes is 3,000 IOPS if omitted.
        :param removal_policy: Policy to apply when the volume is removed from the stack. Default: RemovalPolicy.RETAIN
        :param size: The size of the volume, in GiBs. You must specify either a snapshot ID or a volume size. See {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html} for details on the allowable size for each type of volume. Default: If you're creating the volume from a snapshot and don't specify a volume size, the default is the snapshot size.
        :param snapshot_id: The snapshot from which to create the volume. You must specify either a snapshot ID or a volume size. Default: The EBS volume is not created from a snapshot.
        :param volume_name: The value of the physicalName property of this resource. Default: The physical name will be allocated by CloudFormation at deployment time
        :param volume_type: The type of the volume; what type of storage to use to form the EBS Volume. Default: {@link EbsDeviceVolumeType.GENERAL_PURPOSE_SSD}
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "availability_zone": availability_zone,
        }
        if auto_enable_io is not None:
            self._values["auto_enable_io"] = auto_enable_io
        if enable_multi_attach is not None:
            self._values["enable_multi_attach"] = enable_multi_attach
        if encrypted is not None:
            self._values["encrypted"] = encrypted
        if encryption_key is not None:
            self._values["encryption_key"] = encryption_key
        if iops is not None:
            self._values["iops"] = iops
        if removal_policy is not None:
            self._values["removal_policy"] = removal_policy
        if size is not None:
            self._values["size"] = size
        if snapshot_id is not None:
            self._values["snapshot_id"] = snapshot_id
        if volume_name is not None:
            self._values["volume_name"] = volume_name
        if volume_type is not None:
            self._values["volume_type"] = volume_type

    @builtins.property
    def availability_zone(self) -> builtins.str:
        '''The Availability Zone in which to create the volume.'''
        result = self._values.get("availability_zone")
        assert result is not None, "Required property 'availability_zone' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def auto_enable_io(self) -> typing.Optional[builtins.bool]:
        '''Indicates whether the volume is auto-enabled for I/O operations.

        By default, Amazon EBS disables I/O to the volume from attached EC2
        instances when it determines that a volume's data is potentially inconsistent. If the consistency of the volume is not a concern, and
        you prefer that the volume be made available immediately if it's impaired, you can configure the volume to automatically enable I/O.

        :default: false
        '''
        result = self._values.get("auto_enable_io")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def enable_multi_attach(self) -> typing.Optional[builtins.bool]:
        '''Indicates whether Amazon EBS Multi-Attach is enabled.

        See {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-volumes-multi.html#considerations|Considerations and limitations}
        for the constraints of multi-attach.

        :default: false
        '''
        result = self._values.get("enable_multi_attach")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def encrypted(self) -> typing.Optional[builtins.bool]:
        '''Specifies whether the volume should be encrypted.

        The effect of setting the encryption state to true depends on the volume origin
        (new or from a snapshot), starting encryption state, ownership, and whether encryption by default is enabled. For more information,
        see {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#encryption-by-default|Encryption by Default}
        in the Amazon Elastic Compute Cloud User Guide.

        Encrypted Amazon EBS volumes must be attached to instances that support Amazon EBS encryption. For more information, see
        {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#EBSEncryption_supported_instances|Supported Instance Types.}

        :default: false
        '''
        result = self._values.get("encrypted")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def encryption_key(self) -> typing.Optional[aws_cdk.aws_kms.IKey]:
        '''The customer-managed encryption key that is used to encrypt the Volume.

        The encrypted property must
        be true if this is provided.

        Note: If using an {@link aws-kms.IKey} created from a {@link aws-kms.Key.fromKeyArn()} here,
        then the KMS key **must** have the following in its Key policy; otherwise, the Volume
        will fail to create::

            {
              "Effect": "Allow",
              "Principal": { "AWS": "<arn for your account-user> ex: arn:aws:iam::00000000000:root" },
              "Resource": "*",
              "Action": [
                "kms:DescribeKey",
                "kms:GenerateDataKeyWithoutPlainText",
              ],
              "Condition": {
                "StringEquals": {
                  "kms:ViaService": "ec2.<Region>.amazonaws.com", (eg: ec2.us-east-1.amazonaws.com)
                  "kms:CallerAccount": "0000000000" (your account ID)
                }
              }
            }

        :default: The default KMS key for the account, region, and EC2 service is used.
        '''
        result = self._values.get("encryption_key")
        return typing.cast(typing.Optional[aws_cdk.aws_kms.IKey], result)

    @builtins.property
    def iops(self) -> typing.Optional[jsii.Number]:
        '''The number of I/O operations per second (IOPS) to provision for the volume.

        The maximum ratio is 50 IOPS/GiB for PROVISIONED_IOPS_SSD,
        and 500 IOPS/GiB for both PROVISIONED_IOPS_SSD_IO2 and GENERAL_PURPOSE_SSD_GP3.
        See {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html}
        for more information.

        This parameter is valid only for PROVISIONED_IOPS_SSD, PROVISIONED_IOPS_SSD_IO2 and GENERAL_PURPOSE_SSD_GP3 volumes.

        :default: None -- Required for io1 and io2 volumes. The default for gp3 volumes is 3,000 IOPS if omitted.
        '''
        result = self._values.get("iops")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def removal_policy(self) -> typing.Optional[aws_cdk.core.RemovalPolicy]:
        '''Policy to apply when the volume is removed from the stack.

        :default: RemovalPolicy.RETAIN
        '''
        result = self._values.get("removal_policy")
        return typing.cast(typing.Optional[aws_cdk.core.RemovalPolicy], result)

    @builtins.property
    def size(self) -> typing.Optional[aws_cdk.core.Size]:
        '''The size of the volume, in GiBs.

        You must specify either a snapshot ID or a volume size.
        See {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ebs-volume.html}
        for details on the allowable size for each type of volume.

        :default: If you're creating the volume from a snapshot and don't specify a volume size, the default is the snapshot size.
        '''
        result = self._values.get("size")
        return typing.cast(typing.Optional[aws_cdk.core.Size], result)

    @builtins.property
    def snapshot_id(self) -> typing.Optional[builtins.str]:
        '''The snapshot from which to create the volume.

        You must specify either a snapshot ID or a volume size.

        :default: The EBS volume is not created from a snapshot.
        '''
        result = self._values.get("snapshot_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def volume_name(self) -> typing.Optional[builtins.str]:
        '''The value of the physicalName property of this resource.

        :default: The physical name will be allocated by CloudFormation at deployment time
        '''
        result = self._values.get("volume_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def volume_type(self) -> typing.Optional[EbsDeviceVolumeType]:
        '''The type of the volume;

        what type of storage to use to form the EBS Volume.

        :default: {@link EbsDeviceVolumeType.GENERAL_PURPOSE_SSD}
        '''
        result = self._values.get("volume_type")
        return typing.cast(typing.Optional[EbsDeviceVolumeType], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VolumeProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IVpc)
class Vpc(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.Vpc",
):
    '''Define an AWS Virtual Private Cloud.

    See the package-level documentation of this package for an overview
    of the various dimensions in which you can configure your VPC.

    For example::

       # Example automatically generated. See https://github.com/aws/jsii/issues/826
       vpc = ec2.Vpc(self, "TheVPC",
           cidr="10.0.0.0/16"
       )

       # Iterate the private subnets
       selection = vpc.select_subnets(
           subnet_type=ec2.SubnetType.PRIVATE
       )

       for subnet in selection.subnets:
           pass

    :resource: AWS::EC2::VPC
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        cidr: typing.Optional[builtins.str] = None,
        default_instance_tenancy: typing.Optional[DefaultInstanceTenancy] = None,
        enable_dns_hostnames: typing.Optional[builtins.bool] = None,
        enable_dns_support: typing.Optional[builtins.bool] = None,
        flow_logs: typing.Optional[typing.Mapping[builtins.str, FlowLogOptions]] = None,
        gateway_endpoints: typing.Optional[typing.Mapping[builtins.str, GatewayVpcEndpointOptions]] = None,
        max_azs: typing.Optional[jsii.Number] = None,
        nat_gateway_provider: typing.Optional[NatProvider] = None,
        nat_gateways: typing.Optional[jsii.Number] = None,
        nat_gateway_subnets: typing.Optional[SubnetSelection] = None,
        subnet_configuration: typing.Optional[typing.List[SubnetConfiguration]] = None,
        vpn_connections: typing.Optional[typing.Mapping[builtins.str, "VpnConnectionOptions"]] = None,
        vpn_gateway: typing.Optional[builtins.bool] = None,
        vpn_gateway_asn: typing.Optional[jsii.Number] = None,
        vpn_route_propagation: typing.Optional[typing.List[SubnetSelection]] = None,
    ) -> None:
        '''Vpc creates a VPC that spans a whole region.

        It will automatically divide the provided VPC CIDR range, and create public and private subnets per Availability Zone.
        Network routing for the public subnets will be configured to allow outbound access directly via an Internet Gateway.
        Network routing for the private subnets will be configured to allow outbound access via a set of resilient NAT Gateways (one per AZ).

        :param scope: -
        :param id: -
        :param cidr: The CIDR range to use for the VPC, e.g. '10.0.0.0/16'. Should be a minimum of /28 and maximum size of /16. The range will be split across all subnets per Availability Zone. Default: Vpc.DEFAULT_CIDR_RANGE
        :param default_instance_tenancy: The default tenancy of instances launched into the VPC. By setting this to dedicated tenancy, instances will be launched on hardware dedicated to a single AWS customer, unless specifically specified at instance launch time. Please note, not all instance types are usable with Dedicated tenancy. Default: DefaultInstanceTenancy.Default (shared) tenancy
        :param enable_dns_hostnames: Indicates whether the instances launched in the VPC get public DNS hostnames. If this attribute is true, instances in the VPC get public DNS hostnames, but only if the enableDnsSupport attribute is also set to true. Default: true
        :param enable_dns_support: Indicates whether the DNS resolution is supported for the VPC. If this attribute is false, the Amazon-provided DNS server in the VPC that resolves public DNS hostnames to IP addresses is not enabled. If this attribute is true, queries to the Amazon provided DNS server at the 169.254.169.253 IP address, or the reserved IP address at the base of the VPC IPv4 network range plus two will succeed. Default: true
        :param flow_logs: Flow logs to add to this VPC. Default: - No flow logs.
        :param gateway_endpoints: Gateway endpoints to add to this VPC. Default: - None.
        :param max_azs: Define the maximum number of AZs to use in this region. If the region has more AZs than you want to use (for example, because of EIP limits), pick a lower number here. The AZs will be sorted and picked from the start of the list. If you pick a higher number than the number of AZs in the region, all AZs in the region will be selected. To use "all AZs" available to your account, use a high number (such as 99). Be aware that environment-agnostic stacks will be created with access to only 2 AZs, so to use more than 2 AZs, be sure to specify the account and region on your stack. Default: 3
        :param nat_gateway_provider: (experimental) What type of NAT provider to use. Select between NAT gateways or NAT instances. NAT gateways may not be available in all AWS regions. Default: NatProvider.gateway()
        :param nat_gateways: The number of NAT Gateways/Instances to create. The type of NAT gateway or instance will be determined by the ``natGatewayProvider`` parameter. You can set this number lower than the number of Availability Zones in your VPC in order to save on NAT cost. Be aware you may be charged for cross-AZ data traffic instead. Default: - One NAT gateway/instance per Availability Zone
        :param nat_gateway_subnets: Configures the subnets which will have NAT Gateways/Instances. You can pick a specific group of subnets by specifying the group name; the picked subnets must be public subnets. Only necessary if you have more than one public subnet group. Default: - All public subnets.
        :param subnet_configuration: Configure the subnets to build for each AZ. Each entry in this list configures a Subnet Group; each group will contain a subnet for each Availability Zone. For example, if you want 1 public subnet, 1 private subnet, and 1 isolated subnet in each AZ provide the following:: new ec2.Vpc(this, 'VPC', { subnetConfiguration: [ { cidrMask: 24, name: 'ingress', subnetType: ec2.SubnetType.PUBLIC, }, { cidrMask: 24, name: 'application', subnetType: ec2.SubnetType.PRIVATE, }, { cidrMask: 28, name: 'rds', subnetType: ec2.SubnetType.ISOLATED, } ] }); Default: - The VPC CIDR will be evenly divided between 1 public and 1 private subnet per AZ.
        :param vpn_connections: VPN connections to this VPC. Default: - No connections.
        :param vpn_gateway: Indicates whether a VPN gateway should be created and attached to this VPC. Default: - true when vpnGatewayAsn or vpnConnections is specified
        :param vpn_gateway_asn: The private Autonomous System Number (ASN) for the VPN gateway. Default: - Amazon default ASN.
        :param vpn_route_propagation: Where to propagate VPN routes. Default: - On the route tables associated with private subnets. If no private subnets exists, isolated subnets are used. If no isolated subnets exists, public subnets are used.
        '''
        props = VpcProps(
            cidr=cidr,
            default_instance_tenancy=default_instance_tenancy,
            enable_dns_hostnames=enable_dns_hostnames,
            enable_dns_support=enable_dns_support,
            flow_logs=flow_logs,
            gateway_endpoints=gateway_endpoints,
            max_azs=max_azs,
            nat_gateway_provider=nat_gateway_provider,
            nat_gateways=nat_gateways,
            nat_gateway_subnets=nat_gateway_subnets,
            subnet_configuration=subnet_configuration,
            vpn_connections=vpn_connections,
            vpn_gateway=vpn_gateway,
            vpn_gateway_asn=vpn_gateway_asn,
            vpn_route_propagation=vpn_route_propagation,
        )

        jsii.create(Vpc, self, [scope, id, props])

    @jsii.member(jsii_name="fromLookup") # type: ignore[misc]
    @builtins.classmethod
    def from_lookup(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        is_default: typing.Optional[builtins.bool] = None,
        subnet_group_name_tag: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        vpc_id: typing.Optional[builtins.str] = None,
        vpc_name: typing.Optional[builtins.str] = None,
    ) -> IVpc:
        '''Import an existing VPC from by querying the AWS environment this stack is deployed to.

        This function only needs to be used to use VPCs not defined in your CDK
        application. If you are looking to share a VPC between stacks, you can
        pass the ``Vpc`` object between stacks and use it as normal.

        Calling this method will lead to a lookup when the CDK CLI is executed.
        You can therefore not use any values that will only be available at
        CloudFormation execution time (i.e., Tokens).

        The VPC information will be cached in ``cdk.context.json`` and the same VPC
        will be used on future runs. To refresh the lookup, you will have to
        evict the value from the cache using the ``cdk context`` command. See
        https://docs.aws.amazon.com/cdk/latest/guide/context.html for more information.

        :param scope: -
        :param id: -
        :param is_default: Whether to match the default VPC. Default: Don't care whether we return the default VPC
        :param subnet_group_name_tag: Optional tag for subnet group name. If not provided, we'll look at the aws-cdk:subnet-name tag. If the subnet does not have the specified tag, we'll use its type as the name. Default: aws-cdk:subnet-name
        :param tags: Tags on the VPC. The VPC must have all of these tags Default: Don't filter on tags
        :param vpc_id: The ID of the VPC. If given, will import exactly this VPC. Default: Don't filter on vpcId
        :param vpc_name: The name of the VPC. If given, will import the VPC with this name. Default: Don't filter on vpcName
        '''
        options = VpcLookupOptions(
            is_default=is_default,
            subnet_group_name_tag=subnet_group_name_tag,
            tags=tags,
            vpc_id=vpc_id,
            vpc_name=vpc_name,
        )

        return typing.cast(IVpc, jsii.sinvoke(cls, "fromLookup", [scope, id, options]))

    @jsii.member(jsii_name="fromVpcAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_vpc_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        availability_zones: typing.List[builtins.str],
        vpc_id: builtins.str,
        isolated_subnet_ids: typing.Optional[typing.List[builtins.str]] = None,
        isolated_subnet_names: typing.Optional[typing.List[builtins.str]] = None,
        isolated_subnet_route_table_ids: typing.Optional[typing.List[builtins.str]] = None,
        private_subnet_ids: typing.Optional[typing.List[builtins.str]] = None,
        private_subnet_names: typing.Optional[typing.List[builtins.str]] = None,
        private_subnet_route_table_ids: typing.Optional[typing.List[builtins.str]] = None,
        public_subnet_ids: typing.Optional[typing.List[builtins.str]] = None,
        public_subnet_names: typing.Optional[typing.List[builtins.str]] = None,
        public_subnet_route_table_ids: typing.Optional[typing.List[builtins.str]] = None,
        vpc_cidr_block: typing.Optional[builtins.str] = None,
        vpn_gateway_id: typing.Optional[builtins.str] = None,
    ) -> IVpc:
        '''Import a VPC by supplying all attributes directly.

        NOTE: using ``fromVpcAttributes()`` with deploy-time parameters (like a ``Fn.importValue()`` or
        ``CfnParameter`` to represent a list of subnet IDs) sometimes accidentally works. It happens
        to work for constructs that need a list of subnets (like ``AutoScalingGroup`` and ``eks.Cluster``)
        but it does not work for constructs that need individual subnets (like
        ``Instance``). See https://github.com/aws/aws-cdk/issues/4118 for more
        information.

        Prefer to use ``Vpc.fromLookup()`` instead.

        :param scope: -
        :param id: -
        :param availability_zones: List of availability zones for the subnets in this VPC.
        :param vpc_id: VPC's identifier.
        :param isolated_subnet_ids: List of isolated subnet IDs. Must be undefined or match the availability zones in length and order.
        :param isolated_subnet_names: List of names for the isolated subnets. Must be undefined or have a name for every isolated subnet group.
        :param isolated_subnet_route_table_ids: List of IDs of routing tables for the isolated subnets. Must be undefined or have a name for every isolated subnet group.
        :param private_subnet_ids: List of private subnet IDs. Must be undefined or match the availability zones in length and order.
        :param private_subnet_names: List of names for the private subnets. Must be undefined or have a name for every private subnet group.
        :param private_subnet_route_table_ids: List of IDs of routing tables for the private subnets. Must be undefined or have a name for every private subnet group.
        :param public_subnet_ids: List of public subnet IDs. Must be undefined or match the availability zones in length and order.
        :param public_subnet_names: List of names for the public subnets. Must be undefined or have a name for every public subnet group.
        :param public_subnet_route_table_ids: List of IDs of routing tables for the public subnets. Must be undefined or have a name for every public subnet group.
        :param vpc_cidr_block: VPC's CIDR range. Default: - Retrieving the CIDR from the VPC will fail
        :param vpn_gateway_id: VPN gateway's identifier.
        '''
        attrs = VpcAttributes(
            availability_zones=availability_zones,
            vpc_id=vpc_id,
            isolated_subnet_ids=isolated_subnet_ids,
            isolated_subnet_names=isolated_subnet_names,
            isolated_subnet_route_table_ids=isolated_subnet_route_table_ids,
            private_subnet_ids=private_subnet_ids,
            private_subnet_names=private_subnet_names,
            private_subnet_route_table_ids=private_subnet_route_table_ids,
            public_subnet_ids=public_subnet_ids,
            public_subnet_names=public_subnet_names,
            public_subnet_route_table_ids=public_subnet_route_table_ids,
            vpc_cidr_block=vpc_cidr_block,
            vpn_gateway_id=vpn_gateway_id,
        )

        return typing.cast(IVpc, jsii.sinvoke(cls, "fromVpcAttributes", [scope, id, attrs]))

    @jsii.member(jsii_name="addDynamoDbEndpoint")
    def add_dynamo_db_endpoint(
        self,
        id: builtins.str,
        subnets: typing.Optional[typing.List[SubnetSelection]] = None,
    ) -> "GatewayVpcEndpoint":
        '''(deprecated) Adds a new DynamoDB gateway endpoint to this VPC.

        :param id: -
        :param subnets: -

        :deprecated: use ``addGatewayEndpoint()`` instead

        :stability: deprecated
        '''
        return typing.cast("GatewayVpcEndpoint", jsii.invoke(self, "addDynamoDbEndpoint", [id, subnets]))

    @jsii.member(jsii_name="addFlowLog")
    def add_flow_log(
        self,
        id: builtins.str,
        *,
        destination: typing.Optional[FlowLogDestination] = None,
        traffic_type: typing.Optional[FlowLogTrafficType] = None,
    ) -> "FlowLog":
        '''Adds a new flow log to this VPC.

        :param id: -
        :param destination: (experimental) Specifies the type of destination to which the flow log data is to be published. Flow log data can be published to CloudWatch Logs or Amazon S3 Default: FlowLogDestinationType.toCloudWatchLogs()
        :param traffic_type: (experimental) The type of traffic to log. You can log traffic that the resource accepts or rejects, or all traffic. Default: ALL
        '''
        options = FlowLogOptions(destination=destination, traffic_type=traffic_type)

        return typing.cast("FlowLog", jsii.invoke(self, "addFlowLog", [id, options]))

    @jsii.member(jsii_name="addGatewayEndpoint")
    def add_gateway_endpoint(
        self,
        id: builtins.str,
        *,
        service: IGatewayVpcEndpointService,
        subnets: typing.Optional[typing.List[SubnetSelection]] = None,
    ) -> "GatewayVpcEndpoint":
        '''Adds a new gateway endpoint to this VPC.

        :param id: -
        :param service: The service to use for this gateway VPC endpoint.
        :param subnets: Where to add endpoint routing. By default, this endpoint will be routable from all subnets in the VPC. Specify a list of subnet selection objects here to be more specific. Default: - All subnets in the VPC
        '''
        options = GatewayVpcEndpointOptions(service=service, subnets=subnets)

        return typing.cast("GatewayVpcEndpoint", jsii.invoke(self, "addGatewayEndpoint", [id, options]))

    @jsii.member(jsii_name="addInterfaceEndpoint")
    def add_interface_endpoint(
        self,
        id: builtins.str,
        *,
        service: IInterfaceVpcEndpointService,
        lookup_supported_azs: typing.Optional[builtins.bool] = None,
        open: typing.Optional[builtins.bool] = None,
        private_dns_enabled: typing.Optional[builtins.bool] = None,
        security_groups: typing.Optional[typing.List[ISecurityGroup]] = None,
        subnets: typing.Optional[SubnetSelection] = None,
    ) -> "InterfaceVpcEndpoint":
        '''Adds a new interface endpoint to this VPC.

        :param id: -
        :param service: The service to use for this interface VPC endpoint.
        :param lookup_supported_azs: Limit to only those availability zones where the endpoint service can be created. Setting this to 'true' requires a lookup to be performed at synthesis time. Account and region must be set on the containing stack for this to work. Default: false
        :param open: Whether to automatically allow VPC traffic to the endpoint. If enabled, all traffic to the endpoint from within the VPC will be automatically allowed. This is done based on the VPC's CIDR range. Default: true
        :param private_dns_enabled: Whether to associate a private hosted zone with the specified VPC. This allows you to make requests to the service using its default DNS hostname. Default: set by the instance of IInterfaceVpcEndpointService, or true if not defined by the instance of IInterfaceVpcEndpointService
        :param security_groups: The security groups to associate with this interface VPC endpoint. Default: - a new security group is created
        :param subnets: The subnets in which to create an endpoint network interface. At most one per availability zone. Default: - private subnets
        '''
        options = InterfaceVpcEndpointOptions(
            service=service,
            lookup_supported_azs=lookup_supported_azs,
            open=open,
            private_dns_enabled=private_dns_enabled,
            security_groups=security_groups,
            subnets=subnets,
        )

        return typing.cast("InterfaceVpcEndpoint", jsii.invoke(self, "addInterfaceEndpoint", [id, options]))

    @jsii.member(jsii_name="addS3Endpoint")
    def add_s3_endpoint(
        self,
        id: builtins.str,
        subnets: typing.Optional[typing.List[SubnetSelection]] = None,
    ) -> "GatewayVpcEndpoint":
        '''(deprecated) Adds a new S3 gateway endpoint to this VPC.

        :param id: -
        :param subnets: -

        :deprecated: use ``addGatewayEndpoint()`` instead

        :stability: deprecated
        '''
        return typing.cast("GatewayVpcEndpoint", jsii.invoke(self, "addS3Endpoint", [id, subnets]))

    @jsii.member(jsii_name="addVpnConnection")
    def add_vpn_connection(
        self,
        id: builtins.str,
        *,
        ip: builtins.str,
        asn: typing.Optional[jsii.Number] = None,
        static_routes: typing.Optional[typing.List[builtins.str]] = None,
        tunnel_options: typing.Optional[typing.List["VpnTunnelOption"]] = None,
    ) -> "VpnConnection":
        '''Adds a new VPN connection to this VPC.

        :param id: -
        :param ip: The ip address of the customer gateway.
        :param asn: The ASN of the customer gateway. Default: 65000
        :param static_routes: The static routes to be routed from the VPN gateway to the customer gateway. Default: Dynamic routing (BGP)
        :param tunnel_options: The tunnel options for the VPN connection. At most two elements (one per tunnel). Duplicates not allowed. Default: Amazon generated tunnel options
        '''
        options = VpnConnectionOptions(
            ip=ip, asn=asn, static_routes=static_routes, tunnel_options=tunnel_options
        )

        return typing.cast("VpnConnection", jsii.invoke(self, "addVpnConnection", [id, options]))

    @jsii.member(jsii_name="enableVpnGateway")
    def enable_vpn_gateway(
        self,
        *,
        vpn_route_propagation: typing.Optional[typing.List[SubnetSelection]] = None,
        type: builtins.str,
        amazon_side_asn: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''Adds a VPN Gateway to this VPC.

        :param vpn_route_propagation: Provide an array of subnets where the route propagation should be added. Default: noPropagation
        :param type: Default type ipsec.1.
        :param amazon_side_asn: Explicitly specify an Asn or let aws pick an Asn for you. Default: 65000
        '''
        options = EnableVpnGatewayOptions(
            vpn_route_propagation=vpn_route_propagation,
            type=type,
            amazon_side_asn=amazon_side_asn,
        )

        return typing.cast(None, jsii.invoke(self, "enableVpnGateway", [options]))

    @jsii.member(jsii_name="selectSubnetObjects")
    def _select_subnet_objects(
        self,
        *,
        availability_zones: typing.Optional[typing.List[builtins.str]] = None,
        one_per_az: typing.Optional[builtins.bool] = None,
        subnet_filters: typing.Optional[typing.List[SubnetFilter]] = None,
        subnet_group_name: typing.Optional[builtins.str] = None,
        subnet_name: typing.Optional[builtins.str] = None,
        subnets: typing.Optional[typing.List[ISubnet]] = None,
        subnet_type: typing.Optional[SubnetType] = None,
    ) -> typing.List[ISubnet]:
        '''Return the subnets appropriate for the placement strategy.

        :param availability_zones: Select subnets only in the given AZs. Default: no filtering on AZs is done
        :param one_per_az: If true, return at most one subnet per AZ. Default: false
        :param subnet_filters: List of provided subnet filters. Default: - none
        :param subnet_group_name: Select the subnet group with the given name. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them. Otherwise, prefer ``subnetType``. This field does not select individual subnets, it selects all subnets that share the given subnet group name. This is the name supplied in ``subnetConfiguration``. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: - Selection by type instead of by name
        :param subnet_name: (deprecated) Alias for ``subnetGroupName``. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them.
        :param subnets: Explicitly select individual subnets. Use this if you don't want to automatically use all subnets in a group, but have a need to control selection down to individual subnets. Cannot be specified together with ``subnetType`` or ``subnetGroupName``. Default: - Use all subnets in a selected group (all private subnets by default)
        :param subnet_type: Select all subnets of the given type. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: SubnetType.PRIVATE (or ISOLATED or PUBLIC if there are no PRIVATE subnets)
        '''
        selection = SubnetSelection(
            availability_zones=availability_zones,
            one_per_az=one_per_az,
            subnet_filters=subnet_filters,
            subnet_group_name=subnet_group_name,
            subnet_name=subnet_name,
            subnets=subnets,
            subnet_type=subnet_type,
        )

        return typing.cast(typing.List[ISubnet], jsii.invoke(self, "selectSubnetObjects", [selection]))

    @jsii.member(jsii_name="selectSubnets")
    def select_subnets(
        self,
        *,
        availability_zones: typing.Optional[typing.List[builtins.str]] = None,
        one_per_az: typing.Optional[builtins.bool] = None,
        subnet_filters: typing.Optional[typing.List[SubnetFilter]] = None,
        subnet_group_name: typing.Optional[builtins.str] = None,
        subnet_name: typing.Optional[builtins.str] = None,
        subnets: typing.Optional[typing.List[ISubnet]] = None,
        subnet_type: typing.Optional[SubnetType] = None,
    ) -> SelectedSubnets:
        '''Returns IDs of selected subnets.

        :param availability_zones: Select subnets only in the given AZs. Default: no filtering on AZs is done
        :param one_per_az: If true, return at most one subnet per AZ. Default: false
        :param subnet_filters: List of provided subnet filters. Default: - none
        :param subnet_group_name: Select the subnet group with the given name. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them. Otherwise, prefer ``subnetType``. This field does not select individual subnets, it selects all subnets that share the given subnet group name. This is the name supplied in ``subnetConfiguration``. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: - Selection by type instead of by name
        :param subnet_name: (deprecated) Alias for ``subnetGroupName``. Select the subnet group with the given name. This only needs to be used if you have multiple subnet groups of the same type and you need to distinguish between them.
        :param subnets: Explicitly select individual subnets. Use this if you don't want to automatically use all subnets in a group, but have a need to control selection down to individual subnets. Cannot be specified together with ``subnetType`` or ``subnetGroupName``. Default: - Use all subnets in a selected group (all private subnets by default)
        :param subnet_type: Select all subnets of the given type. At most one of ``subnetType`` and ``subnetGroupName`` can be supplied. Default: SubnetType.PRIVATE (or ISOLATED or PUBLIC if there are no PRIVATE subnets)
        '''
        selection = SubnetSelection(
            availability_zones=availability_zones,
            one_per_az=one_per_az,
            subnet_filters=subnet_filters,
            subnet_group_name=subnet_group_name,
            subnet_name=subnet_name,
            subnets=subnets,
            subnet_type=subnet_type,
        )

        return typing.cast(SelectedSubnets, jsii.invoke(self, "selectSubnets", [selection]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="DEFAULT_CIDR_RANGE")
    def DEFAULT_CIDR_RANGE(cls) -> builtins.str:
        '''The default CIDR range used when creating VPCs.

        This can be overridden using VpcProps when creating a VPCNetwork resource.
        e.g. new VpcResource(this, { cidr: '192.168.0.0./16' })
        '''
        return typing.cast(builtins.str, jsii.sget(cls, "DEFAULT_CIDR_RANGE"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="DEFAULT_SUBNETS")
    def DEFAULT_SUBNETS(cls) -> typing.List[SubnetConfiguration]:
        '''The default subnet configuration.

        1 Public and 1 Private subnet per AZ evenly split
        '''
        return typing.cast(typing.List[SubnetConfiguration], jsii.sget(cls, "DEFAULT_SUBNETS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="DEFAULT_SUBNETS_NO_NAT")
    def DEFAULT_SUBNETS_NO_NAT(cls) -> typing.List[SubnetConfiguration]:
        '''The default subnet configuration if natGateways specified to be 0.

        1 Public and 1 Isolated Subnet per AZ evenly split
        '''
        return typing.cast(typing.List[SubnetConfiguration], jsii.sget(cls, "DEFAULT_SUBNETS_NO_NAT"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="availabilityZones")
    def availability_zones(self) -> typing.List[builtins.str]:
        '''AZs for this VPC.'''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "availabilityZones"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="dnsHostnamesEnabled")
    def dns_hostnames_enabled(self) -> builtins.bool:
        '''Indicates if instances launched in this VPC will have public DNS hostnames.'''
        return typing.cast(builtins.bool, jsii.get(self, "dnsHostnamesEnabled"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="dnsSupportEnabled")
    def dns_support_enabled(self) -> builtins.bool:
        '''Indicates if DNS support is enabled for this VPC.'''
        return typing.cast(builtins.bool, jsii.get(self, "dnsSupportEnabled"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="internetConnectivityEstablished")
    def internet_connectivity_established(self) -> aws_cdk.core.IDependable:
        '''Dependencies for internet connectivity.'''
        return typing.cast(aws_cdk.core.IDependable, jsii.get(self, "internetConnectivityEstablished"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="isolatedSubnets")
    def isolated_subnets(self) -> typing.List[ISubnet]:
        '''List of isolated subnets in this VPC.'''
        return typing.cast(typing.List[ISubnet], jsii.get(self, "isolatedSubnets"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="natDependencies")
    def _nat_dependencies(self) -> typing.List[aws_cdk.core.IConstruct]:
        '''(deprecated) Dependencies for NAT connectivity.

        :deprecated: - This value is no longer used.

        :stability: deprecated
        '''
        return typing.cast(typing.List[aws_cdk.core.IConstruct], jsii.get(self, "natDependencies"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="privateSubnets")
    def private_subnets(self) -> typing.List[ISubnet]:
        '''List of private subnets in this VPC.'''
        return typing.cast(typing.List[ISubnet], jsii.get(self, "privateSubnets"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="publicSubnets")
    def public_subnets(self) -> typing.List[ISubnet]:
        '''List of public subnets in this VPC.'''
        return typing.cast(typing.List[ISubnet], jsii.get(self, "publicSubnets"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcCidrBlock")
    def vpc_cidr_block(self) -> builtins.str:
        '''CIDR range for this VPC.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcCidrBlock"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcCidrBlockAssociations")
    def vpc_cidr_block_associations(self) -> typing.List[builtins.str]:
        '''
        :attribute: true
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "vpcCidrBlockAssociations"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcDefaultNetworkAcl")
    def vpc_default_network_acl(self) -> builtins.str:
        '''
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcDefaultNetworkAcl"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcDefaultSecurityGroup")
    def vpc_default_security_group(self) -> builtins.str:
        '''
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcDefaultSecurityGroup"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcId")
    def vpc_id(self) -> builtins.str:
        '''Identifier for this VPC.'''
        return typing.cast(builtins.str, jsii.get(self, "vpcId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcIpv6CidrBlocks")
    def vpc_ipv6_cidr_blocks(self) -> typing.List[builtins.str]:
        '''
        :attribute: true
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "vpcIpv6CidrBlocks"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="internetGatewayId")
    def internet_gateway_id(self) -> typing.Optional[builtins.str]:
        '''Internet Gateway for the VPC.

        Note that in case the VPC is configured only
        with ISOLATED subnets, this attribute will be ``undefined``.
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "internetGatewayId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnGatewayId")
    def vpn_gateway_id(self) -> typing.Optional[builtins.str]:
        '''Returns the id of the VPN Gateway (if enabled).'''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "vpnGatewayId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="incompleteSubnetDefinition")
    def _incomplete_subnet_definition(self) -> builtins.bool:
        '''If this is set to true, don't error out on trying to select subnets.'''
        return typing.cast(builtins.bool, jsii.get(self, "incompleteSubnetDefinition"))

    @_incomplete_subnet_definition.setter
    def _incomplete_subnet_definition(self, value: builtins.bool) -> None:
        jsii.set(self, "incompleteSubnetDefinition", value)


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.VpcAttributes",
    jsii_struct_bases=[],
    name_mapping={
        "availability_zones": "availabilityZones",
        "vpc_id": "vpcId",
        "isolated_subnet_ids": "isolatedSubnetIds",
        "isolated_subnet_names": "isolatedSubnetNames",
        "isolated_subnet_route_table_ids": "isolatedSubnetRouteTableIds",
        "private_subnet_ids": "privateSubnetIds",
        "private_subnet_names": "privateSubnetNames",
        "private_subnet_route_table_ids": "privateSubnetRouteTableIds",
        "public_subnet_ids": "publicSubnetIds",
        "public_subnet_names": "publicSubnetNames",
        "public_subnet_route_table_ids": "publicSubnetRouteTableIds",
        "vpc_cidr_block": "vpcCidrBlock",
        "vpn_gateway_id": "vpnGatewayId",
    },
)
class VpcAttributes:
    def __init__(
        self,
        *,
        availability_zones: typing.List[builtins.str],
        vpc_id: builtins.str,
        isolated_subnet_ids: typing.Optional[typing.List[builtins.str]] = None,
        isolated_subnet_names: typing.Optional[typing.List[builtins.str]] = None,
        isolated_subnet_route_table_ids: typing.Optional[typing.List[builtins.str]] = None,
        private_subnet_ids: typing.Optional[typing.List[builtins.str]] = None,
        private_subnet_names: typing.Optional[typing.List[builtins.str]] = None,
        private_subnet_route_table_ids: typing.Optional[typing.List[builtins.str]] = None,
        public_subnet_ids: typing.Optional[typing.List[builtins.str]] = None,
        public_subnet_names: typing.Optional[typing.List[builtins.str]] = None,
        public_subnet_route_table_ids: typing.Optional[typing.List[builtins.str]] = None,
        vpc_cidr_block: typing.Optional[builtins.str] = None,
        vpn_gateway_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties that reference an external Vpc.

        :param availability_zones: List of availability zones for the subnets in this VPC.
        :param vpc_id: VPC's identifier.
        :param isolated_subnet_ids: List of isolated subnet IDs. Must be undefined or match the availability zones in length and order.
        :param isolated_subnet_names: List of names for the isolated subnets. Must be undefined or have a name for every isolated subnet group.
        :param isolated_subnet_route_table_ids: List of IDs of routing tables for the isolated subnets. Must be undefined or have a name for every isolated subnet group.
        :param private_subnet_ids: List of private subnet IDs. Must be undefined or match the availability zones in length and order.
        :param private_subnet_names: List of names for the private subnets. Must be undefined or have a name for every private subnet group.
        :param private_subnet_route_table_ids: List of IDs of routing tables for the private subnets. Must be undefined or have a name for every private subnet group.
        :param public_subnet_ids: List of public subnet IDs. Must be undefined or match the availability zones in length and order.
        :param public_subnet_names: List of names for the public subnets. Must be undefined or have a name for every public subnet group.
        :param public_subnet_route_table_ids: List of IDs of routing tables for the public subnets. Must be undefined or have a name for every public subnet group.
        :param vpc_cidr_block: VPC's CIDR range. Default: - Retrieving the CIDR from the VPC will fail
        :param vpn_gateway_id: VPN gateway's identifier.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "availability_zones": availability_zones,
            "vpc_id": vpc_id,
        }
        if isolated_subnet_ids is not None:
            self._values["isolated_subnet_ids"] = isolated_subnet_ids
        if isolated_subnet_names is not None:
            self._values["isolated_subnet_names"] = isolated_subnet_names
        if isolated_subnet_route_table_ids is not None:
            self._values["isolated_subnet_route_table_ids"] = isolated_subnet_route_table_ids
        if private_subnet_ids is not None:
            self._values["private_subnet_ids"] = private_subnet_ids
        if private_subnet_names is not None:
            self._values["private_subnet_names"] = private_subnet_names
        if private_subnet_route_table_ids is not None:
            self._values["private_subnet_route_table_ids"] = private_subnet_route_table_ids
        if public_subnet_ids is not None:
            self._values["public_subnet_ids"] = public_subnet_ids
        if public_subnet_names is not None:
            self._values["public_subnet_names"] = public_subnet_names
        if public_subnet_route_table_ids is not None:
            self._values["public_subnet_route_table_ids"] = public_subnet_route_table_ids
        if vpc_cidr_block is not None:
            self._values["vpc_cidr_block"] = vpc_cidr_block
        if vpn_gateway_id is not None:
            self._values["vpn_gateway_id"] = vpn_gateway_id

    @builtins.property
    def availability_zones(self) -> typing.List[builtins.str]:
        '''List of availability zones for the subnets in this VPC.'''
        result = self._values.get("availability_zones")
        assert result is not None, "Required property 'availability_zones' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''VPC's identifier.'''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def isolated_subnet_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''List of isolated subnet IDs.

        Must be undefined or match the availability zones in length and order.
        '''
        result = self._values.get("isolated_subnet_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def isolated_subnet_names(self) -> typing.Optional[typing.List[builtins.str]]:
        '''List of names for the isolated subnets.

        Must be undefined or have a name for every isolated subnet group.
        '''
        result = self._values.get("isolated_subnet_names")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def isolated_subnet_route_table_ids(
        self,
    ) -> typing.Optional[typing.List[builtins.str]]:
        '''List of IDs of routing tables for the isolated subnets.

        Must be undefined or have a name for every isolated subnet group.
        '''
        result = self._values.get("isolated_subnet_route_table_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def private_subnet_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''List of private subnet IDs.

        Must be undefined or match the availability zones in length and order.
        '''
        result = self._values.get("private_subnet_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def private_subnet_names(self) -> typing.Optional[typing.List[builtins.str]]:
        '''List of names for the private subnets.

        Must be undefined or have a name for every private subnet group.
        '''
        result = self._values.get("private_subnet_names")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def private_subnet_route_table_ids(
        self,
    ) -> typing.Optional[typing.List[builtins.str]]:
        '''List of IDs of routing tables for the private subnets.

        Must be undefined or have a name for every private subnet group.
        '''
        result = self._values.get("private_subnet_route_table_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def public_subnet_ids(self) -> typing.Optional[typing.List[builtins.str]]:
        '''List of public subnet IDs.

        Must be undefined or match the availability zones in length and order.
        '''
        result = self._values.get("public_subnet_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def public_subnet_names(self) -> typing.Optional[typing.List[builtins.str]]:
        '''List of names for the public subnets.

        Must be undefined or have a name for every public subnet group.
        '''
        result = self._values.get("public_subnet_names")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def public_subnet_route_table_ids(
        self,
    ) -> typing.Optional[typing.List[builtins.str]]:
        '''List of IDs of routing tables for the public subnets.

        Must be undefined or have a name for every public subnet group.
        '''
        result = self._values.get("public_subnet_route_table_ids")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def vpc_cidr_block(self) -> typing.Optional[builtins.str]:
        '''VPC's CIDR range.

        :default: - Retrieving the CIDR from the VPC will fail
        '''
        result = self._values.get("vpc_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vpn_gateway_id(self) -> typing.Optional[builtins.str]:
        '''VPN gateway's identifier.'''
        result = self._values.get("vpn_gateway_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VpcAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IVpcEndpoint)
class VpcEndpoint(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-ec2.VpcEndpoint",
):
    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_VpcEndpointProxy"]:
        return _VpcEndpointProxy

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        account: typing.Optional[builtins.str] = None,
        physical_name: typing.Optional[builtins.str] = None,
        region: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param account: The AWS account ID this resource belongs to. Default: - the resource is in the same account as the stack it belongs to
        :param physical_name: The value passed in by users to the physical name prop of the resource. - ``undefined`` implies that a physical name will be allocated by CloudFormation during deployment. - a concrete value implies a specific physical name - ``PhysicalName.GENERATE_IF_NEEDED`` is a marker that indicates that a physical will only be generated by the CDK if it is needed for cross-environment references. Otherwise, it will be allocated by CloudFormation. Default: - The physical name will be allocated by CloudFormation at deployment time
        :param region: The AWS region this resource belongs to. Default: - the resource is in the same region as the stack it belongs to
        '''
        props = aws_cdk.core.ResourceProps(
            account=account, physical_name=physical_name, region=region
        )

        jsii.create(VpcEndpoint, self, [scope, id, props])

    @jsii.member(jsii_name="addToPolicy")
    def add_to_policy(self, statement: aws_cdk.aws_iam.PolicyStatement) -> None:
        '''Adds a statement to the policy document of the VPC endpoint. The statement must have a Principal.

        Not all interface VPC endpoints support policy. For more information
        see https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html

        :param statement: the IAM statement to add.
        '''
        return typing.cast(None, jsii.invoke(self, "addToPolicy", [statement]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointId")
    @abc.abstractmethod
    def vpc_endpoint_id(self) -> builtins.str:
        '''The VPC endpoint identifier.'''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="policyDocument")
    def _policy_document(self) -> typing.Optional[aws_cdk.aws_iam.PolicyDocument]:
        return typing.cast(typing.Optional[aws_cdk.aws_iam.PolicyDocument], jsii.get(self, "policyDocument"))

    @_policy_document.setter
    def _policy_document(
        self,
        value: typing.Optional[aws_cdk.aws_iam.PolicyDocument],
    ) -> None:
        jsii.set(self, "policyDocument", value)


class _VpcEndpointProxy(
    VpcEndpoint, jsii.proxy_for(aws_cdk.core.Resource) # type: ignore[misc]
):
    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointId")
    def vpc_endpoint_id(self) -> builtins.str:
        '''The VPC endpoint identifier.'''
        return typing.cast(builtins.str, jsii.get(self, "vpcEndpointId"))


@jsii.implements(IVpcEndpointService)
class VpcEndpointService(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.VpcEndpointService",
):
    '''(experimental) A VPC endpoint service.

    :stability: experimental
    :resource: AWS::EC2::VPCEndpointService
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        vpc_endpoint_service_load_balancers: typing.List[IVpcEndpointServiceLoadBalancer],
        acceptance_required: typing.Optional[builtins.bool] = None,
        vpc_endpoint_service_name: typing.Optional[builtins.str] = None,
        whitelisted_principals: typing.Optional[typing.List[aws_cdk.aws_iam.ArnPrincipal]] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param vpc_endpoint_service_load_balancers: (experimental) One or more load balancers to host the VPC Endpoint Service.
        :param acceptance_required: (experimental) Whether requests from service consumers to connect to the service through an endpoint must be accepted. Default: true
        :param vpc_endpoint_service_name: (deprecated) Name of the Vpc Endpoint Service. Default: - CDK generated name
        :param whitelisted_principals: (experimental) IAM users, IAM roles, or AWS accounts to allow inbound connections from. These principals can connect to your service using VPC endpoints. Takes a list of one or more ArnPrincipal. Default: - no principals

        :stability: experimental
        '''
        props = VpcEndpointServiceProps(
            vpc_endpoint_service_load_balancers=vpc_endpoint_service_load_balancers,
            acceptance_required=acceptance_required,
            vpc_endpoint_service_name=vpc_endpoint_service_name,
            whitelisted_principals=whitelisted_principals,
        )

        jsii.create(VpcEndpointService, self, [scope, id, props])

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="acceptanceRequired")
    def acceptance_required(self) -> builtins.bool:
        '''(experimental) Whether to require manual acceptance of new connections to the service.

        :stability: experimental
        '''
        return typing.cast(builtins.bool, jsii.get(self, "acceptanceRequired"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointServiceId")
    def vpc_endpoint_service_id(self) -> builtins.str:
        '''(experimental) The id of the VPC Endpoint Service, like vpce-svc-xxxxxxxxxxxxxxxx.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcEndpointServiceId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointServiceLoadBalancers")
    def vpc_endpoint_service_load_balancers(
        self,
    ) -> typing.List[IVpcEndpointServiceLoadBalancer]:
        '''(experimental) One or more network load balancers to host the service.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(typing.List[IVpcEndpointServiceLoadBalancer], jsii.get(self, "vpcEndpointServiceLoadBalancers"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointServiceName")
    def vpc_endpoint_service_name(self) -> builtins.str:
        '''(experimental) The service name of the VPC Endpoint Service that clients use to connect to, like com.amazonaws.vpce..vpce-svc-xxxxxxxxxxxxxxxx.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcEndpointServiceName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="whitelistedPrincipals")
    def whitelisted_principals(self) -> typing.List[aws_cdk.aws_iam.ArnPrincipal]:
        '''(experimental) One or more Principal ARNs to allow inbound connections to.

        :stability: experimental
        '''
        return typing.cast(typing.List[aws_cdk.aws_iam.ArnPrincipal], jsii.get(self, "whitelistedPrincipals"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.VpcEndpointServiceProps",
    jsii_struct_bases=[],
    name_mapping={
        "vpc_endpoint_service_load_balancers": "vpcEndpointServiceLoadBalancers",
        "acceptance_required": "acceptanceRequired",
        "vpc_endpoint_service_name": "vpcEndpointServiceName",
        "whitelisted_principals": "whitelistedPrincipals",
    },
)
class VpcEndpointServiceProps:
    def __init__(
        self,
        *,
        vpc_endpoint_service_load_balancers: typing.List[IVpcEndpointServiceLoadBalancer],
        acceptance_required: typing.Optional[builtins.bool] = None,
        vpc_endpoint_service_name: typing.Optional[builtins.str] = None,
        whitelisted_principals: typing.Optional[typing.List[aws_cdk.aws_iam.ArnPrincipal]] = None,
    ) -> None:
        '''(experimental) Construction properties for a VpcEndpointService.

        :param vpc_endpoint_service_load_balancers: (experimental) One or more load balancers to host the VPC Endpoint Service.
        :param acceptance_required: (experimental) Whether requests from service consumers to connect to the service through an endpoint must be accepted. Default: true
        :param vpc_endpoint_service_name: (deprecated) Name of the Vpc Endpoint Service. Default: - CDK generated name
        :param whitelisted_principals: (experimental) IAM users, IAM roles, or AWS accounts to allow inbound connections from. These principals can connect to your service using VPC endpoints. Takes a list of one or more ArnPrincipal. Default: - no principals

        :stability: experimental
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "vpc_endpoint_service_load_balancers": vpc_endpoint_service_load_balancers,
        }
        if acceptance_required is not None:
            self._values["acceptance_required"] = acceptance_required
        if vpc_endpoint_service_name is not None:
            self._values["vpc_endpoint_service_name"] = vpc_endpoint_service_name
        if whitelisted_principals is not None:
            self._values["whitelisted_principals"] = whitelisted_principals

    @builtins.property
    def vpc_endpoint_service_load_balancers(
        self,
    ) -> typing.List[IVpcEndpointServiceLoadBalancer]:
        '''(experimental) One or more load balancers to host the VPC Endpoint Service.

        :stability: experimental
        '''
        result = self._values.get("vpc_endpoint_service_load_balancers")
        assert result is not None, "Required property 'vpc_endpoint_service_load_balancers' is missing"
        return typing.cast(typing.List[IVpcEndpointServiceLoadBalancer], result)

    @builtins.property
    def acceptance_required(self) -> typing.Optional[builtins.bool]:
        '''(experimental) Whether requests from service consumers to connect to the service through an endpoint must be accepted.

        :default: true

        :stability: experimental
        '''
        result = self._values.get("acceptance_required")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def vpc_endpoint_service_name(self) -> typing.Optional[builtins.str]:
        '''(deprecated) Name of the Vpc Endpoint Service.

        :default: - CDK generated name

        :deprecated: This property is not used

        :stability: deprecated
        '''
        result = self._values.get("vpc_endpoint_service_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def whitelisted_principals(
        self,
    ) -> typing.Optional[typing.List[aws_cdk.aws_iam.ArnPrincipal]]:
        '''(experimental) IAM users, IAM roles, or AWS accounts to allow inbound connections from.

        These principals can connect to your service using VPC endpoints. Takes a
        list of one or more ArnPrincipal.

        :default: - no principals

        :stability: experimental
        '''
        result = self._values.get("whitelisted_principals")
        return typing.cast(typing.Optional[typing.List[aws_cdk.aws_iam.ArnPrincipal]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VpcEndpointServiceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.VpcEndpointType")
class VpcEndpointType(enum.Enum):
    '''The type of VPC endpoint.'''

    INTERFACE = "INTERFACE"
    '''Interface.

    An interface endpoint is an elastic network interface with a private IP
    address that serves as an entry point for traffic destined to a supported
    service.
    '''
    GATEWAY = "GATEWAY"
    '''Gateway.

    A gateway endpoint is a gateway that is a target for a specified route in
    your route table, used for traffic destined to a supported AWS service.
    '''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.VpcLookupOptions",
    jsii_struct_bases=[],
    name_mapping={
        "is_default": "isDefault",
        "subnet_group_name_tag": "subnetGroupNameTag",
        "tags": "tags",
        "vpc_id": "vpcId",
        "vpc_name": "vpcName",
    },
)
class VpcLookupOptions:
    def __init__(
        self,
        *,
        is_default: typing.Optional[builtins.bool] = None,
        subnet_group_name_tag: typing.Optional[builtins.str] = None,
        tags: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        vpc_id: typing.Optional[builtins.str] = None,
        vpc_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for looking up an existing VPC.

        The combination of properties must specify filter down to exactly one
        non-default VPC, otherwise an error is raised.

        :param is_default: Whether to match the default VPC. Default: Don't care whether we return the default VPC
        :param subnet_group_name_tag: Optional tag for subnet group name. If not provided, we'll look at the aws-cdk:subnet-name tag. If the subnet does not have the specified tag, we'll use its type as the name. Default: aws-cdk:subnet-name
        :param tags: Tags on the VPC. The VPC must have all of these tags Default: Don't filter on tags
        :param vpc_id: The ID of the VPC. If given, will import exactly this VPC. Default: Don't filter on vpcId
        :param vpc_name: The name of the VPC. If given, will import the VPC with this name. Default: Don't filter on vpcName
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if is_default is not None:
            self._values["is_default"] = is_default
        if subnet_group_name_tag is not None:
            self._values["subnet_group_name_tag"] = subnet_group_name_tag
        if tags is not None:
            self._values["tags"] = tags
        if vpc_id is not None:
            self._values["vpc_id"] = vpc_id
        if vpc_name is not None:
            self._values["vpc_name"] = vpc_name

    @builtins.property
    def is_default(self) -> typing.Optional[builtins.bool]:
        '''Whether to match the default VPC.

        :default: Don't care whether we return the default VPC
        '''
        result = self._values.get("is_default")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def subnet_group_name_tag(self) -> typing.Optional[builtins.str]:
        '''Optional tag for subnet group name.

        If not provided, we'll look at the aws-cdk:subnet-name tag.
        If the subnet does not have the specified tag,
        we'll use its type as the name.

        :default: aws-cdk:subnet-name
        '''
        result = self._values.get("subnet_group_name_tag")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Tags on the VPC.

        The VPC must have all of these tags

        :default: Don't filter on tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def vpc_id(self) -> typing.Optional[builtins.str]:
        '''The ID of the VPC.

        If given, will import exactly this VPC.

        :default: Don't filter on vpcId
        '''
        result = self._values.get("vpc_id")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def vpc_name(self) -> typing.Optional[builtins.str]:
        '''The name of the VPC.

        If given, will import the VPC with this name.

        :default: Don't filter on vpcName
        '''
        result = self._values.get("vpc_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VpcLookupOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.VpcProps",
    jsii_struct_bases=[],
    name_mapping={
        "cidr": "cidr",
        "default_instance_tenancy": "defaultInstanceTenancy",
        "enable_dns_hostnames": "enableDnsHostnames",
        "enable_dns_support": "enableDnsSupport",
        "flow_logs": "flowLogs",
        "gateway_endpoints": "gatewayEndpoints",
        "max_azs": "maxAzs",
        "nat_gateway_provider": "natGatewayProvider",
        "nat_gateways": "natGateways",
        "nat_gateway_subnets": "natGatewaySubnets",
        "subnet_configuration": "subnetConfiguration",
        "vpn_connections": "vpnConnections",
        "vpn_gateway": "vpnGateway",
        "vpn_gateway_asn": "vpnGatewayAsn",
        "vpn_route_propagation": "vpnRoutePropagation",
    },
)
class VpcProps:
    def __init__(
        self,
        *,
        cidr: typing.Optional[builtins.str] = None,
        default_instance_tenancy: typing.Optional[DefaultInstanceTenancy] = None,
        enable_dns_hostnames: typing.Optional[builtins.bool] = None,
        enable_dns_support: typing.Optional[builtins.bool] = None,
        flow_logs: typing.Optional[typing.Mapping[builtins.str, FlowLogOptions]] = None,
        gateway_endpoints: typing.Optional[typing.Mapping[builtins.str, GatewayVpcEndpointOptions]] = None,
        max_azs: typing.Optional[jsii.Number] = None,
        nat_gateway_provider: typing.Optional[NatProvider] = None,
        nat_gateways: typing.Optional[jsii.Number] = None,
        nat_gateway_subnets: typing.Optional[SubnetSelection] = None,
        subnet_configuration: typing.Optional[typing.List[SubnetConfiguration]] = None,
        vpn_connections: typing.Optional[typing.Mapping[builtins.str, "VpnConnectionOptions"]] = None,
        vpn_gateway: typing.Optional[builtins.bool] = None,
        vpn_gateway_asn: typing.Optional[jsii.Number] = None,
        vpn_route_propagation: typing.Optional[typing.List[SubnetSelection]] = None,
    ) -> None:
        '''Configuration for Vpc.

        :param cidr: The CIDR range to use for the VPC, e.g. '10.0.0.0/16'. Should be a minimum of /28 and maximum size of /16. The range will be split across all subnets per Availability Zone. Default: Vpc.DEFAULT_CIDR_RANGE
        :param default_instance_tenancy: The default tenancy of instances launched into the VPC. By setting this to dedicated tenancy, instances will be launched on hardware dedicated to a single AWS customer, unless specifically specified at instance launch time. Please note, not all instance types are usable with Dedicated tenancy. Default: DefaultInstanceTenancy.Default (shared) tenancy
        :param enable_dns_hostnames: Indicates whether the instances launched in the VPC get public DNS hostnames. If this attribute is true, instances in the VPC get public DNS hostnames, but only if the enableDnsSupport attribute is also set to true. Default: true
        :param enable_dns_support: Indicates whether the DNS resolution is supported for the VPC. If this attribute is false, the Amazon-provided DNS server in the VPC that resolves public DNS hostnames to IP addresses is not enabled. If this attribute is true, queries to the Amazon provided DNS server at the 169.254.169.253 IP address, or the reserved IP address at the base of the VPC IPv4 network range plus two will succeed. Default: true
        :param flow_logs: Flow logs to add to this VPC. Default: - No flow logs.
        :param gateway_endpoints: Gateway endpoints to add to this VPC. Default: - None.
        :param max_azs: Define the maximum number of AZs to use in this region. If the region has more AZs than you want to use (for example, because of EIP limits), pick a lower number here. The AZs will be sorted and picked from the start of the list. If you pick a higher number than the number of AZs in the region, all AZs in the region will be selected. To use "all AZs" available to your account, use a high number (such as 99). Be aware that environment-agnostic stacks will be created with access to only 2 AZs, so to use more than 2 AZs, be sure to specify the account and region on your stack. Default: 3
        :param nat_gateway_provider: (experimental) What type of NAT provider to use. Select between NAT gateways or NAT instances. NAT gateways may not be available in all AWS regions. Default: NatProvider.gateway()
        :param nat_gateways: The number of NAT Gateways/Instances to create. The type of NAT gateway or instance will be determined by the ``natGatewayProvider`` parameter. You can set this number lower than the number of Availability Zones in your VPC in order to save on NAT cost. Be aware you may be charged for cross-AZ data traffic instead. Default: - One NAT gateway/instance per Availability Zone
        :param nat_gateway_subnets: Configures the subnets which will have NAT Gateways/Instances. You can pick a specific group of subnets by specifying the group name; the picked subnets must be public subnets. Only necessary if you have more than one public subnet group. Default: - All public subnets.
        :param subnet_configuration: Configure the subnets to build for each AZ. Each entry in this list configures a Subnet Group; each group will contain a subnet for each Availability Zone. For example, if you want 1 public subnet, 1 private subnet, and 1 isolated subnet in each AZ provide the following:: new ec2.Vpc(this, 'VPC', { subnetConfiguration: [ { cidrMask: 24, name: 'ingress', subnetType: ec2.SubnetType.PUBLIC, }, { cidrMask: 24, name: 'application', subnetType: ec2.SubnetType.PRIVATE, }, { cidrMask: 28, name: 'rds', subnetType: ec2.SubnetType.ISOLATED, } ] }); Default: - The VPC CIDR will be evenly divided between 1 public and 1 private subnet per AZ.
        :param vpn_connections: VPN connections to this VPC. Default: - No connections.
        :param vpn_gateway: Indicates whether a VPN gateway should be created and attached to this VPC. Default: - true when vpnGatewayAsn or vpnConnections is specified
        :param vpn_gateway_asn: The private Autonomous System Number (ASN) for the VPN gateway. Default: - Amazon default ASN.
        :param vpn_route_propagation: Where to propagate VPN routes. Default: - On the route tables associated with private subnets. If no private subnets exists, isolated subnets are used. If no isolated subnets exists, public subnets are used.
        '''
        if isinstance(nat_gateway_subnets, dict):
            nat_gateway_subnets = SubnetSelection(**nat_gateway_subnets)
        self._values: typing.Dict[str, typing.Any] = {}
        if cidr is not None:
            self._values["cidr"] = cidr
        if default_instance_tenancy is not None:
            self._values["default_instance_tenancy"] = default_instance_tenancy
        if enable_dns_hostnames is not None:
            self._values["enable_dns_hostnames"] = enable_dns_hostnames
        if enable_dns_support is not None:
            self._values["enable_dns_support"] = enable_dns_support
        if flow_logs is not None:
            self._values["flow_logs"] = flow_logs
        if gateway_endpoints is not None:
            self._values["gateway_endpoints"] = gateway_endpoints
        if max_azs is not None:
            self._values["max_azs"] = max_azs
        if nat_gateway_provider is not None:
            self._values["nat_gateway_provider"] = nat_gateway_provider
        if nat_gateways is not None:
            self._values["nat_gateways"] = nat_gateways
        if nat_gateway_subnets is not None:
            self._values["nat_gateway_subnets"] = nat_gateway_subnets
        if subnet_configuration is not None:
            self._values["subnet_configuration"] = subnet_configuration
        if vpn_connections is not None:
            self._values["vpn_connections"] = vpn_connections
        if vpn_gateway is not None:
            self._values["vpn_gateway"] = vpn_gateway
        if vpn_gateway_asn is not None:
            self._values["vpn_gateway_asn"] = vpn_gateway_asn
        if vpn_route_propagation is not None:
            self._values["vpn_route_propagation"] = vpn_route_propagation

    @builtins.property
    def cidr(self) -> typing.Optional[builtins.str]:
        '''The CIDR range to use for the VPC, e.g. '10.0.0.0/16'.

        Should be a minimum of /28 and maximum size of /16. The range will be
        split across all subnets per Availability Zone.

        :default: Vpc.DEFAULT_CIDR_RANGE
        '''
        result = self._values.get("cidr")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def default_instance_tenancy(self) -> typing.Optional[DefaultInstanceTenancy]:
        '''The default tenancy of instances launched into the VPC.

        By setting this to dedicated tenancy, instances will be launched on
        hardware dedicated to a single AWS customer, unless specifically specified
        at instance launch time. Please note, not all instance types are usable
        with Dedicated tenancy.

        :default: DefaultInstanceTenancy.Default (shared) tenancy
        '''
        result = self._values.get("default_instance_tenancy")
        return typing.cast(typing.Optional[DefaultInstanceTenancy], result)

    @builtins.property
    def enable_dns_hostnames(self) -> typing.Optional[builtins.bool]:
        '''Indicates whether the instances launched in the VPC get public DNS hostnames.

        If this attribute is true, instances in the VPC get public DNS hostnames,
        but only if the enableDnsSupport attribute is also set to true.

        :default: true
        '''
        result = self._values.get("enable_dns_hostnames")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def enable_dns_support(self) -> typing.Optional[builtins.bool]:
        '''Indicates whether the DNS resolution is supported for the VPC.

        If this attribute is false, the Amazon-provided DNS server in the VPC that
        resolves public DNS hostnames to IP addresses is not enabled. If this
        attribute is true, queries to the Amazon provided DNS server at the
        169.254.169.253 IP address, or the reserved IP address at the base of the
        VPC IPv4 network range plus two will succeed.

        :default: true
        '''
        result = self._values.get("enable_dns_support")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def flow_logs(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, FlowLogOptions]]:
        '''Flow logs to add to this VPC.

        :default: - No flow logs.
        '''
        result = self._values.get("flow_logs")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, FlowLogOptions]], result)

    @builtins.property
    def gateway_endpoints(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, GatewayVpcEndpointOptions]]:
        '''Gateway endpoints to add to this VPC.

        :default: - None.
        '''
        result = self._values.get("gateway_endpoints")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, GatewayVpcEndpointOptions]], result)

    @builtins.property
    def max_azs(self) -> typing.Optional[jsii.Number]:
        '''Define the maximum number of AZs to use in this region.

        If the region has more AZs than you want to use (for example, because of
        EIP limits), pick a lower number here. The AZs will be sorted and picked
        from the start of the list.

        If you pick a higher number than the number of AZs in the region, all AZs
        in the region will be selected. To use "all AZs" available to your
        account, use a high number (such as 99).

        Be aware that environment-agnostic stacks will be created with access to
        only 2 AZs, so to use more than 2 AZs, be sure to specify the account and
        region on your stack.

        :default: 3
        '''
        result = self._values.get("max_azs")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def nat_gateway_provider(self) -> typing.Optional[NatProvider]:
        '''(experimental) What type of NAT provider to use.

        Select between NAT gateways or NAT instances. NAT gateways
        may not be available in all AWS regions.

        :default: NatProvider.gateway()

        :stability: experimental
        '''
        result = self._values.get("nat_gateway_provider")
        return typing.cast(typing.Optional[NatProvider], result)

    @builtins.property
    def nat_gateways(self) -> typing.Optional[jsii.Number]:
        '''The number of NAT Gateways/Instances to create.

        The type of NAT gateway or instance will be determined by the
        ``natGatewayProvider`` parameter.

        You can set this number lower than the number of Availability Zones in your
        VPC in order to save on NAT cost. Be aware you may be charged for
        cross-AZ data traffic instead.

        :default: - One NAT gateway/instance per Availability Zone
        '''
        result = self._values.get("nat_gateways")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def nat_gateway_subnets(self) -> typing.Optional[SubnetSelection]:
        '''Configures the subnets which will have NAT Gateways/Instances.

        You can pick a specific group of subnets by specifying the group name;
        the picked subnets must be public subnets.

        Only necessary if you have more than one public subnet group.

        :default: - All public subnets.
        '''
        result = self._values.get("nat_gateway_subnets")
        return typing.cast(typing.Optional[SubnetSelection], result)

    @builtins.property
    def subnet_configuration(self) -> typing.Optional[typing.List[SubnetConfiguration]]:
        '''Configure the subnets to build for each AZ.

        Each entry in this list configures a Subnet Group; each group will contain a
        subnet for each Availability Zone.

        For example, if you want 1 public subnet, 1 private subnet, and 1 isolated
        subnet in each AZ provide the following::

           # Example automatically generated. See https://github.com/aws/jsii/issues/826
           ec2.Vpc(self, "VPC",
               subnet_configuration=[{
                   "cidr_mask": 24,
                   "name": "ingress",
                   "subnet_type": ec2.SubnetType.PUBLIC
               }, {
                   "cidr_mask": 24,
                   "name": "application",
                   "subnet_type": ec2.SubnetType.PRIVATE
               }, {
                   "cidr_mask": 28,
                   "name": "rds",
                   "subnet_type": ec2.SubnetType.ISOLATED
               }
               ]
           )

        :default:

        - The VPC CIDR will be evenly divided between 1 public and 1
        private subnet per AZ.
        '''
        result = self._values.get("subnet_configuration")
        return typing.cast(typing.Optional[typing.List[SubnetConfiguration]], result)

    @builtins.property
    def vpn_connections(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, "VpnConnectionOptions"]]:
        '''VPN connections to this VPC.

        :default: - No connections.
        '''
        result = self._values.get("vpn_connections")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, "VpnConnectionOptions"]], result)

    @builtins.property
    def vpn_gateway(self) -> typing.Optional[builtins.bool]:
        '''Indicates whether a VPN gateway should be created and attached to this VPC.

        :default: - true when vpnGatewayAsn or vpnConnections is specified
        '''
        result = self._values.get("vpn_gateway")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def vpn_gateway_asn(self) -> typing.Optional[jsii.Number]:
        '''The private Autonomous System Number (ASN) for the VPN gateway.

        :default: - Amazon default ASN.
        '''
        result = self._values.get("vpn_gateway_asn")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def vpn_route_propagation(self) -> typing.Optional[typing.List[SubnetSelection]]:
        '''Where to propagate VPN routes.

        :default:

        - On the route tables associated with private subnets. If no
        private subnets exists, isolated subnets are used. If no isolated subnets
        exists, public subnets are used.
        '''
        result = self._values.get("vpn_route_propagation")
        return typing.cast(typing.Optional[typing.List[SubnetSelection]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VpcProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IVpnConnection)
class VpnConnection(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.VpnConnection",
):
    '''Define a VPN Connection.

    :resource: AWS::EC2::VPNConnection
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        vpc: IVpc,
        ip: builtins.str,
        asn: typing.Optional[jsii.Number] = None,
        static_routes: typing.Optional[typing.List[builtins.str]] = None,
        tunnel_options: typing.Optional[typing.List["VpnTunnelOption"]] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param vpc: The VPC to connect to.
        :param ip: The ip address of the customer gateway.
        :param asn: The ASN of the customer gateway. Default: 65000
        :param static_routes: The static routes to be routed from the VPN gateway to the customer gateway. Default: Dynamic routing (BGP)
        :param tunnel_options: The tunnel options for the VPN connection. At most two elements (one per tunnel). Duplicates not allowed. Default: Amazon generated tunnel options
        '''
        props = VpnConnectionProps(
            vpc=vpc,
            ip=ip,
            asn=asn,
            static_routes=static_routes,
            tunnel_options=tunnel_options,
        )

        jsii.create(VpnConnection, self, [scope, id, props])

    @jsii.member(jsii_name="metricAll") # type: ignore[misc]
    @builtins.classmethod
    def metric_all(
        cls,
        metric_name: builtins.str,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''Return the given named metric for all VPN connections in the account/region.

        :param metric_name: -
        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.sinvoke(cls, "metricAll", [metric_name, props]))

    @jsii.member(jsii_name="metricAllTunnelDataIn") # type: ignore[misc]
    @builtins.classmethod
    def metric_all_tunnel_data_in(
        cls,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''Metric for the tunnel data in of all VPN connections in the account/region.

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream

        :default: sum over 5 minutes
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.sinvoke(cls, "metricAllTunnelDataIn", [props]))

    @jsii.member(jsii_name="metricAllTunnelDataOut") # type: ignore[misc]
    @builtins.classmethod
    def metric_all_tunnel_data_out(
        cls,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''Metric for the tunnel data out of all VPN connections.

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream

        :default: sum over 5 minutes
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.sinvoke(cls, "metricAllTunnelDataOut", [props]))

    @jsii.member(jsii_name="metricAllTunnelState") # type: ignore[misc]
    @builtins.classmethod
    def metric_all_tunnel_state(
        cls,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''Metric for the tunnel state of all VPN connections in the account/region.

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream

        :default: average over 5 minutes
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.sinvoke(cls, "metricAllTunnelState", [props]))

    @jsii.member(jsii_name="metric")
    def metric(
        self,
        metric_name: builtins.str,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''Return the given named metric for this VPNConnection.

        :param metric_name: -
        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.invoke(self, "metric", [metric_name, props]))

    @jsii.member(jsii_name="metricTunnelDataIn")
    def metric_tunnel_data_in(
        self,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''The bytes received through the VPN tunnel.

        Sum over 5 minutes

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.invoke(self, "metricTunnelDataIn", [props]))

    @jsii.member(jsii_name="metricTunnelDataOut")
    def metric_tunnel_data_out(
        self,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''The bytes sent through the VPN tunnel.

        Sum over 5 minutes

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.invoke(self, "metricTunnelDataOut", [props]))

    @jsii.member(jsii_name="metricTunnelState")
    def metric_tunnel_state(
        self,
        *,
        account: typing.Optional[builtins.str] = None,
        color: typing.Optional[builtins.str] = None,
        dimensions: typing.Optional[typing.Mapping[builtins.str, typing.Any]] = None,
        label: typing.Optional[builtins.str] = None,
        period: typing.Optional[aws_cdk.core.Duration] = None,
        region: typing.Optional[builtins.str] = None,
        statistic: typing.Optional[builtins.str] = None,
        unit: typing.Optional[aws_cdk.aws_cloudwatch.Unit] = None,
    ) -> aws_cdk.aws_cloudwatch.Metric:
        '''The state of the tunnel. 0 indicates DOWN and 1 indicates UP.

        Average over 5 minutes

        :param account: Account which this metric comes from. Default: - Deployment account.
        :param color: The hex color code, prefixed with '#' (e.g. '#00ff00'), to use when this metric is rendered on a graph. The ``Color`` class has a set of standard colors that can be used here. Default: - Automatic color
        :param dimensions: Dimensions of the metric. Default: - No dimensions.
        :param label: Label for this metric when added to a Graph in a Dashboard. Default: - No label
        :param period: The period over which the specified statistic is applied. Default: Duration.minutes(5)
        :param region: Region which this metric comes from. Default: - Deployment region.
        :param statistic: What function to use for aggregating. Can be one of the following: - "Minimum" | "min" - "Maximum" | "max" - "Average" | "avg" - "Sum" | "sum" - "SampleCount | "n" - "pNN.NN" Default: Average
        :param unit: Unit used to filter the metric stream. Only refer to datums emitted to the metric stream with the given unit and ignore all others. Only useful when datums are being emitted to the same metric stream under different units. The default is to use all matric datums in the stream, regardless of unit, which is recommended in nearly all cases. CloudWatch does not honor this property for graphs. Default: - All metric datums in the given metric stream
        '''
        props = aws_cdk.aws_cloudwatch.MetricOptions(
            account=account,
            color=color,
            dimensions=dimensions,
            label=label,
            period=period,
            region=region,
            statistic=statistic,
            unit=unit,
        )

        return typing.cast(aws_cdk.aws_cloudwatch.Metric, jsii.invoke(self, "metricTunnelState", [props]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="customerGatewayAsn")
    def customer_gateway_asn(self) -> jsii.Number:
        '''The ASN of the customer gateway.'''
        return typing.cast(jsii.Number, jsii.get(self, "customerGatewayAsn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="customerGatewayId")
    def customer_gateway_id(self) -> builtins.str:
        '''The id of the customer gateway.'''
        return typing.cast(builtins.str, jsii.get(self, "customerGatewayId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="customerGatewayIp")
    def customer_gateway_ip(self) -> builtins.str:
        '''The ip address of the customer gateway.'''
        return typing.cast(builtins.str, jsii.get(self, "customerGatewayIp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpnId")
    def vpn_id(self) -> builtins.str:
        '''The id of the VPN connection.'''
        return typing.cast(builtins.str, jsii.get(self, "vpnId"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.VpnConnectionOptions",
    jsii_struct_bases=[],
    name_mapping={
        "ip": "ip",
        "asn": "asn",
        "static_routes": "staticRoutes",
        "tunnel_options": "tunnelOptions",
    },
)
class VpnConnectionOptions:
    def __init__(
        self,
        *,
        ip: builtins.str,
        asn: typing.Optional[jsii.Number] = None,
        static_routes: typing.Optional[typing.List[builtins.str]] = None,
        tunnel_options: typing.Optional[typing.List["VpnTunnelOption"]] = None,
    ) -> None:
        '''
        :param ip: The ip address of the customer gateway.
        :param asn: The ASN of the customer gateway. Default: 65000
        :param static_routes: The static routes to be routed from the VPN gateway to the customer gateway. Default: Dynamic routing (BGP)
        :param tunnel_options: The tunnel options for the VPN connection. At most two elements (one per tunnel). Duplicates not allowed. Default: Amazon generated tunnel options
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "ip": ip,
        }
        if asn is not None:
            self._values["asn"] = asn
        if static_routes is not None:
            self._values["static_routes"] = static_routes
        if tunnel_options is not None:
            self._values["tunnel_options"] = tunnel_options

    @builtins.property
    def ip(self) -> builtins.str:
        '''The ip address of the customer gateway.'''
        result = self._values.get("ip")
        assert result is not None, "Required property 'ip' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def asn(self) -> typing.Optional[jsii.Number]:
        '''The ASN of the customer gateway.

        :default: 65000
        '''
        result = self._values.get("asn")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def static_routes(self) -> typing.Optional[typing.List[builtins.str]]:
        '''The static routes to be routed from the VPN gateway to the customer gateway.

        :default: Dynamic routing (BGP)
        '''
        result = self._values.get("static_routes")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def tunnel_options(self) -> typing.Optional[typing.List["VpnTunnelOption"]]:
        '''The tunnel options for the VPN connection.

        At most two elements (one per tunnel).
        Duplicates not allowed.

        :default: Amazon generated tunnel options
        '''
        result = self._values.get("tunnel_options")
        return typing.cast(typing.Optional[typing.List["VpnTunnelOption"]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VpnConnectionOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.VpnConnectionProps",
    jsii_struct_bases=[VpnConnectionOptions],
    name_mapping={
        "ip": "ip",
        "asn": "asn",
        "static_routes": "staticRoutes",
        "tunnel_options": "tunnelOptions",
        "vpc": "vpc",
    },
)
class VpnConnectionProps(VpnConnectionOptions):
    def __init__(
        self,
        *,
        ip: builtins.str,
        asn: typing.Optional[jsii.Number] = None,
        static_routes: typing.Optional[typing.List[builtins.str]] = None,
        tunnel_options: typing.Optional[typing.List["VpnTunnelOption"]] = None,
        vpc: IVpc,
    ) -> None:
        '''
        :param ip: The ip address of the customer gateway.
        :param asn: The ASN of the customer gateway. Default: 65000
        :param static_routes: The static routes to be routed from the VPN gateway to the customer gateway. Default: Dynamic routing (BGP)
        :param tunnel_options: The tunnel options for the VPN connection. At most two elements (one per tunnel). Duplicates not allowed. Default: Amazon generated tunnel options
        :param vpc: The VPC to connect to.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "ip": ip,
            "vpc": vpc,
        }
        if asn is not None:
            self._values["asn"] = asn
        if static_routes is not None:
            self._values["static_routes"] = static_routes
        if tunnel_options is not None:
            self._values["tunnel_options"] = tunnel_options

    @builtins.property
    def ip(self) -> builtins.str:
        '''The ip address of the customer gateway.'''
        result = self._values.get("ip")
        assert result is not None, "Required property 'ip' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def asn(self) -> typing.Optional[jsii.Number]:
        '''The ASN of the customer gateway.

        :default: 65000
        '''
        result = self._values.get("asn")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def static_routes(self) -> typing.Optional[typing.List[builtins.str]]:
        '''The static routes to be routed from the VPN gateway to the customer gateway.

        :default: Dynamic routing (BGP)
        '''
        result = self._values.get("static_routes")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def tunnel_options(self) -> typing.Optional[typing.List["VpnTunnelOption"]]:
        '''The tunnel options for the VPN connection.

        At most two elements (one per tunnel).
        Duplicates not allowed.

        :default: Amazon generated tunnel options
        '''
        result = self._values.get("tunnel_options")
        return typing.cast(typing.Optional[typing.List["VpnTunnelOption"]], result)

    @builtins.property
    def vpc(self) -> IVpc:
        '''The VPC to connect to.'''
        result = self._values.get("vpc")
        assert result is not None, "Required property 'vpc' is missing"
        return typing.cast(IVpc, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VpnConnectionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.VpnConnectionType")
class VpnConnectionType(enum.Enum):
    '''The VPN connection type.'''

    IPSEC_1 = "IPSEC_1"
    '''The IPsec 1 VPN connection type.'''
    DUMMY = "DUMMY"
    '''Dummy member TODO: remove once https://github.com/aws/jsii/issues/231 is fixed.'''


@jsii.implements(IVpnGateway)
class VpnGateway(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.VpnGateway",
):
    '''The VPN Gateway that shall be added to the VPC.

    :resource: AWS::EC2::VPNGateway
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        type: builtins.str,
        amazon_side_asn: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param type: Default type ipsec.1.
        :param amazon_side_asn: Explicitly specify an Asn or let aws pick an Asn for you. Default: 65000
        '''
        props = VpnGatewayProps(type=type, amazon_side_asn=amazon_side_asn)

        jsii.create(VpnGateway, self, [scope, id, props])

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="gatewayId")
    def gateway_id(self) -> builtins.str:
        '''The virtual private gateway Id.'''
        return typing.cast(builtins.str, jsii.get(self, "gatewayId"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.VpnGatewayProps",
    jsii_struct_bases=[],
    name_mapping={"type": "type", "amazon_side_asn": "amazonSideAsn"},
)
class VpnGatewayProps:
    def __init__(
        self,
        *,
        type: builtins.str,
        amazon_side_asn: typing.Optional[jsii.Number] = None,
    ) -> None:
        '''The VpnGateway Properties.

        :param type: Default type ipsec.1.
        :param amazon_side_asn: Explicitly specify an Asn or let aws pick an Asn for you. Default: 65000
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if amazon_side_asn is not None:
            self._values["amazon_side_asn"] = amazon_side_asn

    @builtins.property
    def type(self) -> builtins.str:
        '''Default type ipsec.1.'''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def amazon_side_asn(self) -> typing.Optional[jsii.Number]:
        '''Explicitly specify an Asn or let aws pick an Asn for you.

        :default: 65000
        '''
        result = self._values.get("amazon_side_asn")
        return typing.cast(typing.Optional[jsii.Number], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VpnGatewayProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.VpnTunnelOption",
    jsii_struct_bases=[],
    name_mapping={
        "pre_shared_key": "preSharedKey",
        "tunnel_inside_cidr": "tunnelInsideCidr",
    },
)
class VpnTunnelOption:
    def __init__(
        self,
        *,
        pre_shared_key: typing.Optional[builtins.str] = None,
        tunnel_inside_cidr: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param pre_shared_key: The pre-shared key (PSK) to establish initial authentication between the virtual private gateway and customer gateway. Allowed characters are alphanumeric characters and ._. Must be between 8 and 64 characters in length and cannot start with zero (0). Default: an Amazon generated pre-shared key
        :param tunnel_inside_cidr: The range of inside IP addresses for the tunnel. Any specified CIDR blocks must be unique across all VPN connections that use the same virtual private gateway. A size /30 CIDR block from the 169.254.0.0/16 range. Default: an Amazon generated inside IP CIDR
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if pre_shared_key is not None:
            self._values["pre_shared_key"] = pre_shared_key
        if tunnel_inside_cidr is not None:
            self._values["tunnel_inside_cidr"] = tunnel_inside_cidr

    @builtins.property
    def pre_shared_key(self) -> typing.Optional[builtins.str]:
        '''The pre-shared key (PSK) to establish initial authentication between the virtual private gateway and customer gateway.

        Allowed characters are alphanumeric characters
        and ._. Must be between 8 and 64 characters in length and cannot start with zero (0).

        :default: an Amazon generated pre-shared key
        '''
        result = self._values.get("pre_shared_key")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def tunnel_inside_cidr(self) -> typing.Optional[builtins.str]:
        '''The range of inside IP addresses for the tunnel.

        Any specified CIDR blocks must be
        unique across all VPN connections that use the same virtual private gateway.
        A size /30 CIDR block from the 169.254.0.0/16 range.

        :default: an Amazon generated inside IP CIDR
        '''
        result = self._values.get("tunnel_inside_cidr")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "VpnTunnelOption(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.WindowsImageProps",
    jsii_struct_bases=[],
    name_mapping={"user_data": "userData"},
)
class WindowsImageProps:
    def __init__(self, *, user_data: typing.Optional[UserData] = None) -> None:
        '''Configuration options for WindowsImage.

        :param user_data: Initial user data. Default: - Empty UserData for Windows machines
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if user_data is not None:
            self._values["user_data"] = user_data

    @builtins.property
    def user_data(self) -> typing.Optional[UserData]:
        '''Initial user data.

        :default: - Empty UserData for Windows machines
        '''
        result = self._values.get("user_data")
        return typing.cast(typing.Optional[UserData], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "WindowsImageProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-ec2.WindowsVersion")
class WindowsVersion(enum.Enum):
    '''The Windows version to use for the WindowsImage.'''

    WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_SQL_2008_SP4_EXPRESS = "WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_SQL_2008_SP4_EXPRESS"
    WINDOWS_SERVER_2012_R2_RTM_CHINESE_SIMPLIFIED_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_CHINESE_SIMPLIFIED_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_CHINESE_TRADITIONAL_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_CHINESE_TRADITIONAL_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_DUTCH_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_DUTCH_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_ENTERPRISE = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_ENTERPRISE"
    WINDOWS_SERVER_2012_R2_RTM_HUNGARIAN_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_HUNGARIAN_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_BASE"
    WINDOWS_SERVER_2016_ENGLISH_CORE_CONTAINERS = "WINDOWS_SERVER_2016_ENGLISH_CORE_CONTAINERS"
    WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_WEB = "WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_WEB"
    WINDOWS_SERVER_2016_GERMAL_FULL_BASE = "WINDOWS_SERVER_2016_GERMAL_FULL_BASE"
    WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_32BIT_BASE = "WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_32BIT_BASE"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_WEB = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_WEB"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_EXPRESS = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_EXPRESS"
    WINDOWS_SERVER_2012_R2_SP1_PORTUGESE_BRAZIL_64BIT_CORE = "WINDOWS_SERVER_2012_R2_SP1_PORTUGESE_BRAZIL_64BIT_CORE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_STANDARD = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_STANDARD"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_EXPRESS = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_EXPRESS"
    WINDOWS_SERVER_2012_RTM_ITALIAN_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_ITALIAN_64BIT_BASE"
    WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_EXPRESS = "WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_EXPRESS"
    WINDOWS_SERVER_2016_ENGLISH_DEEP_LEARNING = "WINDOWS_SERVER_2016_ENGLISH_DEEP_LEARNING"
    WINDOWS_SERVER_2019_ITALIAN_FULL_BASE = "WINDOWS_SERVER_2019_ITALIAN_FULL_BASE"
    WINDOWS_SERVER_2008_R2_SP1_KOREAN_64BIT_BASE = "WINDOWS_SERVER_2008_R2_SP1_KOREAN_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_EXPRESS = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_EXPRESS"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_WEB = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_WEB"
    WINDOWS_SERVER_2016_JAPANESE_FULL_FQL_2016_SP2_WEB = "WINDOWS_SERVER_2016_JAPANESE_FULL_FQL_2016_SP2_WEB"
    WINDOWS_SERVER_2016_KOREAN_FULL_BASE = "WINDOWS_SERVER_2016_KOREAN_FULL_BASE"
    WINDOWS_SERVER_2016_KOREAN_FULL_SQL_2016_SP2_STANDARD = "WINDOWS_SERVER_2016_KOREAN_FULL_SQL_2016_SP2_STANDARD"
    WINDOWS_SERVER_2016_PORTUGESE_PORTUGAL_FULL_BASE = "WINDOWS_SERVER_2016_PORTUGESE_PORTUGAL_FULL_BASE"
    WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_WEB = "WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_WEB"
    WINDOWS_SERVER_2019_FRENCH_FULL_BASE = "WINDOWS_SERVER_2019_FRENCH_FULL_BASE"
    WINDOWS_SERVER_2019_KOREAN_FULL_BASE = "WINDOWS_SERVER_2019_KOREAN_FULL_BASE"
    WINDOWS_SERVER_2008_R2_SP1_CHINESE_HONG_KONG_SAR_64BIT_BASE = "WINDOWS_SERVER_2008_R2_SP1_CHINESE_HONG_KONG_SAR_64BIT_BASE"
    WINDOWS_SERVER_2008_R2_SP1_CHINESE_PRC_64BIT_BASE = "WINDOWS_SERVER_2008_R2_SP1_CHINESE_PRC_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_FRENCH_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_FRENCH_64BIT_BASE"
    WINDOWS_SERVER_2016_ENGLISH_FULL_CONTAINERS = "WINDOWS_SERVER_2016_ENGLISH_FULL_CONTAINERS"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_STANDARD = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_STANDARD"
    WINDOWS_SERVER_2016_RUSSIAN_FULL_BASE = "WINDOWS_SERVER_2016_RUSSIAN_FULL_BASE"
    WINDOWS_SERVER_2019_CHINESE_SIMPLIFIED_FULL_BASE = "WINDOWS_SERVER_2019_CHINESE_SIMPLIFIED_FULL_BASE"
    WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_STANDARD = "WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_STANDARD"
    WINDOWS_SERVER_2019_HUNGARIAN_FULL_BASE = "WINDOWS_SERVER_2019_HUNGARIAN_FULL_BASE"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_EXPRESS = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_EXPRESS"
    WINDOWS_SERVER_2007_R2_SP1_LANGUAGE_PACKS_64BIT_BASE = "WINDOWS_SERVER_2007_R2_SP1_LANGUAGE_PACKS_64BIT_BASE"
    WINDOWS_SERVER_2008_SP2_ENGLISH_32BIT_BASE = "WINDOWS_SERVER_2008_SP2_ENGLISH_32BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE"
    WINDOWS_SERVER_2012_RTM_CHINESE_TRADITIONAL_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_CHINESE_TRADITIONAL_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2008_R2_SP3_EXPRESS = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2008_R2_SP3_EXPRESS"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_STANDARD = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_STANDARD"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_EXPRESS = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_EXPRESS"
    WINDOWS_SERVER_2016_POLISH_FULL_BASE = "WINDOWS_SERVER_2016_POLISH_FULL_BASE"
    WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_WEB = "WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_WEB"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_STANDARD = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_STANDARD"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_EXPRESS = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_EXPRESS"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_DEEP_LEARNING = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_DEEP_LEARNING"
    WINDOWS_SERVER_2012_R2_RTM_GERMAN_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_GERMAN_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_EXPRESS = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_EXPRESS"
    WINDOWS_SERVER_2012_R2_RTM_RUSSIAN_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_RUSSIAN_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_CHINESE_TRADITIONAL_HONG_KONG_SAR_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_CHINESE_TRADITIONAL_HONG_KONG_SAR_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_HUNGARIAN_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_HUNGARIAN_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_STANDARD = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_STANDARD"
    WINDOWS_SERVER_2019_ENGLISH_FULL_HYPERV = "WINDOWS_SERVER_2019_ENGLISH_FULL_HYPERV"
    WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_SQL_2005_SP4_EXPRESS = "WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_SQL_2005_SP4_EXPRESS"
    WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2012_SP4_EXPRESS = "WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2012_SP4_EXPRESS"
    WINDOWS_SERVER_2012_RTM_GERMAN_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_GERMAN_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2008_R2_SP3_STANDARD = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2008_R2_SP3_STANDARD"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_STANDARD = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_STANDARD"
    WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_EXPRESS = "WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_EXPRESS"
    WINDOWS_SERVER_2019_JAPANESE_FULL_BASE = "WINDOWS_SERVER_2019_JAPANESE_FULL_BASE"
    WINDOWS_SERVER_2019_RUSSIAN_FULL_BASE = "WINDOWS_SERVER_2019_RUSSIAN_FULL_BASE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_STANDARD = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_STANDARD"
    WINDOWS_SERVER_2012_R2_RTM_ITALIAN_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_ITALIAN_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2008_R2_SP3_STANDARD = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2008_R2_SP3_STANDARD"
    WINDOWS_SERVER_2016_ENGLISH_FULL_HYPERV = "WINDOWS_SERVER_2016_ENGLISH_FULL_HYPERV"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_ENTERPRISE = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_ENTERPRISE"
    WINDOWS_SERVER_2019_CHINESE_TRADITIONAL_FULL_BASE = "WINDOWS_SERVER_2019_CHINESE_TRADITIONAL_FULL_BASE"
    WINDOWS_SERVER_2019_ENGLISH_CORE_BASE = "WINDOWS_SERVER_2019_ENGLISH_CORE_BASE"
    WINDOWS_SERVER_2019_ENGLISH_CORE_CONTAINERSLATEST = "WINDOWS_SERVER_2019_ENGLISH_CORE_CONTAINERSLATEST"
    WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_BASE = "WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_FRENCH_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_FRENCH_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_POLISH_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_POLISH_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_EXPRESS = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_EXPRESS"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP3_STANDARD = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP3_STANDARD"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_2012_SP4_STANDARD = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_2012_SP4_STANDARD"
    WINDOWS_SERVER_2016_ENGLISH_CORE_CONTAINERSLATEST = "WINDOWS_SERVER_2016_ENGLISH_CORE_CONTAINERSLATEST"
    WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_EXPRESS = "WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_EXPRESS"
    WINDOWS_SERVER_2019_TURKISH_FULL_BASE = "WINDOWS_SERVER_2019_TURKISH_FULL_BASE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_EXPRESS = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_EXPRESS"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_WEB = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_WEB"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_WEB = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_WEB"
    WINDOWS_SERVER_2012_R2_RTM_PORTUGESE_BRAZIL_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_PORTUGESE_BRAZIL_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_PORTUGESE_PORTUGAL_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_PORTUGESE_PORTUGAL_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_SWEDISH_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_SWEDISH_64BIT_BASE"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_EXPRESS = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_EXPRESS"
    WINDOWS_SERVER_2016_ITALIAN_FULL_BASE = "WINDOWS_SERVER_2016_ITALIAN_FULL_BASE"
    WINDOWS_SERVER_2016_SPANISH_FULL_BASE = "WINDOWS_SERVER_2016_SPANISH_FULL_BASE"
    WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_STANDARD = "WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_STANDARD"
    WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_SQL_2005_SP4_STANDARD = "WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_SQL_2005_SP4_STANDARD"
    WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_STANDARD = "WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_STANDARD"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_STANDARD = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_STANDARD"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2007_R2_SP3_WEB = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2007_R2_SP3_WEB"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_WEB = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_WEB"
    WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_ENTERPRISE = "WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_ENTERPRISE"
    WINDOWS_SERVER_2016_PORTUGESE_BRAZIL_FULL_BASE = "WINDOWS_SERVER_2016_PORTUGESE_BRAZIL_FULL_BASE"
    WINDOWS_SERVER_2019_ENGLISH_FULL_BASE = "WINDOWS_SERVER_2019_ENGLISH_FULL_BASE"
    WINDOWS_SERVER_2003_R2_SP2_ENGLISH_32BIT_BASE = "WINDOWS_SERVER_2003_R2_SP2_ENGLISH_32BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_CZECH_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_CZECH_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_STANDARD = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_STANDARD"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP2_EXPRESS = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP2_EXPRESS"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_STANDARD = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_STANDARD"
    WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_ENTERPRISE = "WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_ENTERPRISE"
    WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_WEB = "WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_WEB"
    WINDOWS_SERVER_2016_SWEDISH_FULL_BASE = "WINDOWS_SERVER_2016_SWEDISH_FULL_BASE"
    WINDOWS_SERVER_2016_TURKISH_FULL_BASE = "WINDOWS_SERVER_2016_TURKISH_FULL_BASE"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_CORE_SQL_2012_SP4_STANDARD = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_CORE_SQL_2012_SP4_STANDARD"
    WINDOWS_SERVER_2008_R2_SP1_LANGUAGE_PACKS_64BIT_SQL_2008_R2_SP3_STANDARD = "WINDOWS_SERVER_2008_R2_SP1_LANGUAGE_PACKS_64BIT_SQL_2008_R2_SP3_STANDARD"
    WINDOWS_SERVER_2012_RTM_CZECH_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_CZECH_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_TURKISH_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_TURKISH_64BIT_BASE"
    WINDOWS_SERVER_2016_DUTCH_FULL_BASE = "WINDOWS_SERVER_2016_DUTCH_FULL_BASE"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_EXPRESS = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_EXPRESS"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_ENTERPRISE = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_ENTERPRISE"
    WINDOWS_SERVER_2016_HUNGARIAN_FULL_BASE = "WINDOWS_SERVER_2016_HUNGARIAN_FULL_BASE"
    WINDOWS_SERVER_2016_KOREAN_FULL_SQL_2016_SP1_STANDARD = "WINDOWS_SERVER_2016_KOREAN_FULL_SQL_2016_SP1_STANDARD"
    WINDOWS_SERVER_2019_SPANISH_FULL_BASE = "WINDOWS_SERVER_2019_SPANISH_FULL_BASE"
    WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_BASE = "WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_BASE"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_BASE = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_BASE"
    WINDOWS_SERVER_2008_R2_SP1_LANGUAGE_PACKS_64BIT_SQL_2008_R2_SP3_EXPRESS = "WINDOWS_SERVER_2008_R2_SP1_LANGUAGE_PACKS_64BIT_SQL_2008_R2_SP3_EXPRESS"
    WINDOWS_SERVER_2012_SP2_PORTUGESE_BRAZIL_64BIT_BASE = "WINDOWS_SERVER_2012_SP2_PORTUGESE_BRAZIL_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_WEB = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_WEB"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP3_EXPRESS = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP3_EXPRESS"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_ENTERPRISE = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_ENTERPRISE"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_BASE"
    WINDOWS_SERVER_2019_ENGLISH_FULL_CONTAINERSLATEST = "WINDOWS_SERVER_2019_ENGLISH_FULL_CONTAINERSLATEST"
    WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_ENTERPRISE = "WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_ENTERPRISE"
    WINDOWS_SERVER_1709_ENGLISH_CORE_CONTAINERSLATEST = "WINDOWS_SERVER_1709_ENGLISH_CORE_CONTAINERSLATEST"
    WINDOWS_SERVER_1803_ENGLISH_CORE_BASE = "WINDOWS_SERVER_1803_ENGLISH_CORE_BASE"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_WEB = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_WEB"
    WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_BASE = "WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_BASE"
    WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_SQL_2008_SP4_STANDARD = "WINDOWS_SERVER_2008_SP2_ENGLISH_64BIT_SQL_2008_SP4_STANDARD"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_PORTUGESE_BRAZIL_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_PORTUGESE_BRAZIL_64BIT_BASE"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_WEB = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_WEB"
    WINDOWS_SERVER_2016_ENGLISH_P3 = "WINDOWS_SERVER_2016_ENGLISH_P3"
    WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_ENTERPRISE = "WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_ENTERPRISE"
    WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_BASE = "WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_CHINESE_TRADITIONAL_HONG_KONG_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_CHINESE_TRADITIONAL_HONG_KONG_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_EXPRESS = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_EXPRESS"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_ENTERPRISE = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_ENTERPRISE"
    WINDOWS_SERVER_2012_RTM_CHINESE_SIMPLIFIED_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_CHINESE_SIMPLIFIED_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_WEB = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_SP4_WEB"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_WEB = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_WEB"
    WINDOWS_SERVER_2016_JAPANESE_FULL_BASE = "WINDOWS_SERVER_2016_JAPANESE_FULL_BASE"
    WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_EXPRESS = "WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_EXPRESS"
    WINDOWS_SERVER_1803_ENGLISH_CORE_CONTAINERSLATEST = "WINDOWS_SERVER_1803_ENGLISH_CORE_CONTAINERSLATEST"
    WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2012_SP4_STANDARD = "WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2012_SP4_STANDARD"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_CORE = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_CORE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_WEB = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP2_WEB"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_ENTERPRISE = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_SP3_ENTERPRISE"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_STANDARD = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP2_STANDARD"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_2014_SP3_WEB = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_2014_SP3_WEB"
    WINDOWS_SERVER_2012_RTM_SWEDISH_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_SWEDISH_64BIT_BASE"
    WINDOWS_SERVER_2016_CHINESE_SIMPLIFIED_FULL_BASE = "WINDOWS_SERVER_2016_CHINESE_SIMPLIFIED_FULL_BASE"
    WINDOWS_SERVER_2019_POLISH_FULL_BASE = "WINDOWS_SERVER_2019_POLISH_FULL_BASE"
    WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_WEB = "WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_WEB"
    WINDOWS_SERVER_2008_R2_SP1_PORTUGESE_BRAZIL_64BIT_BASE = "WINDOWS_SERVER_2008_R2_SP1_PORTUGESE_BRAZIL_64BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_ENTERPRISE = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2016_SP1_ENTERPRISE"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2016_SP2_EXPRESS = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2016_SP2_EXPRESS"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP3_EXPRESS = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP3_EXPRESS"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_STANDARD = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP2_STANDARD"
    WINDOWS_SERVER_2016_ENGLISH_CORE_BASE = "WINDOWS_SERVER_2016_ENGLISH_CORE_BASE"
    WINDOWS_SERVER_2016_ENGLISH_FULL_BASE = "WINDOWS_SERVER_2016_ENGLISH_FULL_BASE"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_WEB = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_WEB"
    WINDOWS_SERVER_2019_GERMAN_FULL_BASE = "WINDOWS_SERVER_2019_GERMAN_FULL_BASE"
    WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_SQL_2005_SP4_STANDARD = "WINDOWS_SERVER_2003_R2_SP2_ENGLISH_64BIT_SQL_2005_SP4_STANDARD"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE"
    WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_EXPRESS = "WINDOWS_SERVER_2008_R2_SP1_JAPANESE_64BIT_SQL_2008_R2_SP3_EXPRESS"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_ENTERPRISE = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP1_ENTERPRISE"
    WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_WEB = "WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2014_SP2_WEB"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2008_R2_SP3_EXPRESS = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2008_R2_SP3_EXPRESS"
    WINDOWS_SERVER_2016_FRENCH_FULL_BASE = "WINDOWS_SERVER_2016_FRENCH_FULL_BASE"
    WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_ENTERPRISE = "WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_ENTERPRISE"
    WINDOWS_SERVER_2019_CZECH_FULL_BASE = "WINDOWS_SERVER_2019_CZECH_FULL_BASE"
    WINDOWS_SERVER_1809_ENGLISH_CORE_BASE = "WINDOWS_SERVER_1809_ENGLISH_CORE_BASE"
    WINDOWS_SERVER_1809_ENGLISH_CORE_CONTAINERSLATEST = "WINDOWS_SERVER_1809_ENGLISH_CORE_CONTAINERSLATEST"
    WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_SQL_2005_SP4_EXPRESS = "WINDOWS_SERVER_2003_R2_SP2_LANGUAGE_PACKS_64BIT_SQL_2005_SP4_EXPRESS"
    WINDOWS_SERVER_2012_R2_RTM_TURKISH_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_TURKISH_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2012_SP4_WEB = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2012_SP4_WEB"
    WINDOWS_SERVER_2012_RTM_POLISH_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_POLISH_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_SPANISH_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_SPANISH_64BIT_BASE"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_ENTERPRISE = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP1_ENTERPRISE"
    WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_EXPRESS = "WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_EXPRESS"
    WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_ENTERPRISE = "WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2016_SP2_ENTERPRISE"
    WINDOWS_SERVER_1709_ENGLISH_CORE_BASE = "WINDOWS_SERVER_1709_ENGLISH_CORE_BASE"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_61BIT_SQL_2012_RTM_SP2_ENTERPRISE = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_61BIT_SQL_2012_RTM_SP2_ENTERPRISE"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_STANDARD = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2012_SP4_STANDARD"
    WINDOWS_SERVER_2008_SP2_PORTUGESE_BRAZIL_32BIT_BASE = "WINDOWS_SERVER_2008_SP2_PORTUGESE_BRAZIL_32BIT_BASE"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP2_STANDARD = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP2_STANDARD"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2012_SP4_EXPRESS = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2012_SP4_EXPRESS"
    WINDOWS_SERVER_2012_RTM_PORTUGESE_PORTUGAL_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_PORTUGESE_PORTUGAL_64BIT_BASE"
    WINDOWS_SERVER_2016_CZECH_FULL_BASE = "WINDOWS_SERVER_2016_CZECH_FULL_BASE"
    WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_STANDARD = "WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP1_STANDARD"
    WINDOWS_SERVER_2019_DUTCH_FULL_BASE = "WINDOWS_SERVER_2019_DUTCH_FULL_BASE"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_CORE = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_CORE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_WEB = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2016_SP2_WEB"
    WINDOWS_SERVER_2012_R2_RTM_KOREAN_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_KOREAN_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_DUTCH_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_DUTCH_64BIT_BASE"
    WINDOWS_SERVER_2016_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE = "WINDOWS_SERVER_2016_ENGLISH_64BIT_SQL_2012_SP4_ENTERPRISE"
    WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_STANDARD = "WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP1_STANDARD"
    WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_EXPRESS = "WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_EXPRESS"
    WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_WEB = "WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_WEB"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_STANDARD = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_STANDARD"
    WINDOWS_SERVER_2019_PORTUGESE_BRAZIL_FULL_BASE = "WINDOWS_SERVER_2019_PORTUGESE_BRAZIL_FULL_BASE"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_STANDARD = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_R2_SP3_STANDARD"
    WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SHAREPOINT_2010_SP2_FOUNDATION = "WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SHAREPOINT_2010_SP2_FOUNDATION"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_P3 = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_P3"
    WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP3_STANDARD = "WINDOWS_SERVER_2012_R2_RTM_JAPANESE_64BIT_SQL_2014_SP3_STANDARD"
    WINDOWS_SERVER_2012_R2_RTM_SPANISH_64BIT_BASE = "WINDOWS_SERVER_2012_R2_RTM_SPANISH_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_EXPRESS = "WINDOWS_SERVER_2012_RTM_JAPANESE_64BIT_SQL_2014_SP3_EXPRESS"
    WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_STANDARD = "WINDOWS_SERVER_2016_ENGLISH_CORE_SQL_2016_SP2_STANDARD"
    WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_STANDARD = "WINDOWS_SERVER_2016_JAPANESE_FULL_SQL_2016_SP2_STANDARD"
    WINDOWS_SERVER_2019_PORTUGESE_PORTUGAL_FULL_BASE = "WINDOWS_SERVER_2019_PORTUGESE_PORTUGAL_FULL_BASE"
    WINDOWS_SERVER_2019_SWEDISH_FULL_BASE = "WINDOWS_SERVER_2019_SWEDISH_FULL_BASE"
    WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_HYPERV = "WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_HYPERV"
    WINDOWS_SERVER_2012_RTM_KOREAN_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_KOREAN_64BIT_BASE"
    WINDOWS_SERVER_2012_RTM_RUSSIAN_64BIT_BASE = "WINDOWS_SERVER_2012_RTM_RUSSIAN_64BIT_BASE"
    WINDOWS_SERVER_2016_CHINESE_TRADITIONAL_FULL_BASE = "WINDOWS_SERVER_2016_CHINESE_TRADITIONAL_FULL_BASE"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_WEB = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_SP2_WEB"
    WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_EXPRESS = "WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2017_EXPRESS"


@jsii.implements(IInstance)
class BastionHostLinux(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.BastionHostLinux",
):
    '''(experimental) This creates a linux bastion host you can use to connect to other instances or services in your VPC.

    The recommended way to connect to the bastion host is by using AWS Systems Manager Session Manager.

    The operating system is Amazon Linux 2 with the latest SSM agent installed

    You can also configure this bastion host to allow connections via SSH

    :stability: experimental
    :resource: AWS::EC2::Instance
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        vpc: IVpc,
        availability_zone: typing.Optional[builtins.str] = None,
        block_devices: typing.Optional[typing.List[BlockDevice]] = None,
        instance_name: typing.Optional[builtins.str] = None,
        instance_type: typing.Optional[InstanceType] = None,
        machine_image: typing.Optional[IMachineImage] = None,
        security_group: typing.Optional[ISecurityGroup] = None,
        subnet_selection: typing.Optional[SubnetSelection] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param vpc: (experimental) VPC to launch the instance in.
        :param availability_zone: (experimental) In which AZ to place the instance within the VPC. Default: - Random zone.
        :param block_devices: (experimental) Specifies how block devices are exposed to the instance. You can specify virtual devices and EBS volumes. Each instance that is launched has an associated root device volume, either an Amazon EBS volume or an instance store volume. You can use block device mappings to specify additional EBS volumes or instance store volumes to attach to an instance when it is launched. Default: - Uses the block device mapping of the AMI
        :param instance_name: (experimental) The name of the instance. Default: 'BastionHost'
        :param instance_type: (experimental) Type of instance to launch. Default: 't3.nano'
        :param machine_image: (experimental) The machine image to use, assumed to have SSM Agent preinstalled. Default: - An Amazon Linux 2 image which is kept up-to-date automatically (the instance may be replaced on every deployment) and already has SSM Agent installed.
        :param security_group: (experimental) Security Group to assign to this instance. Default: - create new security group with no inbound and all outbound traffic allowed
        :param subnet_selection: (experimental) Select the subnets to run the bastion host in. Set this to PUBLIC if you need to connect to this instance via the internet and cannot use SSM. You have to allow port 22 manually by using the connections field Default: - private subnets of the supplied VPC

        :stability: experimental
        '''
        props = BastionHostLinuxProps(
            vpc=vpc,
            availability_zone=availability_zone,
            block_devices=block_devices,
            instance_name=instance_name,
            instance_type=instance_type,
            machine_image=machine_image,
            security_group=security_group,
            subnet_selection=subnet_selection,
        )

        jsii.create(BastionHostLinux, self, [scope, id, props])

    @jsii.member(jsii_name="allowSshAccessFrom")
    def allow_ssh_access_from(self, *peer: IPeer) -> None:
        '''(experimental) Allow SSH access from the given peer or peers.

        Necessary if you want to connect to the instance using ssh. If not
        called, you should use SSM Session Manager to connect to the instance.

        :param peer: -

        :stability: experimental
        '''
        return typing.cast(None, jsii.invoke(self, "allowSshAccessFrom", [*peer]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connections")
    def connections(self) -> "Connections":
        '''(experimental) Allows specify security group connections for the instance.

        :stability: experimental
        '''
        return typing.cast("Connections", jsii.get(self, "connections"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="grantPrincipal")
    def grant_principal(self) -> aws_cdk.aws_iam.IPrincipal:
        '''(experimental) The principal to grant permissions to.

        :stability: experimental
        '''
        return typing.cast(aws_cdk.aws_iam.IPrincipal, jsii.get(self, "grantPrincipal"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instance")
    def instance(self) -> Instance:
        '''(experimental) The underlying instance resource.

        :stability: experimental
        '''
        return typing.cast(Instance, jsii.get(self, "instance"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceAvailabilityZone")
    def instance_availability_zone(self) -> builtins.str:
        '''(experimental) The availability zone the instance was launched in.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instanceAvailabilityZone"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instanceId")
    def instance_id(self) -> builtins.str:
        '''(experimental) The instance's ID.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instanceId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePrivateDnsName")
    def instance_private_dns_name(self) -> builtins.str:
        '''(experimental) Private DNS name for this instance.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePrivateDnsName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePrivateIp")
    def instance_private_ip(self) -> builtins.str:
        '''(experimental) Private IP for this instance.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePrivateIp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePublicDnsName")
    def instance_public_dns_name(self) -> builtins.str:
        '''(experimental) Publicly-routable DNS name for this instance.

        (May be an empty string if the instance does not have a public name).

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePublicDnsName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="instancePublicIp")
    def instance_public_ip(self) -> builtins.str:
        '''(experimental) Publicly-routable IP  address for this instance.

        (May be an empty string if the instance does not have a public IP).

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "instancePublicIp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="role")
    def role(self) -> aws_cdk.aws_iam.IRole:
        '''(experimental) The IAM role assumed by the instance.

        :stability: experimental
        '''
        return typing.cast(aws_cdk.aws_iam.IRole, jsii.get(self, "role"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="stack")
    def stack(self) -> aws_cdk.core.Stack:
        '''(experimental) The stack in which this resource is defined.

        :stability: experimental
        '''
        return typing.cast(aws_cdk.core.Stack, jsii.get(self, "stack"))


@jsii.implements(IConnectable)
class Connections(metaclass=jsii.JSIIMeta, jsii_type="@aws-cdk/aws-ec2.Connections"):
    '''Manage the allowed network connections for constructs with Security Groups.

    Security Groups can be thought of as a firewall for network-connected
    devices. This class makes it easy to allow network connections to and
    from security groups, and between security groups individually. When
    establishing connectivity between security groups, it will automatically
    add rules in both security groups

    This object can manage one or more security groups.
    '''

    def __init__(
        self,
        *,
        default_port: typing.Optional[Port] = None,
        peer: typing.Optional[IPeer] = None,
        security_groups: typing.Optional[typing.List[ISecurityGroup]] = None,
    ) -> None:
        '''
        :param default_port: Default port range for initiating connections to and from this object. Default: - No default port
        :param peer: Class that represents the rule by which others can connect to this connectable. This object is required, but will be derived from securityGroup if that is passed. Default: Derived from securityGroup if set.
        :param security_groups: What securityGroup(s) this object is managing connections for. Default: No security groups
        '''
        props = ConnectionsProps(
            default_port=default_port, peer=peer, security_groups=security_groups
        )

        jsii.create(Connections, self, [props])

    @jsii.member(jsii_name="addSecurityGroup")
    def add_security_group(self, *security_groups: ISecurityGroup) -> None:
        '''Add a security group to the list of security groups managed by this object.

        :param security_groups: -
        '''
        return typing.cast(None, jsii.invoke(self, "addSecurityGroup", [*security_groups]))

    @jsii.member(jsii_name="allowDefaultPortFrom")
    def allow_default_port_from(
        self,
        other: IConnectable,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Allow connections from the peer on our default port.

        Even if the peer has a default port, we will always use our default port.

        :param other: -
        :param description: -
        '''
        return typing.cast(None, jsii.invoke(self, "allowDefaultPortFrom", [other, description]))

    @jsii.member(jsii_name="allowDefaultPortFromAnyIpv4")
    def allow_default_port_from_any_ipv4(
        self,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Allow default connections from all IPv4 ranges.

        :param description: -
        '''
        return typing.cast(None, jsii.invoke(self, "allowDefaultPortFromAnyIpv4", [description]))

    @jsii.member(jsii_name="allowDefaultPortInternally")
    def allow_default_port_internally(
        self,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Allow hosts inside the security group to connect to each other.

        :param description: -
        '''
        return typing.cast(None, jsii.invoke(self, "allowDefaultPortInternally", [description]))

    @jsii.member(jsii_name="allowDefaultPortTo")
    def allow_default_port_to(
        self,
        other: IConnectable,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Allow connections from the peer on our default port.

        Even if the peer has a default port, we will always use our default port.

        :param other: -
        :param description: -
        '''
        return typing.cast(None, jsii.invoke(self, "allowDefaultPortTo", [other, description]))

    @jsii.member(jsii_name="allowFrom")
    def allow_from(
        self,
        other: IConnectable,
        port_range: Port,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Allow connections from the peer on the given port.

        :param other: -
        :param port_range: -
        :param description: -
        '''
        return typing.cast(None, jsii.invoke(self, "allowFrom", [other, port_range, description]))

    @jsii.member(jsii_name="allowFromAnyIpv4")
    def allow_from_any_ipv4(
        self,
        port_range: Port,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Allow from any IPv4 ranges.

        :param port_range: -
        :param description: -
        '''
        return typing.cast(None, jsii.invoke(self, "allowFromAnyIpv4", [port_range, description]))

    @jsii.member(jsii_name="allowInternally")
    def allow_internally(
        self,
        port_range: Port,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Allow hosts inside the security group to connect to each other on the given port.

        :param port_range: -
        :param description: -
        '''
        return typing.cast(None, jsii.invoke(self, "allowInternally", [port_range, description]))

    @jsii.member(jsii_name="allowTo")
    def allow_to(
        self,
        other: IConnectable,
        port_range: Port,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Allow connections to the peer on the given port.

        :param other: -
        :param port_range: -
        :param description: -
        '''
        return typing.cast(None, jsii.invoke(self, "allowTo", [other, port_range, description]))

    @jsii.member(jsii_name="allowToAnyIpv4")
    def allow_to_any_ipv4(
        self,
        port_range: Port,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Allow to all IPv4 ranges.

        :param port_range: -
        :param description: -
        '''
        return typing.cast(None, jsii.invoke(self, "allowToAnyIpv4", [port_range, description]))

    @jsii.member(jsii_name="allowToDefaultPort")
    def allow_to_default_port(
        self,
        other: IConnectable,
        description: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Allow connections to the security group on their default port.

        :param other: -
        :param description: -
        '''
        return typing.cast(None, jsii.invoke(self, "allowToDefaultPort", [other, description]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connections")
    def connections(self) -> "Connections":
        return typing.cast("Connections", jsii.get(self, "connections"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroups")
    def security_groups(self) -> typing.List[ISecurityGroup]:
        return typing.cast(typing.List[ISecurityGroup], jsii.get(self, "securityGroups"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="defaultPort")
    def default_port(self) -> typing.Optional[Port]:
        '''The default port configured for this connection peer, if available.'''
        return typing.cast(typing.Optional[Port], jsii.get(self, "defaultPort"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.EbsDeviceOptions",
    jsii_struct_bases=[EbsDeviceOptionsBase],
    name_mapping={
        "delete_on_termination": "deleteOnTermination",
        "iops": "iops",
        "volume_type": "volumeType",
        "encrypted": "encrypted",
    },
)
class EbsDeviceOptions(EbsDeviceOptionsBase):
    def __init__(
        self,
        *,
        delete_on_termination: typing.Optional[builtins.bool] = None,
        iops: typing.Optional[jsii.Number] = None,
        volume_type: typing.Optional[EbsDeviceVolumeType] = None,
        encrypted: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Block device options for an EBS volume.

        :param delete_on_termination: Indicates whether to delete the volume when the instance is terminated. Default: - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS)
        :param iops: The number of I/O operations per second (IOPS) to provision for the volume. Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1} The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS, you need at least 100 GiB storage on the volume. Default: - none, required for {@link EbsDeviceVolumeType.IO1}
        :param volume_type: The EBS volume type. Default: {@link EbsDeviceVolumeType.GP2}
        :param encrypted: Specifies whether the EBS volume is encrypted. Encrypted EBS volumes can only be attached to instances that support Amazon EBS encryption Default: false
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if delete_on_termination is not None:
            self._values["delete_on_termination"] = delete_on_termination
        if iops is not None:
            self._values["iops"] = iops
        if volume_type is not None:
            self._values["volume_type"] = volume_type
        if encrypted is not None:
            self._values["encrypted"] = encrypted

    @builtins.property
    def delete_on_termination(self) -> typing.Optional[builtins.bool]:
        '''Indicates whether to delete the volume when the instance is terminated.

        :default: - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS)
        '''
        result = self._values.get("delete_on_termination")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def iops(self) -> typing.Optional[jsii.Number]:
        '''The number of I/O operations per second (IOPS) to provision for the volume.

        Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1}

        The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS,
        you need at least 100 GiB storage on the volume.

        :default: - none, required for {@link EbsDeviceVolumeType.IO1}

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
        '''
        result = self._values.get("iops")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def volume_type(self) -> typing.Optional[EbsDeviceVolumeType]:
        '''The EBS volume type.

        :default: {@link EbsDeviceVolumeType.GP2}

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
        '''
        result = self._values.get("volume_type")
        return typing.cast(typing.Optional[EbsDeviceVolumeType], result)

    @builtins.property
    def encrypted(self) -> typing.Optional[builtins.bool]:
        '''Specifies whether the EBS volume is encrypted.

        Encrypted EBS volumes can only be attached to instances that support Amazon EBS encryption

        :default: false

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html#EBSEncryption_supported_instances
        '''
        result = self._values.get("encrypted")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EbsDeviceOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.EbsDeviceProps",
    jsii_struct_bases=[EbsDeviceSnapshotOptions],
    name_mapping={
        "delete_on_termination": "deleteOnTermination",
        "iops": "iops",
        "volume_type": "volumeType",
        "volume_size": "volumeSize",
        "snapshot_id": "snapshotId",
    },
)
class EbsDeviceProps(EbsDeviceSnapshotOptions):
    def __init__(
        self,
        *,
        delete_on_termination: typing.Optional[builtins.bool] = None,
        iops: typing.Optional[jsii.Number] = None,
        volume_type: typing.Optional[EbsDeviceVolumeType] = None,
        volume_size: typing.Optional[jsii.Number] = None,
        snapshot_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties of an EBS block device.

        :param delete_on_termination: Indicates whether to delete the volume when the instance is terminated. Default: - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS)
        :param iops: The number of I/O operations per second (IOPS) to provision for the volume. Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1} The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS, you need at least 100 GiB storage on the volume. Default: - none, required for {@link EbsDeviceVolumeType.IO1}
        :param volume_type: The EBS volume type. Default: {@link EbsDeviceVolumeType.GP2}
        :param volume_size: The volume size, in Gibibytes (GiB). If you specify volumeSize, it must be equal or greater than the size of the snapshot. Default: - The snapshot size
        :param snapshot_id: The snapshot ID of the volume to use. Default: - No snapshot will be used
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if delete_on_termination is not None:
            self._values["delete_on_termination"] = delete_on_termination
        if iops is not None:
            self._values["iops"] = iops
        if volume_type is not None:
            self._values["volume_type"] = volume_type
        if volume_size is not None:
            self._values["volume_size"] = volume_size
        if snapshot_id is not None:
            self._values["snapshot_id"] = snapshot_id

    @builtins.property
    def delete_on_termination(self) -> typing.Optional[builtins.bool]:
        '''Indicates whether to delete the volume when the instance is terminated.

        :default: - true for Amazon EC2 Auto Scaling, false otherwise (e.g. EBS)
        '''
        result = self._values.get("delete_on_termination")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def iops(self) -> typing.Optional[jsii.Number]:
        '''The number of I/O operations per second (IOPS) to provision for the volume.

        Must only be set for {@link volumeType}: {@link EbsDeviceVolumeType.IO1}

        The maximum ratio of IOPS to volume size (in GiB) is 50:1, so for 5,000 provisioned IOPS,
        you need at least 100 GiB storage on the volume.

        :default: - none, required for {@link EbsDeviceVolumeType.IO1}

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
        '''
        result = self._values.get("iops")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def volume_type(self) -> typing.Optional[EbsDeviceVolumeType]:
        '''The EBS volume type.

        :default: {@link EbsDeviceVolumeType.GP2}

        :see: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
        '''
        result = self._values.get("volume_type")
        return typing.cast(typing.Optional[EbsDeviceVolumeType], result)

    @builtins.property
    def volume_size(self) -> typing.Optional[jsii.Number]:
        '''The volume size, in Gibibytes (GiB).

        If you specify volumeSize, it must be equal or greater than the size of the snapshot.

        :default: - The snapshot size
        '''
        result = self._values.get("volume_size")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def snapshot_id(self) -> typing.Optional[builtins.str]:
        '''The snapshot ID of the volume to use.

        :default: - No snapshot will be used
        '''
        result = self._values.get("snapshot_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EbsDeviceProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.EnableVpnGatewayOptions",
    jsii_struct_bases=[VpnGatewayProps],
    name_mapping={
        "type": "type",
        "amazon_side_asn": "amazonSideAsn",
        "vpn_route_propagation": "vpnRoutePropagation",
    },
)
class EnableVpnGatewayOptions(VpnGatewayProps):
    def __init__(
        self,
        *,
        type: builtins.str,
        amazon_side_asn: typing.Optional[jsii.Number] = None,
        vpn_route_propagation: typing.Optional[typing.List[SubnetSelection]] = None,
    ) -> None:
        '''Options for the Vpc.enableVpnGateway() method.

        :param type: Default type ipsec.1.
        :param amazon_side_asn: Explicitly specify an Asn or let aws pick an Asn for you. Default: 65000
        :param vpn_route_propagation: Provide an array of subnets where the route propagation should be added. Default: noPropagation
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "type": type,
        }
        if amazon_side_asn is not None:
            self._values["amazon_side_asn"] = amazon_side_asn
        if vpn_route_propagation is not None:
            self._values["vpn_route_propagation"] = vpn_route_propagation

    @builtins.property
    def type(self) -> builtins.str:
        '''Default type ipsec.1.'''
        result = self._values.get("type")
        assert result is not None, "Required property 'type' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def amazon_side_asn(self) -> typing.Optional[jsii.Number]:
        '''Explicitly specify an Asn or let aws pick an Asn for you.

        :default: 65000
        '''
        result = self._values.get("amazon_side_asn")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def vpn_route_propagation(self) -> typing.Optional[typing.List[SubnetSelection]]:
        '''Provide an array of subnets where the route propagation should be added.

        :default: noPropagation
        '''
        result = self._values.get("vpn_route_propagation")
        return typing.cast(typing.Optional[typing.List[SubnetSelection]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EnableVpnGatewayOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IFlowLog)
class FlowLog(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.FlowLog",
):
    '''(experimental) A VPC flow log.

    :stability: experimental
    :resource: AWS::EC2::FlowLog
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        resource_type: FlowLogResourceType,
        flow_log_name: typing.Optional[builtins.str] = None,
        destination: typing.Optional[FlowLogDestination] = None,
        traffic_type: typing.Optional[FlowLogTrafficType] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param resource_type: (experimental) The type of resource for which to create the flow log.
        :param flow_log_name: (experimental) The name of the FlowLog. It is not recommended to use an explicit name. Default: If you don't specify a flowLogName, AWS CloudFormation generates a unique physical ID and uses that ID for the group name.
        :param destination: (experimental) Specifies the type of destination to which the flow log data is to be published. Flow log data can be published to CloudWatch Logs or Amazon S3 Default: FlowLogDestinationType.toCloudWatchLogs()
        :param traffic_type: (experimental) The type of traffic to log. You can log traffic that the resource accepts or rejects, or all traffic. Default: ALL

        :stability: experimental
        '''
        props = FlowLogProps(
            resource_type=resource_type,
            flow_log_name=flow_log_name,
            destination=destination,
            traffic_type=traffic_type,
        )

        jsii.create(FlowLog, self, [scope, id, props])

    @jsii.member(jsii_name="fromFlowLogId") # type: ignore[misc]
    @builtins.classmethod
    def from_flow_log_id(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        flow_log_id: builtins.str,
    ) -> IFlowLog:
        '''(experimental) Import a Flow Log by it's Id.

        :param scope: -
        :param id: -
        :param flow_log_id: -

        :stability: experimental
        '''
        return typing.cast(IFlowLog, jsii.sinvoke(cls, "fromFlowLogId", [scope, id, flow_log_id]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="flowLogId")
    def flow_log_id(self) -> builtins.str:
        '''(experimental) The Id of the VPC Flow Log.

        :stability: experimental
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "flowLogId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="bucket")
    def bucket(self) -> typing.Optional[aws_cdk.aws_s3.IBucket]:
        '''(experimental) The S3 bucket to publish flow logs to.

        :stability: experimental
        '''
        return typing.cast(typing.Optional[aws_cdk.aws_s3.IBucket], jsii.get(self, "bucket"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="iamRole")
    def iam_role(self) -> typing.Optional[aws_cdk.aws_iam.IRole]:
        '''(experimental) The iam role used to publish logs to CloudWatch.

        :stability: experimental
        '''
        return typing.cast(typing.Optional[aws_cdk.aws_iam.IRole], jsii.get(self, "iamRole"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="keyPrefix")
    def key_prefix(self) -> typing.Optional[builtins.str]:
        '''(experimental) S3 bucket key prefix to publish the flow logs under.

        :stability: experimental
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "keyPrefix"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="logGroup")
    def log_group(self) -> typing.Optional[aws_cdk.aws_logs.ILogGroup]:
        '''(experimental) The CloudWatch Logs LogGroup to publish flow logs to.

        :stability: experimental
        '''
        return typing.cast(typing.Optional[aws_cdk.aws_logs.ILogGroup], jsii.get(self, "logGroup"))


@jsii.implements(IGatewayVpcEndpointService)
class GatewayVpcEndpointAwsService(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.GatewayVpcEndpointAwsService",
):
    '''An AWS service for a gateway VPC endpoint.'''

    def __init__(
        self,
        name: builtins.str,
        prefix: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param name: -
        :param prefix: -
        '''
        jsii.create(GatewayVpcEndpointAwsService, self, [name, prefix])

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="DYNAMODB")
    def DYNAMODB(cls) -> "GatewayVpcEndpointAwsService":
        return typing.cast("GatewayVpcEndpointAwsService", jsii.sget(cls, "DYNAMODB"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="S3")
    def S3(cls) -> "GatewayVpcEndpointAwsService":
        return typing.cast("GatewayVpcEndpointAwsService", jsii.sget(cls, "S3"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="name")
    def name(self) -> builtins.str:
        '''The name of the service.'''
        return typing.cast(builtins.str, jsii.get(self, "name"))


@jsii.implements(IMachineImage)
class GenericLinuxImage(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.GenericLinuxImage",
):
    '''Construct a Linux machine image from an AMI map.

    Linux images IDs are not published to SSM parameter store yet, so you'll have to
    manually specify an AMI map.
    '''

    def __init__(
        self,
        ami_map: typing.Mapping[builtins.str, builtins.str],
        *,
        user_data: typing.Optional[UserData] = None,
    ) -> None:
        '''
        :param ami_map: -
        :param user_data: Initial user data. Default: - Empty UserData for Linux machines
        '''
        props = GenericLinuxImageProps(user_data=user_data)

        jsii.create(GenericLinuxImage, self, [ami_map, props])

    @jsii.member(jsii_name="getImage")
    def get_image(self, scope: aws_cdk.core.Construct) -> MachineImageConfig:
        '''Return the image to use in the given context.

        :param scope: -
        '''
        return typing.cast(MachineImageConfig, jsii.invoke(self, "getImage", [scope]))


@jsii.implements(IMachineImage)
class GenericSSMParameterImage(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.GenericSSMParameterImage",
):
    '''Select the image based on a given SSM parameter.

    This Machine Image automatically updates to the latest version on every
    deployment. Be aware this will cause your instances to be replaced when a
    new version of the image becomes available. Do not store stateful information
    on the instance if you are using this image.

    The AMI ID is selected using the values published to the SSM parameter store.
    '''

    def __init__(
        self,
        parameter_name: builtins.str,
        os: OperatingSystemType,
        user_data: typing.Optional[UserData] = None,
    ) -> None:
        '''
        :param parameter_name: -
        :param os: -
        :param user_data: -
        '''
        jsii.create(GenericSSMParameterImage, self, [parameter_name, os, user_data])

    @jsii.member(jsii_name="getImage")
    def get_image(self, scope: aws_cdk.core.Construct) -> MachineImageConfig:
        '''Return the image to use in the given context.

        :param scope: -
        '''
        return typing.cast(MachineImageConfig, jsii.invoke(self, "getImage", [scope]))


@jsii.implements(IMachineImage)
class GenericWindowsImage(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.GenericWindowsImage",
):
    '''Construct a Windows machine image from an AMI map.

    Allows you to create a generic Windows EC2 , manually specify an AMI map.
    '''

    def __init__(
        self,
        ami_map: typing.Mapping[builtins.str, builtins.str],
        *,
        user_data: typing.Optional[UserData] = None,
    ) -> None:
        '''
        :param ami_map: -
        :param user_data: Initial user data. Default: - Empty UserData for Windows machines
        '''
        props = GenericWindowsImageProps(user_data=user_data)

        jsii.create(GenericWindowsImage, self, [ami_map, props])

    @jsii.member(jsii_name="getImage")
    def get_image(self, scope: aws_cdk.core.Construct) -> MachineImageConfig:
        '''Return the image to use in the given context.

        :param scope: -
        '''
        return typing.cast(MachineImageConfig, jsii.invoke(self, "getImage", [scope]))


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IGatewayVpcEndpoint")
class IGatewayVpcEndpoint(IVpcEndpoint, typing_extensions.Protocol):
    '''A gateway VPC endpoint.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IGatewayVpcEndpointProxy"]:
        return _IGatewayVpcEndpointProxy


class _IGatewayVpcEndpointProxy(
    jsii.proxy_for(IVpcEndpoint) # type: ignore[misc]
):
    '''A gateway VPC endpoint.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IGatewayVpcEndpoint"
    pass


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IInterfaceVpcEndpoint")
class IInterfaceVpcEndpoint(IVpcEndpoint, IConnectable, typing_extensions.Protocol):
    '''An interface VPC endpoint.'''

    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IInterfaceVpcEndpointProxy"]:
        return _IInterfaceVpcEndpointProxy


class _IInterfaceVpcEndpointProxy(
    jsii.proxy_for(IVpcEndpoint), # type: ignore[misc]
    jsii.proxy_for(IConnectable), # type: ignore[misc]
):
    '''An interface VPC endpoint.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IInterfaceVpcEndpoint"
    pass


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IPrivateSubnet")
class IPrivateSubnet(ISubnet, typing_extensions.Protocol):
    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IPrivateSubnetProxy"]:
        return _IPrivateSubnetProxy


class _IPrivateSubnetProxy(
    jsii.proxy_for(ISubnet) # type: ignore[misc]
):
    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IPrivateSubnet"
    pass


@jsii.interface(jsii_type="@aws-cdk/aws-ec2.IPublicSubnet")
class IPublicSubnet(ISubnet, typing_extensions.Protocol):
    @builtins.staticmethod
    def __jsii_proxy_class__() -> typing.Type["_IPublicSubnetProxy"]:
        return _IPublicSubnetProxy


class _IPublicSubnetProxy(
    jsii.proxy_for(ISubnet) # type: ignore[misc]
):
    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-ec2.IPublicSubnet"
    pass


class InitCommand(
    InitElement,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.InitCommand",
):
    '''Command to execute on the instance.'''

    @jsii.member(jsii_name="argvCommand") # type: ignore[misc]
    @builtins.classmethod
    def argv_command(
        cls,
        argv: typing.List[builtins.str],
        *,
        cwd: typing.Optional[builtins.str] = None,
        env: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        ignore_errors: typing.Optional[builtins.bool] = None,
        key: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
        test_cmd: typing.Optional[builtins.str] = None,
        wait_after_completion: typing.Optional[InitCommandWaitDuration] = None,
    ) -> "InitCommand":
        '''Run a command from an argv array.

        You do not need to escape space characters or enclose command parameters in quotes.

        :param argv: -
        :param cwd: The working directory. Default: - Use default working directory
        :param env: Sets environment variables for the command. This property overwrites, rather than appends, the existing environment. Default: - Use current environment
        :param ignore_errors: Continue running if this command fails. Default: false
        :param key: Identifier key for this command. Commands are executed in lexicographical order of their key names. Default: - Automatically generated based on index
        :param service_restart_handles: Restart the given service(s) after this command has run. Default: - Do not restart any service
        :param test_cmd: Command to determine whether this command should be run. If the test passes (exits with error code of 0), the command is run. Default: - Always run the command
        :param wait_after_completion: The duration to wait after a command has finished in case the command causes a reboot. Set this value to ``InitCommandWaitDuration.none()`` if you do not want to wait for every command; ``InitCommandWaitDuration.forever()`` directs cfn-init to exit and resume only after the reboot is complete. For Windows systems only. Default: - 60 seconds
        '''
        options = InitCommandOptions(
            cwd=cwd,
            env=env,
            ignore_errors=ignore_errors,
            key=key,
            service_restart_handles=service_restart_handles,
            test_cmd=test_cmd,
            wait_after_completion=wait_after_completion,
        )

        return typing.cast("InitCommand", jsii.sinvoke(cls, "argvCommand", [argv, options]))

    @jsii.member(jsii_name="shellCommand") # type: ignore[misc]
    @builtins.classmethod
    def shell_command(
        cls,
        shell_command: builtins.str,
        *,
        cwd: typing.Optional[builtins.str] = None,
        env: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        ignore_errors: typing.Optional[builtins.bool] = None,
        key: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
        test_cmd: typing.Optional[builtins.str] = None,
        wait_after_completion: typing.Optional[InitCommandWaitDuration] = None,
    ) -> "InitCommand":
        '''Run a shell command.

        Remember that some characters like ``&``, ``|``, ``;``, ``>`` etc. have special meaning in a shell and
        need to be preceded by a ``\\`` if you want to treat them as part of a filename.

        :param shell_command: -
        :param cwd: The working directory. Default: - Use default working directory
        :param env: Sets environment variables for the command. This property overwrites, rather than appends, the existing environment. Default: - Use current environment
        :param ignore_errors: Continue running if this command fails. Default: false
        :param key: Identifier key for this command. Commands are executed in lexicographical order of their key names. Default: - Automatically generated based on index
        :param service_restart_handles: Restart the given service(s) after this command has run. Default: - Do not restart any service
        :param test_cmd: Command to determine whether this command should be run. If the test passes (exits with error code of 0), the command is run. Default: - Always run the command
        :param wait_after_completion: The duration to wait after a command has finished in case the command causes a reboot. Set this value to ``InitCommandWaitDuration.none()`` if you do not want to wait for every command; ``InitCommandWaitDuration.forever()`` directs cfn-init to exit and resume only after the reboot is complete. For Windows systems only. Default: - 60 seconds
        '''
        options = InitCommandOptions(
            cwd=cwd,
            env=env,
            ignore_errors=ignore_errors,
            key=key,
            service_restart_handles=service_restart_handles,
            test_cmd=test_cmd,
            wait_after_completion=wait_after_completion,
        )

        return typing.cast("InitCommand", jsii.sinvoke(cls, "shellCommand", [shell_command, options]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="elementType")
    def element_type(self) -> builtins.str:
        '''Returns the init element type for this element.'''
        return typing.cast(builtins.str, jsii.get(self, "elementType"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.InitFileAssetOptions",
    jsii_struct_bases=[InitFileOptions, aws_cdk.aws_s3_assets.AssetOptions],
    name_mapping={
        "base64_encoded": "base64Encoded",
        "group": "group",
        "mode": "mode",
        "owner": "owner",
        "service_restart_handles": "serviceRestartHandles",
        "exclude": "exclude",
        "follow": "follow",
        "ignore_mode": "ignoreMode",
        "asset_hash": "assetHash",
        "asset_hash_type": "assetHashType",
        "bundling": "bundling",
        "readers": "readers",
        "source_hash": "sourceHash",
    },
)
class InitFileAssetOptions(InitFileOptions, aws_cdk.aws_s3_assets.AssetOptions):
    def __init__(
        self,
        *,
        base64_encoded: typing.Optional[builtins.bool] = None,
        group: typing.Optional[builtins.str] = None,
        mode: typing.Optional[builtins.str] = None,
        owner: typing.Optional[builtins.str] = None,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
        exclude: typing.Optional[typing.List[builtins.str]] = None,
        follow: typing.Optional[aws_cdk.assets.FollowMode] = None,
        ignore_mode: typing.Optional[aws_cdk.core.IgnoreMode] = None,
        asset_hash: typing.Optional[builtins.str] = None,
        asset_hash_type: typing.Optional[aws_cdk.core.AssetHashType] = None,
        bundling: typing.Optional[aws_cdk.core.BundlingOptions] = None,
        readers: typing.Optional[typing.List[aws_cdk.aws_iam.IGrantable]] = None,
        source_hash: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Additional options for creating an InitFile from an asset.

        :param base64_encoded: True if the inlined content (from a string or file) should be treated as base64 encoded. Only applicable for inlined string and file content. Default: false
        :param group: The name of the owning group for this file. Not supported for Windows systems. Default: 'root'
        :param mode: A six-digit octal value representing the mode for this file. Use the first three digits for symlinks and the last three digits for setting permissions. To create a symlink, specify 120xxx, where xxx defines the permissions of the target file. To specify permissions for a file, use the last three digits, such as 000644. Not supported for Windows systems. Default: '000644'
        :param owner: The name of the owning user for this file. Not supported for Windows systems. Default: 'root'
        :param service_restart_handles: Restart the given service after this file has been written. Default: - Do not restart any service
        :param exclude: (deprecated) Glob patterns to exclude from the copy. Default: nothing is excluded
        :param follow: (deprecated) A strategy for how to handle symlinks. Default: Never
        :param ignore_mode: (deprecated) The ignore behavior to use for exclude patterns. Default: - GLOB for file assets, DOCKER or GLOB for docker assets depending on whether the '
        :param asset_hash: Specify a custom hash for this asset. If ``assetHashType`` is set it must be set to ``AssetHashType.CUSTOM``. For consistency, this custom hash will be SHA256 hashed and encoded as hex. The resulting hash will be the asset hash. NOTE: the hash is used in order to identify a specific revision of the asset, and used for optimizing and caching deployment activities related to this asset such as packaging, uploading to Amazon S3, etc. If you chose to customize the hash, you will need to make sure it is updated every time the asset changes, or otherwise it is possible that some deployments will not be invalidated. Default: - based on ``assetHashType``
        :param asset_hash_type: Specifies the type of hash to calculate for this asset. If ``assetHash`` is configured, this option must be ``undefined`` or ``AssetHashType.CUSTOM``. Default: - the default is ``AssetHashType.SOURCE``, but if ``assetHash`` is explicitly specified this value defaults to ``AssetHashType.CUSTOM``.
        :param bundling: (experimental) Bundle the asset by executing a command in a Docker container. The asset path will be mounted at ``/asset-input``. The Docker container is responsible for putting content at ``/asset-output``. The content at ``/asset-output`` will be zipped and used as the final asset. Default: - uploaded as-is to S3 if the asset is a regular file or a .zip file, archived into a .zip file and uploaded to S3 otherwise
        :param readers: (experimental) A list of principals that should be able to read this asset from S3. You can use ``asset.grantRead(principal)`` to grant read permissions later. Default: - No principals that can read file asset.
        :param source_hash: (deprecated) Custom hash to use when identifying the specific version of the asset. For consistency, this custom hash will be SHA256 hashed and encoded as hex. The resulting hash will be the asset hash. NOTE: the source hash is used in order to identify a specific revision of the asset, and used for optimizing and caching deployment activities related to this asset such as packaging, uploading to Amazon S3, etc. If you chose to customize the source hash, you will need to make sure it is updated every time the source changes, or otherwise it is possible that some deployments will not be invalidated. Default: - automatically calculate source hash based on the contents of the source file or directory.
        '''
        if isinstance(bundling, dict):
            bundling = aws_cdk.core.BundlingOptions(**bundling)
        self._values: typing.Dict[str, typing.Any] = {}
        if base64_encoded is not None:
            self._values["base64_encoded"] = base64_encoded
        if group is not None:
            self._values["group"] = group
        if mode is not None:
            self._values["mode"] = mode
        if owner is not None:
            self._values["owner"] = owner
        if service_restart_handles is not None:
            self._values["service_restart_handles"] = service_restart_handles
        if exclude is not None:
            self._values["exclude"] = exclude
        if follow is not None:
            self._values["follow"] = follow
        if ignore_mode is not None:
            self._values["ignore_mode"] = ignore_mode
        if asset_hash is not None:
            self._values["asset_hash"] = asset_hash
        if asset_hash_type is not None:
            self._values["asset_hash_type"] = asset_hash_type
        if bundling is not None:
            self._values["bundling"] = bundling
        if readers is not None:
            self._values["readers"] = readers
        if source_hash is not None:
            self._values["source_hash"] = source_hash

    @builtins.property
    def base64_encoded(self) -> typing.Optional[builtins.bool]:
        '''True if the inlined content (from a string or file) should be treated as base64 encoded.

        Only applicable for inlined string and file content.

        :default: false
        '''
        result = self._values.get("base64_encoded")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def group(self) -> typing.Optional[builtins.str]:
        '''The name of the owning group for this file.

        Not supported for Windows systems.

        :default: 'root'
        '''
        result = self._values.get("group")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def mode(self) -> typing.Optional[builtins.str]:
        '''A six-digit octal value representing the mode for this file.

        Use the first three digits for symlinks and the last three digits for
        setting permissions. To create a symlink, specify 120xxx, where xxx
        defines the permissions of the target file. To specify permissions for a
        file, use the last three digits, such as 000644.

        Not supported for Windows systems.

        :default: '000644'
        '''
        result = self._values.get("mode")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def owner(self) -> typing.Optional[builtins.str]:
        '''The name of the owning user for this file.

        Not supported for Windows systems.

        :default: 'root'
        '''
        result = self._values.get("owner")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def service_restart_handles(
        self,
    ) -> typing.Optional[typing.List[InitServiceRestartHandle]]:
        '''Restart the given service after this file has been written.

        :default: - Do not restart any service
        '''
        result = self._values.get("service_restart_handles")
        return typing.cast(typing.Optional[typing.List[InitServiceRestartHandle]], result)

    @builtins.property
    def exclude(self) -> typing.Optional[typing.List[builtins.str]]:
        '''(deprecated) Glob patterns to exclude from the copy.

        :default: nothing is excluded

        :stability: deprecated
        '''
        result = self._values.get("exclude")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def follow(self) -> typing.Optional[aws_cdk.assets.FollowMode]:
        '''(deprecated) A strategy for how to handle symlinks.

        :default: Never

        :stability: deprecated
        '''
        result = self._values.get("follow")
        return typing.cast(typing.Optional[aws_cdk.assets.FollowMode], result)

    @builtins.property
    def ignore_mode(self) -> typing.Optional[aws_cdk.core.IgnoreMode]:
        '''(deprecated) The ignore behavior to use for exclude patterns.

        :default:

        - GLOB for file assets, DOCKER or GLOB for docker assets depending on whether the
        '

        :stability: deprecated
        :aws-cdk: /aws-ecr-assets:dockerIgnoreSupport' flag is set.
        '''
        result = self._values.get("ignore_mode")
        return typing.cast(typing.Optional[aws_cdk.core.IgnoreMode], result)

    @builtins.property
    def asset_hash(self) -> typing.Optional[builtins.str]:
        '''Specify a custom hash for this asset.

        If ``assetHashType`` is set it must
        be set to ``AssetHashType.CUSTOM``. For consistency, this custom hash will
        be SHA256 hashed and encoded as hex. The resulting hash will be the asset
        hash.

        NOTE: the hash is used in order to identify a specific revision of the asset, and
        used for optimizing and caching deployment activities related to this asset such as
        packaging, uploading to Amazon S3, etc. If you chose to customize the hash, you will
        need to make sure it is updated every time the asset changes, or otherwise it is
        possible that some deployments will not be invalidated.

        :default: - based on ``assetHashType``
        '''
        result = self._values.get("asset_hash")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def asset_hash_type(self) -> typing.Optional[aws_cdk.core.AssetHashType]:
        '''Specifies the type of hash to calculate for this asset.

        If ``assetHash`` is configured, this option must be ``undefined`` or
        ``AssetHashType.CUSTOM``.

        :default:

        - the default is ``AssetHashType.SOURCE``, but if ``assetHash`` is
        explicitly specified this value defaults to ``AssetHashType.CUSTOM``.
        '''
        result = self._values.get("asset_hash_type")
        return typing.cast(typing.Optional[aws_cdk.core.AssetHashType], result)

    @builtins.property
    def bundling(self) -> typing.Optional[aws_cdk.core.BundlingOptions]:
        '''(experimental) Bundle the asset by executing a command in a Docker container.

        The asset path will be mounted at ``/asset-input``. The Docker
        container is responsible for putting content at ``/asset-output``.
        The content at ``/asset-output`` will be zipped and used as the
        final asset.

        :default:

        - uploaded as-is to S3 if the asset is a regular file or a .zip file,
        archived into a .zip file and uploaded to S3 otherwise

        :stability: experimental
        '''
        result = self._values.get("bundling")
        return typing.cast(typing.Optional[aws_cdk.core.BundlingOptions], result)

    @builtins.property
    def readers(self) -> typing.Optional[typing.List[aws_cdk.aws_iam.IGrantable]]:
        '''(experimental) A list of principals that should be able to read this asset from S3.

        You can use ``asset.grantRead(principal)`` to grant read permissions later.

        :default: - No principals that can read file asset.

        :stability: experimental
        '''
        result = self._values.get("readers")
        return typing.cast(typing.Optional[typing.List[aws_cdk.aws_iam.IGrantable]], result)

    @builtins.property
    def source_hash(self) -> typing.Optional[builtins.str]:
        '''(deprecated) Custom hash to use when identifying the specific version of the asset.

        For consistency,
        this custom hash will be SHA256 hashed and encoded as hex. The resulting hash will be
        the asset hash.

        NOTE: the source hash is used in order to identify a specific revision of the asset,
        and used for optimizing and caching deployment activities related to this asset such as
        packaging, uploading to Amazon S3, etc. If you chose to customize the source hash,
        you will need to make sure it is updated every time the source changes, or otherwise
        it is possible that some deployments will not be invalidated.

        :default:

        - automatically calculate source hash based on the contents
        of the source file or directory.

        :deprecated: see ``assetHash`` and ``assetHashType``

        :stability: deprecated
        '''
        result = self._values.get("source_hash")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "InitFileAssetOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.InitSourceAssetOptions",
    jsii_struct_bases=[InitSourceOptions, aws_cdk.aws_s3_assets.AssetOptions],
    name_mapping={
        "service_restart_handles": "serviceRestartHandles",
        "exclude": "exclude",
        "follow": "follow",
        "ignore_mode": "ignoreMode",
        "asset_hash": "assetHash",
        "asset_hash_type": "assetHashType",
        "bundling": "bundling",
        "readers": "readers",
        "source_hash": "sourceHash",
    },
)
class InitSourceAssetOptions(InitSourceOptions, aws_cdk.aws_s3_assets.AssetOptions):
    def __init__(
        self,
        *,
        service_restart_handles: typing.Optional[typing.List[InitServiceRestartHandle]] = None,
        exclude: typing.Optional[typing.List[builtins.str]] = None,
        follow: typing.Optional[aws_cdk.assets.FollowMode] = None,
        ignore_mode: typing.Optional[aws_cdk.core.IgnoreMode] = None,
        asset_hash: typing.Optional[builtins.str] = None,
        asset_hash_type: typing.Optional[aws_cdk.core.AssetHashType] = None,
        bundling: typing.Optional[aws_cdk.core.BundlingOptions] = None,
        readers: typing.Optional[typing.List[aws_cdk.aws_iam.IGrantable]] = None,
        source_hash: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Additional options for an InitSource that builds an asset from local files.

        :param service_restart_handles: Restart the given services after this archive has been extracted. Default: - Do not restart any service
        :param exclude: (deprecated) Glob patterns to exclude from the copy. Default: nothing is excluded
        :param follow: (deprecated) A strategy for how to handle symlinks. Default: Never
        :param ignore_mode: (deprecated) The ignore behavior to use for exclude patterns. Default: - GLOB for file assets, DOCKER or GLOB for docker assets depending on whether the '
        :param asset_hash: Specify a custom hash for this asset. If ``assetHashType`` is set it must be set to ``AssetHashType.CUSTOM``. For consistency, this custom hash will be SHA256 hashed and encoded as hex. The resulting hash will be the asset hash. NOTE: the hash is used in order to identify a specific revision of the asset, and used for optimizing and caching deployment activities related to this asset such as packaging, uploading to Amazon S3, etc. If you chose to customize the hash, you will need to make sure it is updated every time the asset changes, or otherwise it is possible that some deployments will not be invalidated. Default: - based on ``assetHashType``
        :param asset_hash_type: Specifies the type of hash to calculate for this asset. If ``assetHash`` is configured, this option must be ``undefined`` or ``AssetHashType.CUSTOM``. Default: - the default is ``AssetHashType.SOURCE``, but if ``assetHash`` is explicitly specified this value defaults to ``AssetHashType.CUSTOM``.
        :param bundling: (experimental) Bundle the asset by executing a command in a Docker container. The asset path will be mounted at ``/asset-input``. The Docker container is responsible for putting content at ``/asset-output``. The content at ``/asset-output`` will be zipped and used as the final asset. Default: - uploaded as-is to S3 if the asset is a regular file or a .zip file, archived into a .zip file and uploaded to S3 otherwise
        :param readers: (experimental) A list of principals that should be able to read this asset from S3. You can use ``asset.grantRead(principal)`` to grant read permissions later. Default: - No principals that can read file asset.
        :param source_hash: (deprecated) Custom hash to use when identifying the specific version of the asset. For consistency, this custom hash will be SHA256 hashed and encoded as hex. The resulting hash will be the asset hash. NOTE: the source hash is used in order to identify a specific revision of the asset, and used for optimizing and caching deployment activities related to this asset such as packaging, uploading to Amazon S3, etc. If you chose to customize the source hash, you will need to make sure it is updated every time the source changes, or otherwise it is possible that some deployments will not be invalidated. Default: - automatically calculate source hash based on the contents of the source file or directory.
        '''
        if isinstance(bundling, dict):
            bundling = aws_cdk.core.BundlingOptions(**bundling)
        self._values: typing.Dict[str, typing.Any] = {}
        if service_restart_handles is not None:
            self._values["service_restart_handles"] = service_restart_handles
        if exclude is not None:
            self._values["exclude"] = exclude
        if follow is not None:
            self._values["follow"] = follow
        if ignore_mode is not None:
            self._values["ignore_mode"] = ignore_mode
        if asset_hash is not None:
            self._values["asset_hash"] = asset_hash
        if asset_hash_type is not None:
            self._values["asset_hash_type"] = asset_hash_type
        if bundling is not None:
            self._values["bundling"] = bundling
        if readers is not None:
            self._values["readers"] = readers
        if source_hash is not None:
            self._values["source_hash"] = source_hash

    @builtins.property
    def service_restart_handles(
        self,
    ) -> typing.Optional[typing.List[InitServiceRestartHandle]]:
        '''Restart the given services after this archive has been extracted.

        :default: - Do not restart any service
        '''
        result = self._values.get("service_restart_handles")
        return typing.cast(typing.Optional[typing.List[InitServiceRestartHandle]], result)

    @builtins.property
    def exclude(self) -> typing.Optional[typing.List[builtins.str]]:
        '''(deprecated) Glob patterns to exclude from the copy.

        :default: nothing is excluded

        :stability: deprecated
        '''
        result = self._values.get("exclude")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def follow(self) -> typing.Optional[aws_cdk.assets.FollowMode]:
        '''(deprecated) A strategy for how to handle symlinks.

        :default: Never

        :stability: deprecated
        '''
        result = self._values.get("follow")
        return typing.cast(typing.Optional[aws_cdk.assets.FollowMode], result)

    @builtins.property
    def ignore_mode(self) -> typing.Optional[aws_cdk.core.IgnoreMode]:
        '''(deprecated) The ignore behavior to use for exclude patterns.

        :default:

        - GLOB for file assets, DOCKER or GLOB for docker assets depending on whether the
        '

        :stability: deprecated
        :aws-cdk: /aws-ecr-assets:dockerIgnoreSupport' flag is set.
        '''
        result = self._values.get("ignore_mode")
        return typing.cast(typing.Optional[aws_cdk.core.IgnoreMode], result)

    @builtins.property
    def asset_hash(self) -> typing.Optional[builtins.str]:
        '''Specify a custom hash for this asset.

        If ``assetHashType`` is set it must
        be set to ``AssetHashType.CUSTOM``. For consistency, this custom hash will
        be SHA256 hashed and encoded as hex. The resulting hash will be the asset
        hash.

        NOTE: the hash is used in order to identify a specific revision of the asset, and
        used for optimizing and caching deployment activities related to this asset such as
        packaging, uploading to Amazon S3, etc. If you chose to customize the hash, you will
        need to make sure it is updated every time the asset changes, or otherwise it is
        possible that some deployments will not be invalidated.

        :default: - based on ``assetHashType``
        '''
        result = self._values.get("asset_hash")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def asset_hash_type(self) -> typing.Optional[aws_cdk.core.AssetHashType]:
        '''Specifies the type of hash to calculate for this asset.

        If ``assetHash`` is configured, this option must be ``undefined`` or
        ``AssetHashType.CUSTOM``.

        :default:

        - the default is ``AssetHashType.SOURCE``, but if ``assetHash`` is
        explicitly specified this value defaults to ``AssetHashType.CUSTOM``.
        '''
        result = self._values.get("asset_hash_type")
        return typing.cast(typing.Optional[aws_cdk.core.AssetHashType], result)

    @builtins.property
    def bundling(self) -> typing.Optional[aws_cdk.core.BundlingOptions]:
        '''(experimental) Bundle the asset by executing a command in a Docker container.

        The asset path will be mounted at ``/asset-input``. The Docker
        container is responsible for putting content at ``/asset-output``.
        The content at ``/asset-output`` will be zipped and used as the
        final asset.

        :default:

        - uploaded as-is to S3 if the asset is a regular file or a .zip file,
        archived into a .zip file and uploaded to S3 otherwise

        :stability: experimental
        '''
        result = self._values.get("bundling")
        return typing.cast(typing.Optional[aws_cdk.core.BundlingOptions], result)

    @builtins.property
    def readers(self) -> typing.Optional[typing.List[aws_cdk.aws_iam.IGrantable]]:
        '''(experimental) A list of principals that should be able to read this asset from S3.

        You can use ``asset.grantRead(principal)`` to grant read permissions later.

        :default: - No principals that can read file asset.

        :stability: experimental
        '''
        result = self._values.get("readers")
        return typing.cast(typing.Optional[typing.List[aws_cdk.aws_iam.IGrantable]], result)

    @builtins.property
    def source_hash(self) -> typing.Optional[builtins.str]:
        '''(deprecated) Custom hash to use when identifying the specific version of the asset.

        For consistency,
        this custom hash will be SHA256 hashed and encoded as hex. The resulting hash will be
        the asset hash.

        NOTE: the source hash is used in order to identify a specific revision of the asset,
        and used for optimizing and caching deployment activities related to this asset such as
        packaging, uploading to Amazon S3, etc. If you chose to customize the source hash,
        you will need to make sure it is updated every time the source changes, or otherwise
        it is possible that some deployments will not be invalidated.

        :default:

        - automatically calculate source hash based on the contents
        of the source file or directory.

        :deprecated: see ``assetHash`` and ``assetHashType``

        :stability: deprecated
        '''
        result = self._values.get("source_hash")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "InitSourceAssetOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IInterfaceVpcEndpoint)
class InterfaceVpcEndpoint(
    VpcEndpoint,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.InterfaceVpcEndpoint",
):
    '''A interface VPC endpoint.

    :resource: AWS::EC2::VPCEndpoint
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        vpc: IVpc,
        service: IInterfaceVpcEndpointService,
        lookup_supported_azs: typing.Optional[builtins.bool] = None,
        open: typing.Optional[builtins.bool] = None,
        private_dns_enabled: typing.Optional[builtins.bool] = None,
        security_groups: typing.Optional[typing.List[ISecurityGroup]] = None,
        subnets: typing.Optional[SubnetSelection] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param vpc: The VPC network in which the interface endpoint will be used.
        :param service: The service to use for this interface VPC endpoint.
        :param lookup_supported_azs: Limit to only those availability zones where the endpoint service can be created. Setting this to 'true' requires a lookup to be performed at synthesis time. Account and region must be set on the containing stack for this to work. Default: false
        :param open: Whether to automatically allow VPC traffic to the endpoint. If enabled, all traffic to the endpoint from within the VPC will be automatically allowed. This is done based on the VPC's CIDR range. Default: true
        :param private_dns_enabled: Whether to associate a private hosted zone with the specified VPC. This allows you to make requests to the service using its default DNS hostname. Default: set by the instance of IInterfaceVpcEndpointService, or true if not defined by the instance of IInterfaceVpcEndpointService
        :param security_groups: The security groups to associate with this interface VPC endpoint. Default: - a new security group is created
        :param subnets: The subnets in which to create an endpoint network interface. At most one per availability zone. Default: - private subnets
        '''
        props = InterfaceVpcEndpointProps(
            vpc=vpc,
            service=service,
            lookup_supported_azs=lookup_supported_azs,
            open=open,
            private_dns_enabled=private_dns_enabled,
            security_groups=security_groups,
            subnets=subnets,
        )

        jsii.create(InterfaceVpcEndpoint, self, [scope, id, props])

    @jsii.member(jsii_name="fromInterfaceVpcEndpointAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_interface_vpc_endpoint_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        port: jsii.Number,
        vpc_endpoint_id: builtins.str,
        security_group_id: typing.Optional[builtins.str] = None,
        security_groups: typing.Optional[typing.List[ISecurityGroup]] = None,
    ) -> IInterfaceVpcEndpoint:
        '''Imports an existing interface VPC endpoint.

        :param scope: -
        :param id: -
        :param port: The port of the service of the interface VPC endpoint.
        :param vpc_endpoint_id: The interface VPC endpoint identifier.
        :param security_group_id: (deprecated) The identifier of the security group associated with the interface VPC endpoint.
        :param security_groups: The security groups associated with the interface VPC endpoint.
        '''
        attrs = InterfaceVpcEndpointAttributes(
            port=port,
            vpc_endpoint_id=vpc_endpoint_id,
            security_group_id=security_group_id,
            security_groups=security_groups,
        )

        return typing.cast(IInterfaceVpcEndpoint, jsii.sinvoke(cls, "fromInterfaceVpcEndpointAttributes", [scope, id, attrs]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connections")
    def connections(self) -> Connections:
        '''Access to network connections.'''
        return typing.cast(Connections, jsii.get(self, "connections"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroupId")
    def security_group_id(self) -> builtins.str:
        '''(deprecated) The identifier of the first security group associated with this interface VPC endpoint.

        :deprecated: use the ``connections`` object

        :stability: deprecated
        '''
        return typing.cast(builtins.str, jsii.get(self, "securityGroupId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointCreationTimestamp")
    def vpc_endpoint_creation_timestamp(self) -> builtins.str:
        '''The date and time the interface VPC endpoint was created.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcEndpointCreationTimestamp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointDnsEntries")
    def vpc_endpoint_dns_entries(self) -> typing.List[builtins.str]:
        '''The DNS entries for the interface VPC endpoint.

        :attribute: true
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "vpcEndpointDnsEntries"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointId")
    def vpc_endpoint_id(self) -> builtins.str:
        '''The interface VPC endpoint identifier.'''
        return typing.cast(builtins.str, jsii.get(self, "vpcEndpointId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointNetworkInterfaceIds")
    def vpc_endpoint_network_interface_ids(self) -> typing.List[builtins.str]:
        '''One or more network interfaces for the interface VPC endpoint.

        :attribute: true
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "vpcEndpointNetworkInterfaceIds"))


@jsii.implements(IConnectable)
class NatInstanceProvider(
    NatProvider,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.NatInstanceProvider",
):
    '''NAT provider which uses NAT Instances.'''

    def __init__(
        self,
        *,
        instance_type: InstanceType,
        allow_all_traffic: typing.Optional[builtins.bool] = None,
        key_name: typing.Optional[builtins.str] = None,
        machine_image: typing.Optional[IMachineImage] = None,
        security_group: typing.Optional[ISecurityGroup] = None,
    ) -> None:
        '''
        :param instance_type: (experimental) Instance type of the NAT instance.
        :param allow_all_traffic: (experimental) Allow all traffic through the NAT instance. If you set this to false, you must configure the NAT instance's security groups in another way, either by passing in a fully configured Security Group using the ``securityGroup`` property, or by configuring it using the ``.securityGroup`` or ``.connections`` members after passing the NAT Instance Provider to a Vpc. Default: true
        :param key_name: (experimental) Name of SSH keypair to grant access to instance. Default: - No SSH access will be possible.
        :param machine_image: (experimental) The machine image (AMI) to use. By default, will do an AMI lookup for the latest NAT instance image. If you have a specific AMI ID you want to use, pass a ``GenericLinuxImage``. For example:: ec2.NatProvider.instance({ instanceType: new ec2.InstanceType('t3.micro'), machineImage: new ec2.GenericLinuxImage({ 'us-east-2': 'ami-0f9c61b5a562a16af' }) }) Default: - Latest NAT instance image
        :param security_group: (experimental) Security Group for NAT instances. Default: - A new security group will be created
        '''
        props = NatInstanceProps(
            instance_type=instance_type,
            allow_all_traffic=allow_all_traffic,
            key_name=key_name,
            machine_image=machine_image,
            security_group=security_group,
        )

        jsii.create(NatInstanceProvider, self, [props])

    @jsii.member(jsii_name="configureNat")
    def configure_nat(
        self,
        *,
        nat_subnets: typing.List["PublicSubnet"],
        private_subnets: typing.List["PrivateSubnet"],
        vpc: Vpc,
    ) -> None:
        '''Called by the VPC to configure NAT.

        Don't call this directly, the VPC will call it automatically.

        :param nat_subnets: (experimental) The public subnets where the NAT providers need to be placed.
        :param private_subnets: (experimental) The private subnets that need to route through the NAT providers. There may be more private subnets than public subnets with NAT providers.
        :param vpc: (experimental) The VPC we're configuring NAT for.
        '''
        options = ConfigureNatOptions(
            nat_subnets=nat_subnets, private_subnets=private_subnets, vpc=vpc
        )

        return typing.cast(None, jsii.invoke(self, "configureNat", [options]))

    @jsii.member(jsii_name="configureSubnet")
    def configure_subnet(self, subnet: "PrivateSubnet") -> None:
        '''Configures subnet with the gateway.

        Don't call this directly, the VPC will call it automatically.

        :param subnet: -
        '''
        return typing.cast(None, jsii.invoke(self, "configureSubnet", [subnet]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="configuredGateways")
    def configured_gateways(self) -> typing.List[GatewayConfig]:
        '''Return list of gateways spawned by the provider.'''
        return typing.cast(typing.List[GatewayConfig], jsii.get(self, "configuredGateways"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="connections")
    def connections(self) -> Connections:
        '''Manage the Security Groups associated with the NAT instances.'''
        return typing.cast(Connections, jsii.get(self, "connections"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="securityGroup")
    def security_group(self) -> ISecurityGroup:
        '''The Security Group associated with the NAT instances.'''
        return typing.cast(ISecurityGroup, jsii.get(self, "securityGroup"))


@jsii.implements(IPrivateSubnet)
class PrivateSubnet(
    Subnet,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.PrivateSubnet",
):
    '''Represents a private VPC subnet resource.'''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        availability_zone: builtins.str,
        cidr_block: builtins.str,
        vpc_id: builtins.str,
        map_public_ip_on_launch: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param availability_zone: The availability zone for the subnet.
        :param cidr_block: The CIDR notation for this subnet.
        :param vpc_id: The VPC which this subnet is part of.
        :param map_public_ip_on_launch: Controls if a public IP is associated to an instance at launch. Default: true in Subnet.Public, false in Subnet.Private or Subnet.Isolated.
        '''
        props = PrivateSubnetProps(
            availability_zone=availability_zone,
            cidr_block=cidr_block,
            vpc_id=vpc_id,
            map_public_ip_on_launch=map_public_ip_on_launch,
        )

        jsii.create(PrivateSubnet, self, [scope, id, props])

    @jsii.member(jsii_name="fromPrivateSubnetAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_private_subnet_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        subnet_id: builtins.str,
        availability_zone: typing.Optional[builtins.str] = None,
        ipv4_cidr_block: typing.Optional[builtins.str] = None,
        route_table_id: typing.Optional[builtins.str] = None,
    ) -> IPrivateSubnet:
        '''
        :param scope: -
        :param id: -
        :param subnet_id: The subnetId for this particular subnet.
        :param availability_zone: The Availability Zone the subnet is located in. Default: - No AZ information, cannot use AZ selection features
        :param ipv4_cidr_block: The IPv4 CIDR block associated with the subnet. Default: - No CIDR information, cannot use CIDR filter features
        :param route_table_id: The ID of the route table for this particular subnet. Default: - No route table information, cannot create VPC endpoints
        '''
        attrs = PrivateSubnetAttributes(
            subnet_id=subnet_id,
            availability_zone=availability_zone,
            ipv4_cidr_block=ipv4_cidr_block,
            route_table_id=route_table_id,
        )

        return typing.cast(IPrivateSubnet, jsii.sinvoke(cls, "fromPrivateSubnetAttributes", [scope, id, attrs]))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.PrivateSubnetAttributes",
    jsii_struct_bases=[SubnetAttributes],
    name_mapping={
        "subnet_id": "subnetId",
        "availability_zone": "availabilityZone",
        "ipv4_cidr_block": "ipv4CidrBlock",
        "route_table_id": "routeTableId",
    },
)
class PrivateSubnetAttributes(SubnetAttributes):
    def __init__(
        self,
        *,
        subnet_id: builtins.str,
        availability_zone: typing.Optional[builtins.str] = None,
        ipv4_cidr_block: typing.Optional[builtins.str] = None,
        route_table_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param subnet_id: The subnetId for this particular subnet.
        :param availability_zone: The Availability Zone the subnet is located in. Default: - No AZ information, cannot use AZ selection features
        :param ipv4_cidr_block: The IPv4 CIDR block associated with the subnet. Default: - No CIDR information, cannot use CIDR filter features
        :param route_table_id: The ID of the route table for this particular subnet. Default: - No route table information, cannot create VPC endpoints
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "subnet_id": subnet_id,
        }
        if availability_zone is not None:
            self._values["availability_zone"] = availability_zone
        if ipv4_cidr_block is not None:
            self._values["ipv4_cidr_block"] = ipv4_cidr_block
        if route_table_id is not None:
            self._values["route_table_id"] = route_table_id

    @builtins.property
    def subnet_id(self) -> builtins.str:
        '''The subnetId for this particular subnet.'''
        result = self._values.get("subnet_id")
        assert result is not None, "Required property 'subnet_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def availability_zone(self) -> typing.Optional[builtins.str]:
        '''The Availability Zone the subnet is located in.

        :default: - No AZ information, cannot use AZ selection features
        '''
        result = self._values.get("availability_zone")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ipv4_cidr_block(self) -> typing.Optional[builtins.str]:
        '''The IPv4 CIDR block associated with the subnet.

        :default: - No CIDR information, cannot use CIDR filter features
        '''
        result = self._values.get("ipv4_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def route_table_id(self) -> typing.Optional[builtins.str]:
        '''The ID of the route table for this particular subnet.

        :default: - No route table information, cannot create VPC endpoints
        '''
        result = self._values.get("route_table_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PrivateSubnetAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.PrivateSubnetProps",
    jsii_struct_bases=[SubnetProps],
    name_mapping={
        "availability_zone": "availabilityZone",
        "cidr_block": "cidrBlock",
        "vpc_id": "vpcId",
        "map_public_ip_on_launch": "mapPublicIpOnLaunch",
    },
)
class PrivateSubnetProps(SubnetProps):
    def __init__(
        self,
        *,
        availability_zone: builtins.str,
        cidr_block: builtins.str,
        vpc_id: builtins.str,
        map_public_ip_on_launch: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''
        :param availability_zone: The availability zone for the subnet.
        :param cidr_block: The CIDR notation for this subnet.
        :param vpc_id: The VPC which this subnet is part of.
        :param map_public_ip_on_launch: Controls if a public IP is associated to an instance at launch. Default: true in Subnet.Public, false in Subnet.Private or Subnet.Isolated.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "availability_zone": availability_zone,
            "cidr_block": cidr_block,
            "vpc_id": vpc_id,
        }
        if map_public_ip_on_launch is not None:
            self._values["map_public_ip_on_launch"] = map_public_ip_on_launch

    @builtins.property
    def availability_zone(self) -> builtins.str:
        '''The availability zone for the subnet.'''
        result = self._values.get("availability_zone")
        assert result is not None, "Required property 'availability_zone' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def cidr_block(self) -> builtins.str:
        '''The CIDR notation for this subnet.'''
        result = self._values.get("cidr_block")
        assert result is not None, "Required property 'cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''The VPC which this subnet is part of.'''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def map_public_ip_on_launch(self) -> typing.Optional[builtins.bool]:
        '''Controls if a public IP is associated to an instance at launch.

        :default: true in Subnet.Public, false in Subnet.Private or Subnet.Isolated.
        '''
        result = self._values.get("map_public_ip_on_launch")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PrivateSubnetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IPublicSubnet)
class PublicSubnet(
    Subnet,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.PublicSubnet",
):
    '''Represents a public VPC subnet resource.'''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        availability_zone: builtins.str,
        cidr_block: builtins.str,
        vpc_id: builtins.str,
        map_public_ip_on_launch: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param availability_zone: The availability zone for the subnet.
        :param cidr_block: The CIDR notation for this subnet.
        :param vpc_id: The VPC which this subnet is part of.
        :param map_public_ip_on_launch: Controls if a public IP is associated to an instance at launch. Default: true in Subnet.Public, false in Subnet.Private or Subnet.Isolated.
        '''
        props = PublicSubnetProps(
            availability_zone=availability_zone,
            cidr_block=cidr_block,
            vpc_id=vpc_id,
            map_public_ip_on_launch=map_public_ip_on_launch,
        )

        jsii.create(PublicSubnet, self, [scope, id, props])

    @jsii.member(jsii_name="fromPublicSubnetAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_public_subnet_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        subnet_id: builtins.str,
        availability_zone: typing.Optional[builtins.str] = None,
        ipv4_cidr_block: typing.Optional[builtins.str] = None,
        route_table_id: typing.Optional[builtins.str] = None,
    ) -> IPublicSubnet:
        '''
        :param scope: -
        :param id: -
        :param subnet_id: The subnetId for this particular subnet.
        :param availability_zone: The Availability Zone the subnet is located in. Default: - No AZ information, cannot use AZ selection features
        :param ipv4_cidr_block: The IPv4 CIDR block associated with the subnet. Default: - No CIDR information, cannot use CIDR filter features
        :param route_table_id: The ID of the route table for this particular subnet. Default: - No route table information, cannot create VPC endpoints
        '''
        attrs = PublicSubnetAttributes(
            subnet_id=subnet_id,
            availability_zone=availability_zone,
            ipv4_cidr_block=ipv4_cidr_block,
            route_table_id=route_table_id,
        )

        return typing.cast(IPublicSubnet, jsii.sinvoke(cls, "fromPublicSubnetAttributes", [scope, id, attrs]))

    @jsii.member(jsii_name="addNatGateway")
    def add_nat_gateway(self) -> CfnNatGateway:
        '''Creates a new managed NAT gateway attached to this public subnet.

        Also adds the EIP for the managed NAT.

        :return: A ref to the the NAT Gateway ID
        '''
        return typing.cast(CfnNatGateway, jsii.invoke(self, "addNatGateway", []))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.PublicSubnetAttributes",
    jsii_struct_bases=[SubnetAttributes],
    name_mapping={
        "subnet_id": "subnetId",
        "availability_zone": "availabilityZone",
        "ipv4_cidr_block": "ipv4CidrBlock",
        "route_table_id": "routeTableId",
    },
)
class PublicSubnetAttributes(SubnetAttributes):
    def __init__(
        self,
        *,
        subnet_id: builtins.str,
        availability_zone: typing.Optional[builtins.str] = None,
        ipv4_cidr_block: typing.Optional[builtins.str] = None,
        route_table_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param subnet_id: The subnetId for this particular subnet.
        :param availability_zone: The Availability Zone the subnet is located in. Default: - No AZ information, cannot use AZ selection features
        :param ipv4_cidr_block: The IPv4 CIDR block associated with the subnet. Default: - No CIDR information, cannot use CIDR filter features
        :param route_table_id: The ID of the route table for this particular subnet. Default: - No route table information, cannot create VPC endpoints
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "subnet_id": subnet_id,
        }
        if availability_zone is not None:
            self._values["availability_zone"] = availability_zone
        if ipv4_cidr_block is not None:
            self._values["ipv4_cidr_block"] = ipv4_cidr_block
        if route_table_id is not None:
            self._values["route_table_id"] = route_table_id

    @builtins.property
    def subnet_id(self) -> builtins.str:
        '''The subnetId for this particular subnet.'''
        result = self._values.get("subnet_id")
        assert result is not None, "Required property 'subnet_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def availability_zone(self) -> typing.Optional[builtins.str]:
        '''The Availability Zone the subnet is located in.

        :default: - No AZ information, cannot use AZ selection features
        '''
        result = self._values.get("availability_zone")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ipv4_cidr_block(self) -> typing.Optional[builtins.str]:
        '''The IPv4 CIDR block associated with the subnet.

        :default: - No CIDR information, cannot use CIDR filter features
        '''
        result = self._values.get("ipv4_cidr_block")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def route_table_id(self) -> typing.Optional[builtins.str]:
        '''The ID of the route table for this particular subnet.

        :default: - No route table information, cannot create VPC endpoints
        '''
        result = self._values.get("route_table_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PublicSubnetAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-ec2.PublicSubnetProps",
    jsii_struct_bases=[SubnetProps],
    name_mapping={
        "availability_zone": "availabilityZone",
        "cidr_block": "cidrBlock",
        "vpc_id": "vpcId",
        "map_public_ip_on_launch": "mapPublicIpOnLaunch",
    },
)
class PublicSubnetProps(SubnetProps):
    def __init__(
        self,
        *,
        availability_zone: builtins.str,
        cidr_block: builtins.str,
        vpc_id: builtins.str,
        map_public_ip_on_launch: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''
        :param availability_zone: The availability zone for the subnet.
        :param cidr_block: The CIDR notation for this subnet.
        :param vpc_id: The VPC which this subnet is part of.
        :param map_public_ip_on_launch: Controls if a public IP is associated to an instance at launch. Default: true in Subnet.Public, false in Subnet.Private or Subnet.Isolated.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "availability_zone": availability_zone,
            "cidr_block": cidr_block,
            "vpc_id": vpc_id,
        }
        if map_public_ip_on_launch is not None:
            self._values["map_public_ip_on_launch"] = map_public_ip_on_launch

    @builtins.property
    def availability_zone(self) -> builtins.str:
        '''The availability zone for the subnet.'''
        result = self._values.get("availability_zone")
        assert result is not None, "Required property 'availability_zone' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def cidr_block(self) -> builtins.str:
        '''The CIDR notation for this subnet.'''
        result = self._values.get("cidr_block")
        assert result is not None, "Required property 'cidr_block' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def vpc_id(self) -> builtins.str:
        '''The VPC which this subnet is part of.'''
        result = self._values.get("vpc_id")
        assert result is not None, "Required property 'vpc_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def map_public_ip_on_launch(self) -> typing.Optional[builtins.bool]:
        '''Controls if a public IP is associated to an instance at launch.

        :default: true in Subnet.Public, false in Subnet.Private or Subnet.Isolated.
        '''
        result = self._values.get("map_public_ip_on_launch")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PublicSubnetProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class WindowsImage(
    GenericSSMParameterImage,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.WindowsImage",
):
    '''Select the latest version of the indicated Windows version.

    This Machine Image automatically updates to the latest version on every
    deployment. Be aware this will cause your instances to be replaced when a
    new version of the image becomes available. Do not store stateful information
    on the instance if you are using this image.

    The AMI ID is selected using the values published to the SSM parameter store.

    https://aws.amazon.com/blogs/mt/query-for-the-latest-windows-ami-using-systems-manager-parameter-store/
    '''

    def __init__(
        self,
        version: WindowsVersion,
        *,
        user_data: typing.Optional[UserData] = None,
    ) -> None:
        '''
        :param version: -
        :param user_data: Initial user data. Default: - Empty UserData for Windows machines
        '''
        props = WindowsImageProps(user_data=user_data)

        jsii.create(WindowsImage, self, [version, props])


class AmazonLinuxImage(
    GenericSSMParameterImage,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.AmazonLinuxImage",
):
    '''Selects the latest version of Amazon Linux.

    This Machine Image automatically updates to the latest version on every
    deployment. Be aware this will cause your instances to be replaced when a
    new version of the image becomes available. Do not store stateful information
    on the instance if you are using this image.

    The AMI ID is selected using the values published to the SSM parameter store.
    '''

    def __init__(
        self,
        *,
        cpu_type: typing.Optional[AmazonLinuxCpuType] = None,
        edition: typing.Optional[AmazonLinuxEdition] = None,
        generation: typing.Optional[AmazonLinuxGeneration] = None,
        storage: typing.Optional[AmazonLinuxStorage] = None,
        user_data: typing.Optional[UserData] = None,
        virtualization: typing.Optional[AmazonLinuxVirt] = None,
    ) -> None:
        '''
        :param cpu_type: CPU Type. Default: X86_64
        :param edition: What edition of Amazon Linux to use. Default: Standard
        :param generation: What generation of Amazon Linux to use. Default: AmazonLinux
        :param storage: What storage backed image to use. Default: GeneralPurpose
        :param user_data: Initial user data. Default: - Empty UserData for Linux machines
        :param virtualization: Virtualization type. Default: HVM
        '''
        props = AmazonLinuxImageProps(
            cpu_type=cpu_type,
            edition=edition,
            generation=generation,
            storage=storage,
            user_data=user_data,
            virtualization=virtualization,
        )

        jsii.create(AmazonLinuxImage, self, [props])


@jsii.implements(IGatewayVpcEndpoint)
class GatewayVpcEndpoint(
    VpcEndpoint,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-ec2.GatewayVpcEndpoint",
):
    '''A gateway VPC endpoint.

    :resource: AWS::EC2::VPCEndpoint
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        vpc: IVpc,
        service: IGatewayVpcEndpointService,
        subnets: typing.Optional[typing.List[SubnetSelection]] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param vpc: The VPC network in which the gateway endpoint will be used.
        :param service: The service to use for this gateway VPC endpoint.
        :param subnets: Where to add endpoint routing. By default, this endpoint will be routable from all subnets in the VPC. Specify a list of subnet selection objects here to be more specific. Default: - All subnets in the VPC
        '''
        props = GatewayVpcEndpointProps(vpc=vpc, service=service, subnets=subnets)

        jsii.create(GatewayVpcEndpoint, self, [scope, id, props])

    @jsii.member(jsii_name="fromGatewayVpcEndpointId") # type: ignore[misc]
    @builtins.classmethod
    def from_gateway_vpc_endpoint_id(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        gateway_vpc_endpoint_id: builtins.str,
    ) -> IGatewayVpcEndpoint:
        '''
        :param scope: -
        :param id: -
        :param gateway_vpc_endpoint_id: -
        '''
        return typing.cast(IGatewayVpcEndpoint, jsii.sinvoke(cls, "fromGatewayVpcEndpointId", [scope, id, gateway_vpc_endpoint_id]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointCreationTimestamp")
    def vpc_endpoint_creation_timestamp(self) -> builtins.str:
        '''The date and time the gateway VPC endpoint was created.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "vpcEndpointCreationTimestamp"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointDnsEntries")
    def vpc_endpoint_dns_entries(self) -> typing.List[builtins.str]:
        '''
        :attribute: true
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "vpcEndpointDnsEntries"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointId")
    def vpc_endpoint_id(self) -> builtins.str:
        '''The gateway VPC endpoint identifier.'''
        return typing.cast(builtins.str, jsii.get(self, "vpcEndpointId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="vpcEndpointNetworkInterfaceIds")
    def vpc_endpoint_network_interface_ids(self) -> typing.List[builtins.str]:
        '''
        :attribute: true
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "vpcEndpointNetworkInterfaceIds"))


__all__ = [
    "AclCidr",
    "AclCidrConfig",
    "AclIcmp",
    "AclPortRange",
    "AclTraffic",
    "AclTrafficConfig",
    "Action",
    "AddRouteOptions",
    "AmazonLinuxCpuType",
    "AmazonLinuxEdition",
    "AmazonLinuxGeneration",
    "AmazonLinuxImage",
    "AmazonLinuxImageProps",
    "AmazonLinuxStorage",
    "AmazonLinuxVirt",
    "ApplyCloudFormationInitOptions",
    "AttachInitOptions",
    "BastionHostLinux",
    "BastionHostLinuxProps",
    "BlockDevice",
    "BlockDeviceVolume",
    "CfnCapacityReservation",
    "CfnCapacityReservationProps",
    "CfnCarrierGateway",
    "CfnCarrierGatewayProps",
    "CfnClientVpnAuthorizationRule",
    "CfnClientVpnAuthorizationRuleProps",
    "CfnClientVpnEndpoint",
    "CfnClientVpnEndpointProps",
    "CfnClientVpnRoute",
    "CfnClientVpnRouteProps",
    "CfnClientVpnTargetNetworkAssociation",
    "CfnClientVpnTargetNetworkAssociationProps",
    "CfnCustomerGateway",
    "CfnCustomerGatewayProps",
    "CfnDHCPOptions",
    "CfnDHCPOptionsProps",
    "CfnEC2Fleet",
    "CfnEC2FleetProps",
    "CfnEIP",
    "CfnEIPAssociation",
    "CfnEIPAssociationProps",
    "CfnEIPProps",
    "CfnEgressOnlyInternetGateway",
    "CfnEgressOnlyInternetGatewayProps",
    "CfnFlowLog",
    "CfnFlowLogProps",
    "CfnGatewayRouteTableAssociation",
    "CfnGatewayRouteTableAssociationProps",
    "CfnHost",
    "CfnHostProps",
    "CfnInstance",
    "CfnInstanceProps",
    "CfnInternetGateway",
    "CfnInternetGatewayProps",
    "CfnLaunchTemplate",
    "CfnLaunchTemplateProps",
    "CfnLocalGatewayRoute",
    "CfnLocalGatewayRouteProps",
    "CfnLocalGatewayRouteTableVPCAssociation",
    "CfnLocalGatewayRouteTableVPCAssociationProps",
    "CfnNatGateway",
    "CfnNatGatewayProps",
    "CfnNetworkAcl",
    "CfnNetworkAclEntry",
    "CfnNetworkAclEntryProps",
    "CfnNetworkAclProps",
    "CfnNetworkInsightsAnalysis",
    "CfnNetworkInsightsAnalysisProps",
    "CfnNetworkInsightsPath",
    "CfnNetworkInsightsPathProps",
    "CfnNetworkInterface",
    "CfnNetworkInterfaceAttachment",
    "CfnNetworkInterfaceAttachmentProps",
    "CfnNetworkInterfacePermission",
    "CfnNetworkInterfacePermissionProps",
    "CfnNetworkInterfaceProps",
    "CfnPlacementGroup",
    "CfnPlacementGroupProps",
    "CfnPrefixList",
    "CfnPrefixListProps",
    "CfnRoute",
    "CfnRouteProps",
    "CfnRouteTable",
    "CfnRouteTableProps",
    "CfnSecurityGroup",
    "CfnSecurityGroupEgress",
    "CfnSecurityGroupEgressProps",
    "CfnSecurityGroupIngress",
    "CfnSecurityGroupIngressProps",
    "CfnSecurityGroupProps",
    "CfnSpotFleet",
    "CfnSpotFleetProps",
    "CfnSubnet",
    "CfnSubnetCidrBlock",
    "CfnSubnetCidrBlockProps",
    "CfnSubnetNetworkAclAssociation",
    "CfnSubnetNetworkAclAssociationProps",
    "CfnSubnetProps",
    "CfnSubnetRouteTableAssociation",
    "CfnSubnetRouteTableAssociationProps",
    "CfnTrafficMirrorFilter",
    "CfnTrafficMirrorFilterProps",
    "CfnTrafficMirrorFilterRule",
    "CfnTrafficMirrorFilterRuleProps",
    "CfnTrafficMirrorSession",
    "CfnTrafficMirrorSessionProps",
    "CfnTrafficMirrorTarget",
    "CfnTrafficMirrorTargetProps",
    "CfnTransitGateway",
    "CfnTransitGatewayAttachment",
    "CfnTransitGatewayAttachmentProps",
    "CfnTransitGatewayMulticastDomain",
    "CfnTransitGatewayMulticastDomainAssociation",
    "CfnTransitGatewayMulticastDomainAssociationProps",
    "CfnTransitGatewayMulticastDomainProps",
    "CfnTransitGatewayMulticastGroupMember",
    "CfnTransitGatewayMulticastGroupMemberProps",
    "CfnTransitGatewayMulticastGroupSource",
    "CfnTransitGatewayMulticastGroupSourceProps",
    "CfnTransitGatewayProps",
    "CfnTransitGatewayRoute",
    "CfnTransitGatewayRouteProps",
    "CfnTransitGatewayRouteTable",
    "CfnTransitGatewayRouteTableAssociation",
    "CfnTransitGatewayRouteTableAssociationProps",
    "CfnTransitGatewayRouteTablePropagation",
    "CfnTransitGatewayRouteTablePropagationProps",
    "CfnTransitGatewayRouteTableProps",
    "CfnVPC",
    "CfnVPCCidrBlock",
    "CfnVPCCidrBlockProps",
    "CfnVPCDHCPOptionsAssociation",
    "CfnVPCDHCPOptionsAssociationProps",
    "CfnVPCEndpoint",
    "CfnVPCEndpointConnectionNotification",
    "CfnVPCEndpointConnectionNotificationProps",
    "CfnVPCEndpointProps",
    "CfnVPCEndpointService",
    "CfnVPCEndpointServicePermissions",
    "CfnVPCEndpointServicePermissionsProps",
    "CfnVPCEndpointServiceProps",
    "CfnVPCGatewayAttachment",
    "CfnVPCGatewayAttachmentProps",
    "CfnVPCPeeringConnection",
    "CfnVPCPeeringConnectionProps",
    "CfnVPCProps",
    "CfnVPNConnection",
    "CfnVPNConnectionProps",
    "CfnVPNConnectionRoute",
    "CfnVPNConnectionRouteProps",
    "CfnVPNGateway",
    "CfnVPNGatewayProps",
    "CfnVPNGatewayRoutePropagation",
    "CfnVPNGatewayRoutePropagationProps",
    "CfnVolume",
    "CfnVolumeAttachment",
    "CfnVolumeAttachmentProps",
    "CfnVolumeProps",
    "CloudFormationInit",
    "CommonNetworkAclEntryOptions",
    "ConfigSetProps",
    "ConfigureNatOptions",
    "ConnectionRule",
    "Connections",
    "ConnectionsProps",
    "CpuCredits",
    "DefaultInstanceTenancy",
    "EbsDeviceOptions",
    "EbsDeviceOptionsBase",
    "EbsDeviceProps",
    "EbsDeviceSnapshotOptions",
    "EbsDeviceVolumeType",
    "EnableVpnGatewayOptions",
    "ExecuteFileOptions",
    "FlowLog",
    "FlowLogDestination",
    "FlowLogDestinationConfig",
    "FlowLogDestinationType",
    "FlowLogOptions",
    "FlowLogProps",
    "FlowLogResourceType",
    "FlowLogTrafficType",
    "GatewayConfig",
    "GatewayVpcEndpoint",
    "GatewayVpcEndpointAwsService",
    "GatewayVpcEndpointOptions",
    "GatewayVpcEndpointProps",
    "GenericLinuxImage",
    "GenericLinuxImageProps",
    "GenericSSMParameterImage",
    "GenericWindowsImage",
    "GenericWindowsImageProps",
    "IConnectable",
    "IFlowLog",
    "IGatewayVpcEndpoint",
    "IGatewayVpcEndpointService",
    "IInstance",
    "IInterfaceVpcEndpoint",
    "IInterfaceVpcEndpointService",
    "ILaunchTemplate",
    "IMachineImage",
    "INetworkAcl",
    "INetworkAclEntry",
    "IPeer",
    "IPrivateSubnet",
    "IPublicSubnet",
    "IRouteTable",
    "ISecurityGroup",
    "ISubnet",
    "ISubnetNetworkAclAssociation",
    "IVolume",
    "IVpc",
    "IVpcEndpoint",
    "IVpcEndpointService",
    "IVpcEndpointServiceLoadBalancer",
    "IVpnConnection",
    "IVpnGateway",
    "InitCommand",
    "InitCommandOptions",
    "InitCommandWaitDuration",
    "InitConfig",
    "InitElement",
    "InitFile",
    "InitFileAssetOptions",
    "InitFileOptions",
    "InitGroup",
    "InitPackage",
    "InitService",
    "InitServiceOptions",
    "InitServiceRestartHandle",
    "InitSource",
    "InitSourceAssetOptions",
    "InitSourceOptions",
    "InitUser",
    "InitUserOptions",
    "Instance",
    "InstanceArchitecture",
    "InstanceClass",
    "InstanceInitiatedShutdownBehavior",
    "InstanceProps",
    "InstanceSize",
    "InstanceType",
    "InterfaceVpcEndpoint",
    "InterfaceVpcEndpointAttributes",
    "InterfaceVpcEndpointAwsService",
    "InterfaceVpcEndpointOptions",
    "InterfaceVpcEndpointProps",
    "InterfaceVpcEndpointService",
    "LaunchTemplate",
    "LaunchTemplateAttributes",
    "LaunchTemplateProps",
    "LaunchTemplateSpecialVersions",
    "LaunchTemplateSpotOptions",
    "LinuxUserDataOptions",
    "LocationPackageOptions",
    "LookupMachineImage",
    "LookupMachineImageProps",
    "MachineImage",
    "MachineImageConfig",
    "NamedPackageOptions",
    "NatInstanceImage",
    "NatInstanceProps",
    "NatInstanceProvider",
    "NatProvider",
    "NetworkAcl",
    "NetworkAclEntry",
    "NetworkAclEntryProps",
    "NetworkAclProps",
    "OperatingSystemType",
    "Peer",
    "Port",
    "PortProps",
    "PrivateSubnet",
    "PrivateSubnetAttributes",
    "PrivateSubnetProps",
    "Protocol",
    "PublicSubnet",
    "PublicSubnetAttributes",
    "PublicSubnetProps",
    "RouterType",
    "S3DownloadOptions",
    "SecurityGroup",
    "SecurityGroupImportOptions",
    "SecurityGroupProps",
    "SelectedSubnets",
    "SpotInstanceInterruption",
    "SpotRequestType",
    "Subnet",
    "SubnetAttributes",
    "SubnetConfiguration",
    "SubnetFilter",
    "SubnetNetworkAclAssociation",
    "SubnetNetworkAclAssociationProps",
    "SubnetProps",
    "SubnetSelection",
    "SubnetType",
    "TrafficDirection",
    "UserData",
    "Volume",
    "VolumeAttributes",
    "VolumeProps",
    "Vpc",
    "VpcAttributes",
    "VpcEndpoint",
    "VpcEndpointService",
    "VpcEndpointServiceProps",
    "VpcEndpointType",
    "VpcLookupOptions",
    "VpcProps",
    "VpnConnection",
    "VpnConnectionOptions",
    "VpnConnectionProps",
    "VpnConnectionType",
    "VpnGateway",
    "VpnGatewayProps",
    "VpnTunnelOption",
    "WindowsImage",
    "WindowsImageProps",
    "WindowsVersion",
]

publication.publish()
