import * as iam from "../../aws-iam";
import { Duration, IResource, Resource } from "../../core";
import { Construct } from 'constructs';
import { CloudFormationInit } from './cfn-init';
import { Connections, IConnectable } from './connections';
import { CfnInstance } from './ec2.generated';
import { InstanceType } from './instance-types';
import { IMachineImage, OperatingSystemType } from './machine-image';
import { ISecurityGroup } from './security-group';
import { UserData } from './user-data';
import { BlockDevice } from './volume';
import { IVpc, SubnetSelection } from './vpc';
/**
 * @experimental
 */
export interface IInstance extends IResource, IConnectable, iam.IGrantable {
    /**
     * (experimental) The instance's ID.
     *
     * @experimental
     * @attribute true
     */
    readonly instanceId: string;
    /**
     * (experimental) The availability zone the instance was launched in.
     *
     * @experimental
     * @attribute true
     */
    readonly instanceAvailabilityZone: string;
    /**
     * (experimental) Private DNS name for this instance.
     *
     * @experimental
     * @attribute true
     */
    readonly instancePrivateDnsName: string;
    /**
     * (experimental) Private IP for this instance.
     *
     * @experimental
     * @attribute true
     */
    readonly instancePrivateIp: string;
    /**
     * (experimental) Publicly-routable DNS name for this instance.
     *
     * (May be an empty string if the instance does not have a public name).
     *
     * @experimental
     * @attribute true
     */
    readonly instancePublicDnsName: string;
    /**
     * (experimental) Publicly-routable IP  address for this instance.
     *
     * (May be an empty string if the instance does not have a public IP).
     *
     * @experimental
     * @attribute true
     */
    readonly instancePublicIp: string;
}
/**
 * (experimental) Properties of an EC2 Instance.
 *
 * @experimental
 */
export interface InstanceProps {
    /**
     * (experimental) Name of SSH keypair to grant access to instance.
     *
     * @default - No SSH access will be possible.
     * @experimental
     */
    readonly keyName?: string;
    /**
     * (experimental) Where to place the instance within the VPC.
     *
     * @default - Private subnets.
     * @experimental
     */
    readonly vpcSubnets?: SubnetSelection;
    /**
     * (experimental) In which AZ to place the instance within the VPC.
     *
     * @default - Random zone.
     * @experimental
     */
    readonly availabilityZone?: string;
    /**
     * (experimental) 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
     * @experimental
     */
    readonly allowAllOutbound?: boolean;
    /**
     * (experimental) The length of time to wait for the resourceSignalCount.
     *
     * The maximum value is 43200 (12 hours).
     *
     * @default Duration.minutes(5)
     * @experimental
     */
    readonly resourceSignalTimeout?: Duration;
    /**
     * (experimental) VPC to launch the instance in.
     *
     * @experimental
     */
    readonly vpc: IVpc;
    /**
     * (experimental) Security Group to assign to this instance.
     *
     * @default - create new security group
     * @experimental
     */
    readonly securityGroup?: ISecurityGroup;
    /**
     * (experimental) Type of instance to launch.
     *
     * @experimental
     */
    readonly instanceType: InstanceType;
    /**
     * (experimental) AMI to launch.
     *
     * @experimental
     */
    readonly machineImage: IMachineImage;
    /**
     * (experimental) 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.
     * @experimental
     */
    readonly userData?: UserData;
    /**
     * (experimental) 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.
     * @experimental
     */
    readonly userDataCausesReplacement?: boolean;
    /**
     * (experimental) 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
     * @experimental
     * @example
     *
     * const role = new iam.Role(this, 'MyRole', {
     *   assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com')
     * });
     */
    readonly role?: iam.IRole;
    /**
     * (experimental) The name of the instance.
     *
     * @default - CDK generated name
     * @experimental
     */
    readonly instanceName?: string;
    /**
     * (experimental) 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
     * @experimental
     */
    readonly sourceDestCheck?: boolean;
    /**
     * (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
     * @experimental
     */
    readonly blockDevices?: BlockDevice[];
    /**
     * (experimental) 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
     * @experimental
     */
    readonly privateIpAddress?: string;
    /**
     * (experimental) Apply the given CloudFormation Init configuration to the instance at startup.
     *
     * @default - no CloudFormation init
     * @experimental
     */
    readonly init?: CloudFormationInit;
    /**
     * (experimental) Use the given options for applying CloudFormation Init.
     *
     * Describes the configsets to use and the timeout to wait
     *
     * @default - default options
     * @experimental
     */
    readonly initOptions?: ApplyCloudFormationInitOptions;
}
/**
 * (experimental) This represents a single EC2 instance.
 *
 * @experimental
 */
export declare class Instance extends Resource implements IInstance {
    /**
     * (experimental) The type of OS the instance is running.
     *
     * @experimental
     */
    readonly osType: OperatingSystemType;
    /**
     * (experimental) Allows specify security group connections for the instance.
     *
     * @experimental
     */
    readonly connections: Connections;
    /**
     * (experimental) The IAM role assumed by the instance.
     *
     * @experimental
     */
    readonly role: iam.IRole;
    /**
     * (experimental) The principal to grant permissions to.
     *
     * @experimental
     */
    readonly grantPrincipal: iam.IPrincipal;
    /**
     * (experimental) UserData for the instance.
     *
     * @experimental
     */
    readonly userData: UserData;
    /**
     * (experimental) the underlying instance resource.
     *
     * @experimental
     */
    readonly instance: CfnInstance;
    /**
     * (experimental) The instance's ID.
     *
     * @experimental
     * @attribute true
     */
    readonly instanceId: string;
    /**
     * (experimental) The availability zone the instance was launched in.
     *
     * @experimental
     * @attribute true
     */
    readonly instanceAvailabilityZone: string;
    /**
     * (experimental) Private DNS name for this instance.
     *
     * @experimental
     * @attribute true
     */
    readonly instancePrivateDnsName: string;
    /**
     * (experimental) Private IP for this instance.
     *
     * @experimental
     * @attribute true
     */
    readonly instancePrivateIp: string;
    /**
     * (experimental) Publicly-routable DNS name for this instance.
     *
     * (May be an empty string if the instance does not have a public name).
     *
     * @experimental
     * @attribute true
     */
    readonly instancePublicDnsName: string;
    /**
     * (experimental) Publicly-routable IP  address for this instance.
     *
     * (May be an empty string if the instance does not have a public IP).
     *
     * @experimental
     * @attribute true
     */
    readonly instancePublicIp: string;
    private readonly securityGroup;
    private readonly securityGroups;
    /**
     * @experimental
     */
    constructor(scope: Construct, id: string, props: InstanceProps);
    /**
     * (experimental) Add the security group to the instance.
     *
     * @param securityGroup : The security group to add.
     * @experimental
     */
    addSecurityGroup(securityGroup: ISecurityGroup): void;
    /**
     * (experimental) 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).
     *
     * @experimental
     */
    addUserData(...commands: string[]): void;
    /**
     * (experimental) Adds a statement to the IAM role assumed by the instance.
     *
     * @experimental
     */
    addToRolePolicy(statement: iam.PolicyStatement): void;
    /**
     * Use a CloudFormation Init configuration at instance startup
     *
     * This does the following:
     *
     * - Attaches the CloudFormation Init metadata to the Instance resource.
     * - Add commands to the instance UserData to run `cfn-init` and `cfn-signal`.
     * - Update the instance's CreationPolicy to wait for the `cfn-signal` commands.
     */
    private applyCloudFormationInit;
    /**
     * Wait for a single additional resource signal
     *
     * Add 1 to the current ResourceSignal Count and add the given timeout to the current timeout.
     *
     * Use this to pause the CloudFormation deployment to wait for the instances
     * in the AutoScalingGroup to report successful startup during
     * creation and updates. The UserData script needs to invoke `cfn-signal`
     * with a success or failure code after it is done setting up the instance.
     */
    private waitForResourceSignal;
    /**
     * Apply CloudFormation update policies for the instance
     */
    private applyUpdatePolicies;
}
/**
 * (experimental) Options for applying CloudFormation init to an instance or instance group.
 *
 * @experimental
 */
export interface ApplyCloudFormationInitOptions {
    /**
     * (experimental) ConfigSet to activate.
     *
     * @default ['default']
     * @experimental
     */
    readonly configSets?: string[];
    /**
     * (experimental) Timeout waiting for the configuration to be applied.
     *
     * @default Duration.minutes(5)
     * @experimental
     */
    readonly timeout?: Duration;
    /**
     * (experimental) 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
     * @experimental
     */
    readonly embedFingerprint?: boolean;
    /**
     * (experimental) 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
     * @experimental
     */
    readonly printLog?: boolean;
    /**
     * (experimental) 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
     * @experimental
     */
    readonly ignoreFailures?: boolean;
}
