# This file is automatically generated by botocraft.  Do not edit directly.
# pylint: disable=anomalous-backslash-in-string,unsubscriptable-object,line-too-long,arguments-differ,arguments-renamed
# mypy: disable-error-code="index, override, assignment"
from collections import OrderedDict
from datetime import datetime
from functools import cached_property
from typing import Any, ClassVar, Dict, List, Literal, Optional, Type, cast

from pydantic import Field

from botocraft.mixins.autoscaling import AutoScalingGroupInstancesMixin
from botocraft.mixins.tags import TagsDictMixin
from botocraft.services.common import Filter, Tag
from botocraft.services.ec2 import (LaunchTemplateVersion,
                                    LaunchTemplateVersionManager)

from .abstract import (Boto3Model, Boto3ModelManager, PrimaryBoto3Model,
                       ReadonlyBoto3Model, ReadonlyBoto3ModelManager,
                       ReadonlyPrimaryBoto3Model)

# ===============
# Managers
# ===============


class AutoScalingGroupManager(Boto3ModelManager):
    service_name: str = "autoscaling"

    def create(
        self,
        model: "AutoScalingGroup",
        InstanceId: Optional[str] = None,
        LifecycleHookSpecificationList: Optional[
            List["LifecycleHookSpecification"]
        ] = None,
    ) -> None:
        """
        **We strongly recommend using a launch template when calling this
        operation to ensure full functionality for Amazon EC2 Auto Scaling and
        Amazon EC2.**

        Args:
            model: The :py:class:`AutoScalingGroup` to create.

        Keyword Args:
            InstanceId: The ID of the instance used to base the launch configuration
                on. If specified, Amazon EC2 Auto Scaling uses the configuration values
                from the specified instance to create a new launch configuration. To get
                the instance ID, use the Amazon EC2 `DescribeInstances
                <https://docs.aws.amazon.com/AWSEC2/latest/APIRef
                erence/API_DescribeInstances.html>`_ API operation. For more information,
                see `Creating an Auto Scaling group using an EC2 instance
                <https://docs.aws.amazon.com/autoscaling/ec2/userguide/create-asg- from-
                instance.html>`_ in the *Amazon EC2 Auto Scaling User Guide*.
            LifecycleHookSpecificationList: One or more lifecycle hooks to add to the
                Auto Scaling group before instances are launched.
        """
        data = model.model_dump(exclude_none=True, by_alias=True)
        args = dict(
            AutoScalingGroupName=data.get("AutoScalingGroupName"),
            MinSize=data.get("MinSize"),
            MaxSize=data.get("MaxSize"),
            LaunchConfigurationName=data.get("LaunchConfigurationName"),
            LaunchTemplate=data.get("LaunchTemplate"),
            MixedInstancesPolicy=data.get("MixedInstancesPolicy"),
            InstanceId=self.serialize(InstanceId),
            DesiredCapacity=data.get("DesiredCapacity"),
            DefaultCooldown=data.get("DefaultCooldown"),
            AvailabilityZones=data.get("AvailabilityZones"),
            LoadBalancerNames=data.get("LoadBalancerNames"),
            TargetGroupARNs=data.get("TargetGroupARNs"),
            HealthCheckType=data.get("HealthCheckType"),
            HealthCheckGracePeriod=data.get("HealthCheckGracePeriod"),
            PlacementGroup=data.get("PlacementGroup"),
            VPCZoneIdentifier=data.get("VPCZoneIdentifier"),
            TerminationPolicies=data.get("TerminationPolicies"),
            NewInstancesProtectedFromScaleIn=data.get(
                "NewInstancesProtectedFromScaleIn"
            ),
            CapacityRebalance=data.get("CapacityRebalance"),
            LifecycleHookSpecificationList=self.serialize(
                LifecycleHookSpecificationList
            ),
            Tags=data.get("Tags"),
            ServiceLinkedRoleARN=data.get("ServiceLinkedRoleARN"),
            MaxInstanceLifetime=data.get("MaxInstanceLifetime"),
            Context=data.get("Context"),
            DesiredCapacityType=data.get("DesiredCapacityType"),
            DefaultInstanceWarmup=data.get("DefaultInstanceWarmup"),
            TrafficSources=data.get("TrafficSources"),
            InstanceMaintenancePolicy=data.get("InstanceMaintenancePolicy"),
        )
        self.client.create_auto_scaling_group(
            **{k: v for k, v in args.items() if v is not None}
        )

    def update(self, model: "AutoScalingGroup") -> None:
        """
        **We strongly recommend that all Auto Scaling groups use launch
        templates to ensure full functionality for Amazon EC2 Auto Scaling and
        Amazon EC2.**

        Args:
            model: The :py:class:`AutoScalingGroup` to update.
        """
        data = model.model_dump(exclude_none=True, by_alias=True)
        args = dict(
            AutoScalingGroupName=data.get("AutoScalingGroupName"),
            LaunchConfigurationName=data.get("LaunchConfigurationName"),
            LaunchTemplate=data.get("LaunchTemplate"),
            MixedInstancesPolicy=data.get("MixedInstancesPolicy"),
            MinSize=data.get("MinSize"),
            MaxSize=data.get("MaxSize"),
            DesiredCapacity=data.get("DesiredCapacity"),
            DefaultCooldown=data.get("DefaultCooldown"),
            AvailabilityZones=data.get("AvailabilityZones"),
            HealthCheckType=data.get("HealthCheckType"),
            HealthCheckGracePeriod=data.get("HealthCheckGracePeriod"),
            PlacementGroup=data.get("PlacementGroup"),
            VPCZoneIdentifier=data.get("VPCZoneIdentifier"),
            TerminationPolicies=data.get("TerminationPolicies"),
            NewInstancesProtectedFromScaleIn=data.get(
                "NewInstancesProtectedFromScaleIn"
            ),
            ServiceLinkedRoleARN=data.get("ServiceLinkedRoleARN"),
            MaxInstanceLifetime=data.get("MaxInstanceLifetime"),
            CapacityRebalance=data.get("CapacityRebalance"),
            Context=data.get("Context"),
            DesiredCapacityType=data.get("DesiredCapacityType"),
            DefaultInstanceWarmup=data.get("DefaultInstanceWarmup"),
            InstanceMaintenancePolicy=data.get("InstanceMaintenancePolicy"),
        )
        self.client.update_auto_scaling_group(
            **{k: v for k, v in args.items() if v is not None}
        )

    def delete(
        self, AutoScalingGroupName: str, *, ForceDelete: Optional[bool] = None
    ) -> None:
        """
        Deletes the specified Auto Scaling group.

        Args:
            AutoScalingGroupName: The name of the Auto Scaling group.

        Keyword Args:
            ForceDelete: Specifies that the group is to be deleted along with all
                instances associated with the group, without waiting for all instances to
                be terminated. This action also deletes any outstanding lifecycle actions
                associated with the group.
        """
        args: Dict[str, Any] = dict(
            AutoScalingGroupName=self.serialize(AutoScalingGroupName),
            ForceDelete=self.serialize(ForceDelete),
        )
        self.client.delete_auto_scaling_group(
            **{k: v for k, v in args.items() if v is not None}
        )

    def get(self, AutoScalingGroupName: str) -> Optional["AutoScalingGroup"]:
        """
        Gets information about the Auto Scaling groups in the account and
        Region.

        Args:
            AutoScalingGroupName: The name of the Auto Scaling group. The name can be a
                maximum of 1600 characters.
        """
        args: Dict[str, Any] = dict(
            AutoScalingGroupNames=self.serialize([AutoScalingGroupName])
        )
        _response = self.client.describe_auto_scaling_groups(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = AutoScalingGroupsType(**_response)

        if response.AutoScalingGroups:
            return response.AutoScalingGroups[0]
        return None

    def list(
        self,
        *,
        AutoScalingGroupNames: Optional[List[str]] = None,
        Filters: Optional[List[Filter]] = None
    ) -> List["AutoScalingGroup"]:
        """
        Gets information about the Auto Scaling groups in the account and
        Region.

        Keyword Args:
            AutoScalingGroupNames: The names of the Auto Scaling groups. By default,
                you can only specify up to 50 names. You can optionally increase this limit
                using the ``MaxRecords`` property.
            Filters: One or more filters to limit the results based on specific tags.
        """
        paginator = self.client.get_paginator("describe_auto_scaling_groups")
        args: Dict[str, Any] = dict(
            AutoScalingGroupNames=self.serialize(AutoScalingGroupNames),
            Filters=self.serialize(Filters),
        )
        response_iterator = paginator.paginate(
            **{k: v for k, v in args.items() if v is not None}
        )
        results: List["AutoScalingGroup"] = []
        for _response in response_iterator:
            response = AutoScalingGroupsType(**_response)
            if response.AutoScalingGroups:
                results.extend(response.AutoScalingGroups)
            else:
                break
        return results

    def scale(self, AutoScalingGroupName: str, DesiredCapacity: int) -> None:
        """
        Sets the size of the specified Auto Scaling group.

        Args:
            AutoScalingGroupName: The name of the Auto Scaling group.
            DesiredCapacity: The desired capacity is the initial capacity of the Auto
                Scaling group after this operation completes and the capacity it attempts
                to maintain.
        """
        args: Dict[str, Any] = dict(
            AutoScalingGroupName=self.serialize(AutoScalingGroupName),
            DesiredCapacity=self.serialize(DesiredCapacity),
            HonorCooldown=False,
        )
        self.client.set_desired_capacity(
            **{k: v for k, v in args.items() if v is not None}
        )


class LaunchConfigurationManager(Boto3ModelManager):
    service_name: str = "autoscaling"

    def create(
        self, model: "LaunchConfiguration", InstanceId: Optional[str] = None
    ) -> None:
        """
        Creates a launch configuration.

        Args:
            model: The :py:class:`LaunchConfiguration` to create.

        Keyword Args:
            InstanceId: The ID of the instance to use to create the launch
                configuration. The new launch configuration derives attributes from the
                instance, except for the block device mapping.
        """
        data = model.model_dump(exclude_none=True, by_alias=True)
        args = dict(
            LaunchConfigurationName=data.get("LaunchConfigurationName"),
            ImageId=data.get("ImageId"),
            KeyName=data.get("KeyName"),
            SecurityGroups=data.get("SecurityGroups"),
            ClassicLinkVPCId=data.get("ClassicLinkVPCId"),
            ClassicLinkVPCSecurityGroups=data.get("ClassicLinkVPCSecurityGroups"),
            UserData=data.get("UserData"),
            InstanceId=self.serialize(InstanceId),
            InstanceType=data.get("InstanceType"),
            KernelId=data.get("KernelId"),
            RamdiskId=data.get("RamdiskId"),
            BlockDeviceMappings=data.get("BlockDeviceMappings"),
            InstanceMonitoring=data.get("InstanceMonitoring"),
            SpotPrice=data.get("SpotPrice"),
            IamInstanceProfile=data.get("IamInstanceProfile"),
            EbsOptimized=data.get("EbsOptimized"),
            AssociatePublicIpAddress=data.get("AssociatePublicIpAddress"),
            PlacementTenancy=data.get("PlacementTenancy"),
            MetadataOptions=data.get("MetadataOptions"),
        )
        self.client.create_launch_configuration(
            **{k: v for k, v in args.items() if v is not None}
        )

    def delete(self, LaunchConfigurationName: str) -> None:
        """
        Deletes the specified launch configuration.

        Args:
            LaunchConfigurationName: The name of the launch configuration.
        """
        args: Dict[str, Any] = dict(
            LaunchConfigurationName=self.serialize(LaunchConfigurationName)
        )
        self.client.delete_launch_configuration(
            **{k: v for k, v in args.items() if v is not None}
        )

    def get(self, LaunchConfigurationName: str) -> Optional["LaunchConfiguration"]:
        """
        Gets information about the launch configurations in the account and
        Region.

        Args:
            LaunchConfigurationName: The name of the launch configuration. This name
                must be unique per Region per account.
        """
        args: Dict[str, Any] = dict(
            LaunchConfigurationNames=self.serialize([LaunchConfigurationName])
        )
        _response = self.client.describe_launch_configurations(
            **{k: v for k, v in args.items() if v is not None}
        )
        response = LaunchConfigurationsType(**_response)

        if response.LaunchConfigurations:
            return response.LaunchConfigurations[0]
        return None

    def list(
        self, *, LaunchConfigurationNames: Optional[List[str]] = None
    ) -> List["LaunchConfiguration"]:
        """
        Gets information about the launch configurations in the account and
        Region.

        Keyword Args:
            LaunchConfigurationNames: The launch configuration names. If you omit this
                property, all launch configurations are described.
        """
        paginator = self.client.get_paginator("describe_launch_configurations")
        args: Dict[str, Any] = dict(
            LaunchConfigurationNames=self.serialize(LaunchConfigurationNames)
        )
        response_iterator = paginator.paginate(
            **{k: v for k, v in args.items() if v is not None}
        )
        results: List["LaunchConfiguration"] = []
        for _response in response_iterator:
            response = LaunchConfigurationsType(**_response)
            if response.LaunchConfigurations:
                results.extend(response.LaunchConfigurations)
            else:
                break
        return results


# ==============
# Service Models
# ==============


class AutoScalingLaunchTemplateSpecification(Boto3Model):
    """
    The launch template for the group.
    """

    #: The ID of the launch template. To get the template ID, use the Amazon EC2 `Desc
    #: ribeLaunchTemplates <https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API
    #: _DescribeLaunchTemplates.html>`_ API operation. New launch templates can be
    #: created using the Amazon EC2 `CreateLaunchTemplate <https://docs.aws.amazon.com
    #: /AWSEC2/latest/APIReference/API_CreateLaunchTemplate.html>`_ API.
    LaunchTemplateId: Optional[str] = None
    #: The name of the launch template. To get the template name, use the Amazon EC2 `
    #: DescribeLaunchTemplates <https://docs.aws.amazon.com/AWSEC2/latest/APIReference
    #: /API_DescribeLaunchTemplates.html>`_ API operation. New launch templates can be
    #: created using the Amazon EC2 `CreateLaunchTemplate <https://docs.aws.amazon.com
    #: /AWSEC2/latest/APIReference/API_CreateLaunchTemplate.html>`_ API.
    LaunchTemplateName: Optional[str] = None
    #: The version number, ``$Latest``, or ``$Default``. To get the version number,
    #: use the Amazon EC2 `DescribeLaunchTemplateVersions <https://docs.aws.amazon.com
    #: /AWSEC2/latest/APIReference/API_DescribeLaunchTemplateVersions.html>`_ API
    #: operation. New launch template versions can be created using the Amazon EC2 `Cr
    #: eateLaunchTemplateVersion <https://docs.aws.amazon.com/AWSEC2/latest/APIReferen
    #: ce/API_CreateLaunchTemplateVersion.html>`_ API. If the value is ``$Latest``,
    #: Amazon EC2 Auto Scaling selects the latest version of the launch template when
    #: launching instances. If the value is ``$Default``, Amazon EC2 Auto Scaling
    #: selects the default version of the launch template when launching instances.
    #: The default value is ``$Default``.
    Version: Optional[str] = None


class VCpuCountRequest(Boto3Model):
    """
    The minimum and maximum number of vCPUs for an instance type.
    """

    #: The minimum number of vCPUs.
    Min: int
    #: The maximum number of vCPUs.
    Max: Optional[int] = None


class AutoScalingMemoryMiBRequest(Boto3Model):
    """
    The minimum and maximum instance memory size for an instance type, in MiB.
    """

    #: The memory minimum in MiB.
    Min: int
    #: The memory maximum in MiB.
    Max: Optional[int] = None


class MemoryGiBPerVCpuRequest(Boto3Model):
    """
    The minimum and maximum amount of memory per vCPU for an instance type, in
    GiB.

    Default: No minimum or maximum limits
    """

    #: The memory minimum in GiB.
    Min: Optional[float] = None
    #: The memory maximum in GiB.
    Max: Optional[float] = None


class AutoScalingNetworkInterfaceCountRequest(Boto3Model):
    """
    The minimum and maximum number of network interfaces for an instance type.

    Default: No minimum or maximum limits
    """

    #: The minimum number of network interfaces.
    Min: Optional[int] = None
    #: The maximum number of network interfaces.
    Max: Optional[int] = None


class AutoScalingTotalLocalStorageGBRequest(Boto3Model):
    """
    The minimum and maximum total local storage size for an instance type, in
    GB.

    Default: No minimum or maximum limits
    """

    #: The storage minimum in GB.
    Min: Optional[float] = None
    #: The storage maximum in GB.
    Max: Optional[float] = None


class AutoScalingBaselineEbsBandwidthMbsRequest(Boto3Model):
    """The minimum and maximum baseline bandwidth performance for an instance type, in
    Mbps. For more information, see `Amazon EBS–optimized
    instances <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-
    optimized.html>`_ in the *Amazon EC2 User Guide for Linux Instances*.

    Default: No minimum or maximum limits
    """

    #: The minimum value in Mbps.
    Min: Optional[int] = None
    #: The maximum value in Mbps.
    Max: Optional[int] = None


class AutoScalingAcceleratorCountRequest(Boto3Model):
    """
    The minimum and maximum number of accelerators (GPUs, FPGAs, or Amazon Web
    Services Inferentia chips) for an instance type.

    To exclude accelerator-enabled instance types, set ``Max`` to ``0``.

    Default: No minimum or maximum limits
    """

    #: The minimum value.
    Min: Optional[int] = None
    #: The maximum value.
    Max: Optional[int] = None


class AutoScalingAcceleratorTotalMemoryMiBRequest(Boto3Model):
    """
    The minimum and maximum total memory size for the accelerators on an
    instance type, in MiB.

    Default: No minimum or maximum limits
    """

    #: The memory minimum in MiB.
    Min: Optional[int] = None
    #: The memory maximum in MiB.
    Max: Optional[int] = None


class NetworkBandwidthGbpsRequest(Boto3Model):
    """
    The minimum and maximum amount of network bandwidth, in gigabits per second
    (Gbps).

    Default: No minimum or maximum limits
    """

    #: The minimum amount of network bandwidth, in gigabits per second (Gbps).
    Min: Optional[float] = None
    #: The maximum amount of network bandwidth, in gigabits per second (Gbps).
    Max: Optional[float] = None


class AutoScalingInstanceRequirements(Boto3Model):
    """
    The instance requirements. Amazon EC2 Auto Scaling uses your specified
    requirements to identify instance types. Then, it uses your On-Demand and
    Spot allocation strategies to launch instances from these instance types.

    You can specify up to four separate sets of instance requirements per Auto
    Scaling group. This is useful for provisioning instances from different Amazon
    Machine Images (AMIs) in the same Auto Scaling group. To do this, create the
    AMIs and create a new launch template for each AMI. Then, create a compatible
    set of instance requirements for each launch template.

    If you specify ``InstanceRequirements``, you can't specify ``InstanceType``.
    """

    #: The minimum and maximum number of vCPUs for an instance type.
    VCpuCount: VCpuCountRequest
    #: The minimum and maximum instance memory size for an instance type, in MiB.
    MemoryMiB: AutoScalingMemoryMiBRequest
    #: Lists which specific CPU manufacturers to include.
    CpuManufacturers: Optional[
        List[Literal["intel", "amd", "amazon-web-services"]]
    ] = None
    #: The minimum and maximum amount of memory per vCPU for an instance type, in GiB.
    MemoryGiBPerVCpu: Optional[MemoryGiBPerVCpuRequest] = None
    #: The instance types to exclude. You can use strings with one or more wild cards,
    #: represented by an asterisk (``*``), to exclude an instance family, type, size,
    #: or generation. The following are examples: ``m5.8xlarge``, ``c5*.*``,
    #: ``m5a.*``, ``r*``, ``*3*``.
    ExcludedInstanceTypes: Optional[List[str]] = None
    #: Indicates whether current or previous generation instance types are included.
    InstanceGenerations: Optional[List[Literal["current", "previous"]]] = None
    #: The price protection threshold for Spot Instances. This is the maximum you’ll
    #: pay for a Spot Instance, expressed as a percentage higher than the least
    #: expensive current generation M, C, or R instance type with your specified
    #: attributes. When Amazon EC2 Auto Scaling selects instance types with your
    #: attributes, we will exclude instance types whose price is higher than your
    #: threshold. The parameter accepts an integer, which Amazon EC2 Auto Scaling
    #: interprets as a percentage. To turn off price protection, specify a high value,
    #: such as ``999999``.
    SpotMaxPricePercentageOverLowestPrice: Optional[int] = None
    #: The price protection threshold for On-Demand Instances. This is the maximum
    #: you’ll pay for an On-Demand Instance, expressed as a percentage higher than the
    #: least expensive current generation M, C, or R instance type with your specified
    #: attributes. When Amazon EC2 Auto Scaling selects instance types with your
    #: attributes, we will exclude instance types whose price is higher than your
    #: threshold. The parameter accepts an integer, which Amazon EC2 Auto Scaling
    #: interprets as a percentage. To turn off price protection, specify a high value,
    #: such as ``999999``.
    OnDemandMaxPricePercentageOverLowestPrice: Optional[int] = None
    #: Indicates whether bare metal instance types are included, excluded, or
    #: required.
    BareMetal: Optional[Literal["included", "excluded", "required"]] = None
    #: Indicates whether burstable performance instance types are included, excluded,
    #: or required. For more information, see `Burstable performance instances
    #: <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/burstable- performance-
    #: instances.html>`_ in the *Amazon EC2 User Guide for Linux Instances*.
    BurstablePerformance: Optional[Literal["included", "excluded", "required"]] = None
    #: Indicates whether instance types must provide On-Demand Instance hibernation
    #: support.
    RequireHibernateSupport: Optional[bool] = None
    #: The minimum and maximum number of network interfaces for an instance type.
    NetworkInterfaceCount: Optional[AutoScalingNetworkInterfaceCountRequest] = None
    #: Indicates whether instance types with instance store volumes are included,
    #: excluded, or required. For more information, see `Amazon EC2 instance store <ht
    #: tps://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html>`_ in
    #: the *Amazon EC2 User Guide for Linux Instances*.
    LocalStorage: Optional[Literal["included", "excluded", "required"]] = None
    #: Indicates the type of local storage that is required.
    LocalStorageTypes: Optional[List[Literal["hdd", "ssd"]]] = None
    #: The minimum and maximum total local storage size for an instance type, in GB.
    TotalLocalStorageGB: Optional[AutoScalingTotalLocalStorageGBRequest] = None
    #: The minimum and maximum baseline bandwidth performance for an instance type, in
    #: Mbps. For more information, see `Amazon EBS–optimized instances
    #: <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs- optimized.html>`_ in
    #: the *Amazon EC2 User Guide for Linux Instances*.
    BaselineEbsBandwidthMbps: Optional[AutoScalingBaselineEbsBandwidthMbsRequest] = None
    #: Lists the accelerator types that must be on an instance type.
    AcceleratorTypes: Optional[List[Literal["gpu", "fpga", "inference"]]] = None
    #: The minimum and maximum number of accelerators (GPUs, FPGAs, or Amazon Web
    #: Services Inferentia chips) for an instance type.
    AcceleratorCount: Optional[AutoScalingAcceleratorCountRequest] = None
    #: Indicates whether instance types must have accelerators by specific
    #: manufacturers.
    AcceleratorManufacturers: Optional[
        List[Literal["nvidia", "amd", "amazon-web-services", "xilinx"]]
    ] = None
    #: Lists the accelerators that must be on an instance type.
    AcceleratorNames: Optional[
        List[Literal["a100", "v100", "k80", "t4", "m60", "radeon-pro-v520", "vu9p"]]
    ] = None
    #: The minimum and maximum total memory size for the accelerators on an instance
    #: type, in MiB.
    AcceleratorTotalMemoryMiB: Optional[
        AutoScalingAcceleratorTotalMemoryMiBRequest
    ] = None
    #: The minimum and maximum amount of network bandwidth, in gigabits per second
    #: (Gbps).
    NetworkBandwidthGbps: Optional[NetworkBandwidthGbpsRequest] = None
    #: The instance types to apply your specified attributes against. All other
    #: instance types are ignored, even if they match your specified attributes.
    AllowedInstanceTypes: Optional[List[str]] = None


class LaunchTemplateOverrides(Boto3Model):
    """Use this structure to let Amazon EC2 Auto Scaling do the following when the
    Auto Scaling group has a mixed instances policy:

    * Override the instance type that is specified in the launch template.
    * Use multiple instance types.

    Specify the instance types that you want, or define your instance requirements
    instead and let Amazon EC2 Auto Scaling provision the available instance types
    that meet your requirements. This can provide Amazon EC2 Auto Scaling with a
    larger selection of instance types to choose from when fulfilling Spot and On-
    Demand capacities. You can view which instance types are matched before you
    apply the instance requirements to your Auto Scaling group.

    After you define your instance requirements, you don't have to keep updating
    these settings to get new EC2 instance types automatically. Amazon EC2 Auto
    Scaling uses the instance requirements of the Auto Scaling group to determine
    whether a new EC2 instance type can be used.
    """

    #: The instance type, such as ``m3.xlarge``. You must specify an instance type
    #: that is supported in your requested Region and Availability Zones. For more
    #: information, see `Instance types
    #: <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html>`_ in
    #: the *Amazon Elastic Compute Cloud User Guide*.
    InstanceType: Optional[str] = None
    #: If you provide a list of instance types to use, you can specify the number of
    #: capacity units provided by each instance type in terms of virtual CPUs, memory,
    #: storage, throughput, or other relative performance characteristic. When a Spot
    #: or On-Demand Instance is launched, the capacity units count toward the desired
    #: capacity. Amazon EC2 Auto Scaling launches instances until the desired capacity
    #: is totally fulfilled, even if this results in an overage. For example, if there
    #: are two units remaining to fulfill capacity, and Amazon EC2 Auto Scaling can
    #: only launch an instance with a ``WeightedCapacity`` of five units, the instance
    #: is launched, and the desired capacity is exceeded by three units. For more
    #: information, see `Configuring instance weighting for Amazon EC2 Auto Scaling
    #: <https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto- scaling-mixed-
    #: instances-groups-instance-weighting.html>`_ in the *Amazon EC2 Auto Scaling
    #: User Guide*. Value must be in the range of 1–999.
    WeightedCapacity: Optional[str] = None
    #: Provides a launch template for the specified instance type or set of instance
    #: requirements. For example, some instance types might require a launch template
    #: with a different AMI. If not provided, Amazon EC2 Auto Scaling uses the launch
    #: template that's specified in the ``LaunchTemplate`` definition. For more
    #: information, see `Specifying a different launch template for an instance type
    #: <https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling- mixed-
    #: instances-groups-launch-template-overrides.html>`_ in the *Amazon EC2 Auto
    #: Scaling User Guide*.
    LaunchTemplateSpecification: Optional[AutoScalingLaunchTemplateSpecification] = None
    #: The instance requirements. Amazon EC2 Auto Scaling uses your specified
    #: requirements to identify instance types. Then, it uses your On-Demand and Spot
    #: allocation strategies to launch instances from these instance types.
    InstanceRequirements: Optional[AutoScalingInstanceRequirements] = None


class AutoScalingLaunchTemplate(Boto3Model):
    """
    One or more launch templates and the instance types (overrides) that are
    used to launch EC2 instances to fulfill On-Demand and Spot capacities.
    """

    #: The launch template.
    LaunchTemplateSpecification: Optional[AutoScalingLaunchTemplateSpecification] = None
    #: Any properties that you specify override the same properties in the launch
    #: template.
    Overrides: Optional[List["LaunchTemplateOverrides"]] = None


class AutoScalingInstancesDistribution(Boto3Model):
    """
    The instances distribution.
    """

    #: The allocation strategy to apply to your On-Demand Instances when they are
    #: launched. Possible instance types are determined by the launch template
    #: overrides that you specify.
    OnDemandAllocationStrategy: Optional[str] = None
    #: The minimum amount of the Auto Scaling group's capacity that must be fulfilled
    #: by On-Demand Instances. This base portion is launched first as your group
    #: scales.
    OnDemandBaseCapacity: Optional[int] = None
    #: Controls the percentages of On-Demand Instances and Spot Instances for your
    #: additional capacity beyond ``OnDemandBaseCapacity``. Expressed as a number (for
    #: example, 20 specifies 20% On-Demand Instances, 80% Spot Instances). If set to
    #: 100, only On-Demand Instances are used.
    OnDemandPercentageAboveBaseCapacity: Optional[int] = None
    #: The allocation strategy to apply to your Spot Instances when they are launched.
    #: Possible instance types are determined by the launch template overrides that
    #: you specify.
    SpotAllocationStrategy: Optional[str] = None
    #: The number of Spot Instance pools across which to allocate your Spot Instances.
    #: The Spot pools are determined from the different instance types in the
    #: overrides. Valid only when the ``SpotAllocationStrategy`` is ``lowest-price``.
    #: Value must be in the range of 1–20.
    SpotInstancePools: Optional[int] = None
    #: The maximum price per unit hour that you are willing to pay for a Spot
    #: Instance. If your maximum price is lower than the Spot price for the instance
    #: types that you selected, your Spot Instances are not launched. We do not
    #: recommend specifying a maximum price because it can lead to increased
    #: interruptions. When Spot Instances launch, you pay the current Spot price. To
    #: remove a maximum price that you previously set, include the property but
    #: specify an empty string ("") for the value.
    SpotMaxPrice: Optional[str] = None


class AutoScalingMixedInstancesPolicy(Boto3Model):
    """
    The mixed instances policy for the group.
    """

    #: One or more launch templates and the instance types (overrides) that are used
    #: to launch EC2 instances to fulfill On-Demand and Spot capacities.
    LaunchTemplate: Optional[AutoScalingLaunchTemplate] = None
    #: The instances distribution.
    InstancesDistribution: Optional[AutoScalingInstancesDistribution] = None


class AutoScalingInstanceReference(Boto3Model):
    """
    Describes an EC2 instance.
    """

    #: The ID of the instance.
    InstanceId: str
    #: The instance type of the EC2 instance.
    InstanceType: Optional[str] = None
    #: The Availability Zone in which the instance is running.
    AvailabilityZone: str
    #: A description of the current lifecycle state. The ``Quarantined`` state is not
    #: used. For information about lifecycle states, see `Instance lifecycle <https://
    #: docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroupLifecycle.html>`_
    #: in the *Amazon EC2 Auto Scaling User Guide*.
    LifecycleState: Literal[
        "Pending",
        "Pending:Wait",
        "Pending:Proceed",
        "Quarantined",
        "InService",
        "Terminating",
        "Terminating:Wait",
        "Terminating:Proceed",
        "Terminated",
        "Detaching",
        "Detached",
        "EnteringStandby",
        "Standby",
        "Warmed:Pending",
        "Warmed:Pending:Wait",
        "Warmed:Pending:Proceed",
        "Warmed:Terminating",
        "Warmed:Terminating:Wait",
        "Warmed:Terminating:Proceed",
        "Warmed:Terminated",
        "Warmed:Stopped",
        "Warmed:Running",
        "Warmed:Hibernated",
    ]
    #: The last reported health status of the instance. ``Healthy`` means that the
    #: instance is healthy and should remain in service. ``Unhealthy`` means that the
    #: instance is unhealthy and that Amazon EC2 Auto Scaling should terminate and
    #: replace it.
    HealthStatus: str
    #: The launch configuration associated with the instance.
    LaunchConfigurationName: Optional[str] = None
    #: The launch template for the instance.
    LaunchTemplate: Optional[AutoScalingLaunchTemplateSpecification] = None
    #: Indicates whether the instance is protected from termination by Amazon EC2 Auto
    #: Scaling when scaling in.
    ProtectedFromScaleIn: bool
    #: The number of capacity units contributed by the instance based on its instance
    #: type.
    WeightedCapacity: Optional[str] = None


class SuspendedProcess(Boto3Model):
    """
    Describes an auto scaling process that has been suspended.

    For more information, see
    `Scaling processes <https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-suspend-
    resume-processes.html#process-types>`_ in the *Amazon EC2 Auto Scaling User
    Guide*.
    """

    #: The name of the suspended process.
    ProcessName: Optional[str] = None
    #: The reason that the process was suspended.
    SuspensionReason: Optional[str] = None


class EnabledMetric(Boto3Model):
    """
    Describes an enabled Auto Scaling group metric.
    """

    #: One of the following metrics:
    Metric: Optional[str] = None
    #: The granularity of the metric. The only valid value is ``1Minute``.
    Granularity: Optional[str] = None


class TagDescription(Boto3Model):
    """
    Describes a tag for an Auto Scaling group.
    """

    #: The name of the group.
    ResourceId: Optional[str] = None
    #: The type of resource. The only supported value is ``auto-scaling-group``.
    ResourceType: Optional[str] = None
    #: The tag key.
    Key: Optional[str] = None
    #: The tag value.
    Value: Optional[str] = None
    #: Determines whether the tag is added to new instances as they are launched in
    #: the group.
    PropagateAtLaunch: Optional[bool] = None


class AutoScalingInstanceReusePolicy(Boto3Model):
    """
    The instance reuse policy.
    """

    #: Specifies whether instances in the Auto Scaling group can be returned to the
    #: warm pool on scale in.
    ReuseOnScaleIn: Optional[bool] = None


class AutoScalingWarmPoolConfiguration(Boto3Model):
    """
    The warm pool for the group.
    """

    #: The maximum number of instances that are allowed to be in the warm pool or in
    #: any state except ``Terminated`` for the Auto Scaling group.
    MaxGroupPreparedCapacity: Optional[int] = None
    #: The minimum number of instances to maintain in the warm pool.
    MinSize: Optional[int] = None
    #: The instance state to transition to after the lifecycle actions are complete.
    PoolState: Optional[Literal["Stopped", "Running", "Hibernated"]] = None
    #: The status of a warm pool that is marked for deletion.
    Status: Optional[Literal["PendingDelete"]] = None
    #: The instance reuse policy.
    InstanceReusePolicy: Optional[AutoScalingInstanceReusePolicy] = None


class TrafficSourceIdentifier(Boto3Model):
    """
    Identifying information for a traffic source.
    """

    #: Identifies the traffic source.
    Identifier: str
    #: Provides additional context for the value of ``Identifier``.
    Type: Optional[str] = None


class AutoScalingInstanceMaintenancePolicy(Boto3Model):
    """
    An instance maintenance policy.
    """

    #: Specifies the lower threshold as a percentage of the desired capacity of the
    #: Auto Scaling group. It represents the minimum percentage of the group to keep
    #: in service, healthy, and ready to use to support your workload when replacing
    #: instances. Value range is 0 to 100. After it's set, a value of ``-1`` will
    #: clear the previously set value.
    MinHealthyPercentage: Optional[int] = None
    #: Specifies the upper threshold as a percentage of the desired capacity of the
    #: Auto Scaling group. It represents the maximum percentage of the group that can
    #: be in service and healthy, or pending, to support your workload when replacing
    #: instances. Value range is 100 to 200. After it's set, a value of ``-1`` will
    #: clear the previously set value.
    MaxHealthyPercentage: Optional[int] = None


class AutoScalingGroup(
    TagsDictMixin, AutoScalingGroupInstancesMixin, PrimaryBoto3Model
):
    """
    Describes an Auto Scaling group.
    """

    tag_class: ClassVar[Type] = TagDescription
    objects: ClassVar[Boto3ModelManager] = AutoScalingGroupManager()

    #: The duration of the default cooldown period, in seconds.
    DefaultCooldown: int
    #: The name of the Auto Scaling group.
    AutoScalingGroupName: str
    #: The Amazon Resource Name (ARN) of the Auto Scaling group.
    AutoScalingGroupARN: str = Field(default=None, frozen=True)
    #: The name of the associated launch configuration.
    LaunchConfigurationName: Optional[str] = None
    #: The launch template for the group.
    LaunchTemplate: Optional[AutoScalingLaunchTemplateSpecification] = None
    #: The mixed instances policy for the group.
    MixedInstancesPolicy: Optional[AutoScalingMixedInstancesPolicy] = None
    #: The minimum size of the group.
    MinSize: int
    #: The maximum size of the group.
    MaxSize: int
    #: The desired size of the group.
    DesiredCapacity: int
    #: The predicted capacity of the group when it has a predictive scaling policy.
    PredictedCapacity: int = Field(default=None, frozen=True)
    #: One or more Availability Zones for the group.
    AvailabilityZones: List[str]
    #: One or more load balancers associated with the group.
    LoadBalancerNames: Optional[List[str]] = None
    #: The Amazon Resource Names (ARN) of the target groups for your load balancer.
    TargetGroupARNs: Optional[List[str]] = None
    #: A comma-separated value string of one or more health check types.
    HealthCheckType: str
    #: The duration of the health check grace period, in seconds.
    HealthCheckGracePeriod: Optional[int] = None
    #: The EC2 instances associated with the group.
    Instances: List["AutoScalingInstanceReference"] = Field(default=None, frozen=True)
    #: The date and time the group was created.
    CreatedTime: datetime = Field(frozen=True)
    #: The suspended processes associated with the group.
    SuspendedProcesses: List["SuspendedProcess"] = Field(default=None, frozen=True)
    #: The name of the placement group into which to launch your instances, if any.
    PlacementGroup: Optional[str] = None
    #: One or more subnet IDs, if applicable, separated by commas.
    VPCZoneIdentifier: Optional[str] = None
    #: The metrics enabled for the group.
    EnabledMetrics: List["EnabledMetric"] = Field(default=None, frozen=True)
    #: The current state of the group when the DeleteAutoScalingGroup operation is in
    #: progress.
    Status: str = Field(default=None, frozen=True)
    #: The tags for the group.
    Tags: Optional[List["TagDescription"]] = None
    #: The termination policies for the group.
    TerminationPolicies: Optional[List[str]] = None
    #: Indicates whether newly launched instances are protected from termination by
    #: Amazon EC2 Auto Scaling when scaling in.
    NewInstancesProtectedFromScaleIn: Optional[bool] = None
    #: The Amazon Resource Name (ARN) of the service-linked role that the Auto Scaling
    #: group uses to call other Amazon Web Services on your behalf.
    ServiceLinkedRoleARN: Optional[str] = None
    #: The maximum amount of time, in seconds, that an instance can be in service.
    MaxInstanceLifetime: Optional[int] = None
    #: Indicates whether Capacity Rebalancing is enabled.
    CapacityRebalance: Optional[bool] = None
    #: The warm pool for the group.
    WarmPoolConfiguration: AutoScalingWarmPoolConfiguration = Field(
        default=None, frozen=True
    )
    #: The current size of the warm pool.
    WarmPoolSize: int = Field(default=None, frozen=True)
    #: Reserved.
    Context: Optional[str] = None
    #: The unit of measurement for the value specified for desired capacity. Amazon
    #: EC2 Auto Scaling supports ``DesiredCapacityType`` for attribute-based instance
    #: type selection only.
    DesiredCapacityType: Optional[str] = None
    #: The duration of the default instance warmup, in seconds.
    DefaultInstanceWarmup: Optional[int] = None
    #: The traffic sources associated with this Auto Scaling group.
    TrafficSources: Optional[List["TrafficSourceIdentifier"]] = None
    #: An instance maintenance policy.
    InstanceMaintenancePolicy: Optional[AutoScalingInstanceMaintenancePolicy] = None

    @property
    def pk(self) -> Optional[str]:
        """
        Return the primary key of the model.   This is the value of the
        :py:attr:`AutoScalingGroupName` attribute.

        Returns:
            The primary key of the model instance.
        """
        return self.AutoScalingGroupName

    @property
    def arn(self) -> Optional[str]:
        """
        Return the ARN of the model.   This is the value of the
        :py:attr:`AutoScalingGroupARN` attribute.

        Returns:
            The ARN of the model instance.
        """
        return self.AutoScalingGroupARN

    @property
    def name(self) -> Optional[str]:
        """
        Return the name of the model.   This is the value of the
        :py:attr:`AutoScalingGroupName` attribute.

        Returns:
            The name of the model instance.
        """
        return self.AutoScalingGroupName

    @cached_property
    def launch_configuration(self) -> Optional["LaunchConfiguration"]:
        """
        Return the :py:class:`LaunchConfiguration` object that this group uses,
        if any.
        """

        try:
            pk = OrderedDict(
                {
                    "launchConfigurationName": self.LaunchConfigurationName,
                }
            )
        except AttributeError:
            return None
        return LaunchConfiguration.objects.get(**pk)

    @cached_property
    def launch_template(self) -> Optional["LaunchTemplateVersion"]:
        """
        Return the :py:class:`LaunchTemplate` object that this group uses, if
        any.
        """

        try:
            pk = OrderedDict(
                {
                    "LaunchTemplateId": self.LaunchTemplate.LaunchTemplateId,
                    "Version": self.LaunchTemplate.Version,
                }
            )
        except AttributeError:
            return None
        return LaunchTemplateVersion.objects.get(**pk)


class EbsMapping(Boto3Model):
    """
    Information to attach an EBS volume to an instance at launch.
    """

    #: The snapshot ID of the volume to use.
    SnapshotId: Optional[str] = None
    #: The volume size, in GiBs. The following are the supported volumes sizes for
    #: each volume type:
    VolumeSize: Optional[int] = None
    #: The volume type. For more information, see `Amazon EBS volume types
    #: <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html>`_ in
    #: the *Amazon EC2 User Guide for Linux Instances*.
    VolumeType: Optional[str] = None
    #: Indicates whether the volume is deleted on instance termination. For Amazon EC2
    #: Auto Scaling, the default value is ``true``.
    DeleteOnTermination: Optional[bool] = None
    #: The number of input/output (I/O) operations per second (IOPS) to provision for
    #: the volume. For ``gp3`` and ``io1`` volumes, this represents the number of IOPS
    #: that are provisioned for the volume. For ``gp2`` volumes, this represents the
    #: baseline performance of the volume and the rate at which the volume accumulates
    #: I/O credits for bursting.
    Iops: Optional[int] = None
    #: Specifies whether the volume should be encrypted. Encrypted EBS volumes can
    #: only be attached to instances that support Amazon EBS encryption. For more
    #: information, see `Supported instance types <https://docs.aws.amazon.com/AWSEC2/
    #: latest/UserGuide/EBSEncryption.html#EBSEncryption_supported_instances>`_. If
    #: your AMI uses encrypted volumes, you can also only launch it on supported
    #: instance types.
    Encrypted: Optional[bool] = None
    #: The throughput (MiBps) to provision for a ``gp3`` volume.
    Throughput: Optional[int] = None


class AutoScalingBlockDeviceMapping(Boto3Model):
    """
    Describes a block device mapping.
    """

    #: The name of the instance store volume (virtual device) to attach to an instance
    #: at launch. The name must be in the form ephemeral*X* where *X* is a number
    #: starting from zero (0), for example, ``ephemeral0``.
    VirtualName: Optional[str] = None
    #: The device name assigned to the volume (for example, ``/dev/sdh`` or ``xvdh``).
    #: For more information, see `Device naming on Linux instances <https://docs.aws.a
    #: mazon.com/AWSEC2/latest/UserGuide/device_naming.html>`_ in the *Amazon EC2 User
    #: Guide for Linux Instances*.
    DeviceName: str
    #: Information to attach an EBS volume to an instance at launch.
    Ebs: Optional[EbsMapping] = None
    #: Setting this value to ``true`` prevents a volume that is included in the block
    #: device mapping of the AMI from being mapped to the specified device name at
    #: launch.
    NoDevice: Optional[bool] = None


class AutoScalingInstanceMonitoring(Boto3Model):
    """
    Controls whether instances in this group are launched with detailed
    (``true``) or basic (``false``) monitoring.

    For more information, see
    `Configure Monitoring for Auto Scaling Instances <https://docs.aws.amazon.com/autoscaling/latest/userguide/enable-as-
    instance-metrics.html>`_ in the *Amazon EC2 Auto Scaling User Guide*.
    """

    #: If ``true``, detailed monitoring is enabled. Otherwise, basic monitoring is
    #: enabled.
    Enabled: Optional[bool] = None


class InstanceMetadataOptions(Boto3Model):
    """
    The metadata options for the instances.

    For more information, see
    `Configuring the Instance Metadata Options <https://docs.aws.amazon.com/autoscaling/ec2/userguide/create-launch-
    config.html#launch-configurations-imds>`_ in the *Amazon EC2 Auto Scaling User
    Guide*.
    """

    #: The state of token usage for your instance metadata requests. If the parameter
    #: is not specified in the request, the default state is ``optional``.
    HttpTokens: Optional[Literal["optional", "required"]] = None
    #: The desired HTTP PUT response hop limit for instance metadata requests. The
    #: larger the number, the further instance metadata requests can travel.
    HttpPutResponseHopLimit: Optional[int] = None
    #: This parameter enables or disables the HTTP metadata endpoint on your
    #: instances. If the parameter is not specified, the default state is ``enabled``.
    HttpEndpoint: Optional[Literal["disabled", "enabled"]] = None


class LaunchConfiguration(PrimaryBoto3Model):
    """
    Describes a launch configuration.
    """

    objects: ClassVar[Boto3ModelManager] = LaunchConfigurationManager()

    #: The name of the launch configuration.
    LaunchConfigurationName: str
    #: The Amazon Resource Name (ARN) of the launch configuration.
    LaunchConfigurationARN: str = Field(default=None, frozen=True)
    #: The ID of the Amazon Machine Image (AMI) to use to launch your EC2 instances.
    #: For more information, see `Find a Linux AMI
    #: <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html>`_ in
    #: the *Amazon EC2 User Guide for Linux Instances*.
    ImageId: str
    #: The name of the key pair.
    KeyName: Optional[str] = None
    #: A list that contains the security groups to assign to the instances in the Auto
    #: Scaling group. For more information, see `Security Groups for Your VPC <https:/
    #: /docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_SecurityGroups.html>`_ in
    #: the *Amazon Virtual Private Cloud User Guide*.
    SecurityGroups: Optional[List[str]] = None
    #: Available for backward compatibility.
    ClassicLinkVPCId: Optional[str] = None
    #: Available for backward compatibility.
    ClassicLinkVPCSecurityGroups: Optional[List[str]] = None
    #: The user data to make available to the launched EC2 instances. For more
    #: information, see `Instance metadata and user data
    #: <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-
    #: metadata.html>`_ (Linux) and `Instance metadata and user data
    #: <https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-instance-
    #: metadata.html>`_ (Windows). If you are using a command line tool,
    #: base64-encoding is performed for you, and you can load the text from a file.
    #: Otherwise, you must provide base64-encoded text. User data is limited to 16 KB.
    UserData: Optional[str] = None
    #: The instance type for the instances. For information about available instance
    #: types, see `Available instance types
    #: <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-
    #: types.html#AvailableInstanceTypes>`_ in the *Amazon EC2 User Guide for Linux
    #: Instances*.
    InstanceType: str
    #: The ID of the kernel associated with the AMI.
    KernelId: Optional[str] = None
    #: The ID of the RAM disk associated with the AMI.
    RamdiskId: Optional[str] = None
    #: The block device mapping entries that define the block devices to attach to the
    #: instances at launch. By default, the block devices specified in the block
    #: device mapping for the AMI are used. For more information, see `Block Device
    #: Mapping <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-
    #: mapping-concepts.html>`_ in the *Amazon EC2 User Guide for Linux Instances*.
    BlockDeviceMappings: Optional[List["AutoScalingBlockDeviceMapping"]] = None
    #: Controls whether instances in this group are launched with detailed (``true``)
    #: or basic (``false``) monitoring.
    InstanceMonitoring: Optional[AutoScalingInstanceMonitoring] = None
    #: The maximum hourly price to be paid for any Spot Instance launched to fulfill
    #: the request. Spot Instances are launched when the price you specify exceeds the
    #: current Spot price. For more information, see `Requesting Spot Instances
    #: <https://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-launch- spot-
    #: instances.html>`_ in the *Amazon EC2 Auto Scaling User Guide*.
    SpotPrice: Optional[str] = None
    #: The name or the Amazon Resource Name (ARN) of the instance profile associated
    #: with the IAM role for the instance. The instance profile contains the IAM role.
    #: For more information, see `IAM role for applications that run on Amazon EC2
    #: instances <https://docs.aws.amazon.com/autoscaling/ec2/userguide/us-iam-
    #: role.html>`_ in the *Amazon EC2 Auto Scaling User Guide*.
    IamInstanceProfile: Optional[str] = None
    #: The creation date and time for the launch configuration.
    CreatedTime: datetime = Field(frozen=True)
    #: Specifies whether the launch configuration is optimized for EBS I/O (``true``)
    #: or not (``false``). For more information, see `Amazon EBS-Optimized Instances <
    #: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSOptimized.html>`_ in the
    #: *Amazon EC2 User Guide for Linux Instances*.
    EbsOptimized: Optional[bool] = None
    #: Specifies whether to assign a public IPv4 address to the group's instances. If
    #: the instance is launched into a default subnet, the default is to assign a
    #: public IPv4 address, unless you disabled the option to assign a public IPv4
    #: address on the subnet. If the instance is launched into a nondefault subnet,
    #: the default is not to assign a public IPv4 address, unless you enabled the
    #: option to assign a public IPv4 address on the subnet. For more information, see
    #: `Launching Auto Scaling instances in a VPC
    #: <https://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-in-vpc.html>`_ in
    #: the *Amazon EC2 Auto Scaling User Guide*.
    AssociatePublicIpAddress: Optional[bool] = None
    #: The tenancy of the instance, either ``default`` or ``dedicated``. An instance
    #: with ``dedicated`` tenancy runs on isolated, single-tenant hardware and can
    #: only be launched into a VPC.
    PlacementTenancy: Optional[str] = None
    #: The metadata options for the instances. For more information, see `Configuring
    #: the Instance Metadata Options
    #: <https://docs.aws.amazon.com/autoscaling/ec2/userguide/create-launch-
    #: config.html#launch-configurations-imds>`_ in the *Amazon EC2 Auto Scaling User
    #: Guide*.
    MetadataOptions: Optional[InstanceMetadataOptions] = None

    @property
    def pk(self) -> Optional[str]:
        """
        Return the primary key of the model.   This is the value of the
        :py:attr:`LaunchConfigurationName` attribute.

        Returns:
            The primary key of the model instance.
        """
        return self.LaunchConfigurationName

    @property
    def arn(self) -> Optional[str]:
        """
        Return the ARN of the model.   This is the value of the
        :py:attr:`LaunchConfigurationARN` attribute.

        Returns:
            The ARN of the model instance.
        """
        return self.LaunchConfigurationARN

    @property
    def name(self) -> Optional[str]:
        """
        Return the name of the model.   This is the value of the
        :py:attr:`LaunchConfigurationName` attribute.

        Returns:
            The name of the model instance.
        """
        return self.LaunchConfigurationName


# =======================
# Request/Response Models
# =======================


class LifecycleHookSpecification(Boto3Model):
    """
    Describes information used to specify a lifecycle hook for an Auto Scaling
    group.

    For more information, see
    `Amazon EC2 Auto Scaling lifecycle hooks <https://docs.aws.amazon.com/autoscaling/ec2/userguide/lifecycle-
    hooks.html>`_ in the *Amazon EC2 Auto Scaling User Guide*.
    """

    #: The name of the lifecycle hook.
    LifecycleHookName: str
    #: The lifecycle transition. For Auto Scaling groups, there are two major
    #: lifecycle transitions.
    LifecycleTransition: str
    #: Additional information that you want to include any time Amazon EC2 Auto
    #: Scaling sends a message to the notification target.
    NotificationMetadata: Optional[str] = None
    #: The maximum time, in seconds, that can elapse before the lifecycle hook times
    #: out. The range is from ``30`` to ``7200`` seconds. The default value is
    #: ``3600`` seconds (1 hour).
    HeartbeatTimeout: Optional[int] = None
    #: The action the Auto Scaling group takes when the lifecycle hook timeout elapses
    #: or if an unexpected failure occurs. The default value is ``ABANDON``.
    DefaultResult: Optional[str] = None
    #: The Amazon Resource Name (ARN) of the notification target that Amazon EC2 Auto
    #: Scaling sends notifications to when an instance is in a wait state for the
    #: lifecycle hook. You can specify an Amazon SNS topic or an Amazon SQS queue.
    NotificationTargetARN: Optional[str] = None
    #: The ARN of the IAM role that allows the Auto Scaling group to publish to the
    #: specified notification target. For information about creating this role, see
    #: `Configure a notification target for a lifecycle hook
    #: <https://docs.aws.amazon.com/autoscaling/ec2/userguide/prepare-for- lifecycle-
    #: notifications.html#lifecycle-hook-notification-target>`_ in the *Amazon EC2
    #: Auto Scaling User Guide*.
    RoleARN: Optional[str] = None


class AutoScalingGroupsType(Boto3Model):
    #: The groups.
    AutoScalingGroups: List["AutoScalingGroup"]
    #: A string that indicates that the response contains more items than can be
    #: returned in a single response. To receive additional items, specify this string
    #: for the ``NextToken`` value when requesting the next set of items. This value
    #: is null when there are no more items to return.
    NextToken: Optional[str] = None


class LaunchConfigurationsType(Boto3Model):
    #: The launch configurations.
    LaunchConfigurations: List["LaunchConfiguration"]
    #: A string that indicates that the response contains more items than can be
    #: returned in a single response. To receive additional items, specify this string
    #: for the ``NextToken`` value when requesting the next set of items. This value
    #: is null when there are no more items to return.
    NextToken: Optional[str] = None
