

O AWS SDK para .NET V3 entrou no modo de manutenção.

Recomendamos que você migre para a [AWS SDK para .NET V4](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/welcome.html). Para obter detalhes e informações adicionais sobre como migrar, consulte nosso [anúncio do modo de manutenção](https://aws.amazon.com/blogs/developer/aws-sdk-for-net-v3-maintenance-mode-announcement/).

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Trabalhar com o Amazon EC2
<a name="ec2-apis-intro"></a>

O AWS SDK para .NET suporta o [Amazon EC2](https://docs.aws.amazon.com/ec2/), que é um serviço web que fornece capacidade de computação redimensionável. Você usa essa capacidade de computação para criar e hospedar seus sistemas de software.

## APIs
<a name="w2aac19c15c17b5"></a>

 AWS SDK para .NET Ele fornece APIs para clientes do Amazon EC2. As APIs permitem que você trabalhe com recursos do EC2, como grupos de segurança e pares de chaves. As APIs também permitem que você controle as instâncias do Amazon EC2. Esta seção contém um pequeno número de exemplos que mostram os padrões que você pode seguir ao trabalhar com eles APIs. Para ver o conjunto completo de APIs, consulte a [Referência da AWS SDK para .NET API](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/) (e vá até “Amazon.ec2").

O Amazon EC2 APIs é fornecido pelo [AWSSDK NuGet pacote.EC2](https://www.nuget.org/packages/AWSSDK.EC2).

## Pré-requisitos
<a name="w2aac19c15c17b7"></a>

Antes de começar, assegure-se de ter [configurado o seu ambiente e seu projeto](net-dg-config.md). Revise também as informações em [Atributos do SDK](net-dg-sdk-features.md).

## Sobre os exemplos
<a name="ec2-apis-intro-about"></a>

Os exemplos nesta seção mostram como trabalhar com clientes do Amazon EC2 e como gerenciar as instâncias do Amazon EC2.

Os [tutoriais de instâncias spot do EC2](how-to-spot-instances.md) mostram como solicitar instâncias spot do Amazon EC2. As instâncias spot permitem que você acesse a capacidade do EC2 não utilizada por um valor mais baixo que o preço sob demanda.

**Topics**
+ [APIs](#w2aac19c15c17b5)
+ [Pré-requisitos](#w2aac19c15c17b7)
+ [Sobre os exemplos](#ec2-apis-intro-about)
+ [Grupos de segurança](security-groups.md)
+ [Pares de chaves](key-pairs.md)
+ [Regiões e zonas de disponibilidade](using-regions-and-availability-zones.md)
+ [Instâncias do EC2](how-to-ec2.md)
+ [Tutorial: instância spot](how-to-spot-instances.md)

# Como trabalhar com grupos de segurança no Amazon EC2
<a name="security-groups"></a>

No Amazon EC2, um *grupo de segurança* atua como um firewall virtual que controla o tráfego de rede para uma ou mais instâncias do EC2. Por padrão, o EC2 associa as instâncias a um grupo de segurança que não permite tráfego de entrada. Você pode criar um security group que permita que as instâncias do EC2 aceitem um determinado tráfego. Por exemplo, se você precisar se conectar a uma instância do EC2 em Windows, deverá configurar o security group para permitir tráfego RDP.

Para ler mais sobre grupos de segurança, consulte [Grupos de segurança do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html) no [Guia de usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).

**Atenção**  
O EC2-Classic foi removido em 15 de agosto de 2022. É recomendável migrar do EC2-Classic para uma VPC. Para obter mais informações, consulte a postagem do blog [EC2-Classic Networking is Retiring – Here's How to Prepare](https://aws.amazon.com/blogs/aws/ec2-classic-is-retiring-heres-how-to-prepare/).

Para obter informações sobre os pré-requisitos APIs e, consulte a seção principal (). [Trabalhar com o Amazon EC2](ec2-apis-intro.md)

**Topics**
+ [Como enumerar grupos de segurança](enumerate-security-groups.md)
+ [Como criar grupos de segurança](creating-security-group.md)
+ [Como atualizar Grupos de Segurança](authorize-ingress.md)

# Como enumerar grupos de segurança
<a name="enumerate-security-groups"></a>

Este exemplo mostra como usar o AWS SDK para .NET para enumerar grupos de segurança. Se você fornecer um [Amazon Private Cloud](https://docs.aws.amazon.com/vpc/latest/userguide/) ID, o aplicativo enumera os grupos de segurança dessa VPC específica. Caso contrário, o aplicativo exibirá apenas uma lista de todos os grupos de segurança disponíveis.

As seções a seguir fornecem snippets desse exemplo. O [código completo do exemplo](#enum-sec-groups-complete-code) é mostrado depois e pode ser criado e executado como está.

**Topics**
+ [Como enumerar seus grupos de segurança](#enum-sec-groups-enum)
+ [Código completo](#enum-sec-groups-complete-code)
+ [Considerações adicionais](#enum-sec-groups-additional)

## Como enumerar seus grupos de segurança
<a name="enum-sec-groups-enum"></a>

O snippet a seguir enumera seus grupos de segurança. Ele enumera todos os grupos ou os grupos de uma VPC específica, se houver um.

O exemplo [no final deste tópico](#enum-sec-groups-complete-code) mostra o snippet em uso.

```
    //
    // Method to enumerate the security groups
    private static async Task EnumerateGroups(IAmazonEC2 ec2Client, string vpcID)
    {
      // A request object, in case we need it.
      var request = new DescribeSecurityGroupsRequest();

      // Put together the properties, if needed
      if(!string.IsNullOrEmpty(vpcID))
      {
        // We have a VPC ID. Find the security groups for just that VPC.
        Console.WriteLine($"\nGetting security groups for VPC {vpcID}...\n");
        request.Filters.Add(new Filter
        {
          Name = "vpc-id",
          Values = new List<string>() { vpcID }
        });
      }

      // Get the list of security groups
      DescribeSecurityGroupsResponse response =
        await ec2Client.DescribeSecurityGroupsAsync(request);

      // Display the list of security groups.
      foreach (SecurityGroup item in response.SecurityGroups)
      {
        Console.WriteLine("Security group: " + item.GroupId);
        Console.WriteLine("\tGroupId: " + item.GroupId);
        Console.WriteLine("\tGroupName: " + item.GroupName);
        Console.WriteLine("\tVpcId: " + item.VpcId);
        Console.WriteLine();
      }
    }
```

## Código completo
<a name="enum-sec-groups-complete-code"></a>

Esta seção mostra as referências relevantes e o código completo desse exemplo.

### Referências do SDK
<a name="w2aac19c15c17c13c13c15b5b1"></a>

NuGet pacotes:
+ [AWSSDK.EC2](https://www.nuget.org/packages/AWSSDK.EC2)

Elementos de programação:
+ Namespace [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2.html)

  Classe [Amazon EC2 Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TEC2Client.html)
+ Namespace [Amazon.EC2.model](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2Model.html)

  Classe [DescribeSecurityGroupsRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeSecurityGroupsRequest.html)

  Classe [DescribeSecurityGroupsResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeSecurityGroupsResponse.html)

  Classe [Filter](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TFilter.html)

  Classe [SecurityGroup](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TSecurityGroup.html)

### O Código
<a name="w2aac19c15c17c13c13c15b7b1"></a>

```
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Amazon.EC2;
using Amazon.EC2.Model;

namespace EC2EnumerateSecGroups
{
  class Program
  {
    static async Task Main(string[] args)
    {
      // Parse the command line
       string vpcID = string.Empty;
      if(args.Length == 0)
      {
        Console.WriteLine("\nEC2EnumerateSecGroups [vpc_id]");
        Console.WriteLine("  vpc_id - The ID of the VPC for which you want to see security groups.");
        Console.WriteLine("\nSince you specified no arguments, showing all available security groups.");
      }
      else
      {
        vpcID = args[0];
      }

      if(vpcID.StartsWith("vpc-") || string.IsNullOrEmpty(vpcID))
      {
        // Create an EC2 client object
        var ec2Client = new AmazonEC2Client();

        // Enumerate the security groups
        await EnumerateGroups(ec2Client, vpcID);
      }
      else
      {
        Console.WriteLine("Could not find a valid VPC ID in the command-line arguments:");
        Console.WriteLine($"{args[0]}");
      }
    }


    //
    // Method to enumerate the security groups
    private static async Task EnumerateGroups(IAmazonEC2 ec2Client, string vpcID)
    {
      // A request object, in case we need it.
      var request = new DescribeSecurityGroupsRequest();

      // Put together the properties, if needed
      if(!string.IsNullOrEmpty(vpcID))
      {
        // We have a VPC ID. Find the security groups for just that VPC.
        Console.WriteLine($"\nGetting security groups for VPC {vpcID}...\n");
        request.Filters.Add(new Filter
        {
          Name = "vpc-id",
          Values = new List<string>() { vpcID }
        });
      }

      // Get the list of security groups
      DescribeSecurityGroupsResponse response =
        await ec2Client.DescribeSecurityGroupsAsync(request);

      // Display the list of security groups.
      foreach (SecurityGroup item in response.SecurityGroups)
      {
        Console.WriteLine("Security group: " + item.GroupId);
        Console.WriteLine("\tGroupId: " + item.GroupId);
        Console.WriteLine("\tGroupName: " + item.GroupName);
        Console.WriteLine("\tVpcId: " + item.VpcId);
        Console.WriteLine();
      }
    }
  }
}
```

## Considerações adicionais
<a name="enum-sec-groups-additional"></a>
+ Observe que, no caso da VPC, o filtro é construído com a parte `Name` do par nome-valor definida como “vpc-id”. Esse nome vem da descrição da `Filters` propriedade da [DescribeSecurityGroupsRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeSecurityGroupsRequest.html)classe.
+ Para obter a lista completa dos seus grupos de segurança, você também pode usar [ DescribeSecurityGroupsAsync sem parâmetros](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/MEC2DescribeSecurityGroupsAsyncCancellationToken.html).
+ Você pode verificar os resultados consultando a lista de grupos de segurança no [console do Amazon EC2](https://console.aws.amazon.com/ec2/v2/home#SecurityGroups).

# Como criar grupos de segurança
<a name="creating-security-group"></a>

Este exemplo mostra como usar o AWS SDK para .NET para criar um grupo de segurança. Você pode fornecer o ID de uma VPC existente para criar um grupo de segurança para o EC2 em uma VPC. Se você não fornecer essa ID, o novo grupo de segurança será para o EC2-Classic se sua AWS conta suportar isso.

Se você não fornecer uma VPC ID e sua AWS conta não for compatível com o EC2-Classic, o novo grupo de segurança pertencerá à VPC padrão da sua conta.

**Atenção**  
O EC2-Classic foi removido em 15 de agosto de 2022. É recomendável migrar do EC2-Classic para uma VPC. Para acessar mais informações, consulte a postagem do blog [EC2-Classic Networking is Retiring - Here's How to Prepare](https://aws.amazon.com/blogs/aws/ec2-classic-is-retiring-heres-how-to-prepare/).

As seções a seguir fornecem snippets desse exemplo. O [código completo do exemplo](#create-sec-groups-complete-code) é mostrado depois e pode ser criado e executado como está.

**Topics**
+ [Como encontrar grupos de segurança existentes](#create-sec-groups-find)
+ [Criar um grupo de segurança](#create-sec-groups-enum)
+ [Código completo](#create-sec-groups-complete-code)

## Como encontrar grupos de segurança existentes
<a name="create-sec-groups-find"></a>

O snippet a seguir pesquisa grupos de segurança existentes com o nome fornecido na VPC fornecida.

O exemplo [no final deste tópico](#create-sec-groups-complete-code) mostra o snippet em uso.

```
    //
    // Method to determine if a security group with the specified name
    // already exists in the VPC
    private static async Task<List<SecurityGroup>> FindSecurityGroups(
      IAmazonEC2 ec2Client, string groupName, string vpcID)
    {
      var request = new DescribeSecurityGroupsRequest();
      request.Filters.Add(new Filter{
        Name = "group-name",
        Values = new List<string>() { groupName }
      });
      if(!string.IsNullOrEmpty(vpcID))
        request.Filters.Add(new Filter{
          Name = "vpc-id",
          Values = new List<string>() { vpcID }
        });

      var response = await ec2Client.DescribeSecurityGroupsAsync(request);
      return response.SecurityGroups;
    }
```

## Criar um grupo de segurança
<a name="create-sec-groups-enum"></a>

O snippet a seguir cria um novo grupo de segurança se um grupo com esse nome não existir na VPC fornecida. Se nenhuma VPC for fornecida e existir um ou mais grupos com esse nome, o snippet apenas retornará a lista de grupos.

O exemplo [no final deste tópico](#create-sec-groups-complete-code) mostra o snippet em uso.

```
    //
    // Method to create a new security group (either EC2-Classic or EC2-VPC)
    // If vpcID is empty, the security group will be for EC2-Classic
    private static async Task<List<SecurityGroup>> CreateSecurityGroup(
      IAmazonEC2 ec2Client, string groupName, string vpcID)
    {
      // See if one or more security groups with that name
      // already exist in the given VPC. If so, return the list of them.
      var securityGroups = await FindSecurityGroups(ec2Client, groupName, vpcID);
      if (securityGroups.Count > 0)
      {
        Console.WriteLine(
          $"\nOne or more security groups with name {groupName} already exist.\n");
        return securityGroups;
      }

      // If the security group doesn't already exists, create it.
      var createRequest = new CreateSecurityGroupRequest{
        GroupName = groupName
      };
      if(string.IsNullOrEmpty(vpcID))
      {
        createRequest.Description = "My .NET example security group for EC2-Classic";
      }
      else
      {
        createRequest.VpcId = vpcID;
        createRequest.Description = "My .NET example security group for EC2-VPC";
      }
      CreateSecurityGroupResponse createResponse =
        await ec2Client.CreateSecurityGroupAsync(createRequest);

      // Return the new security group
      DescribeSecurityGroupsResponse describeResponse =
        await ec2Client.DescribeSecurityGroupsAsync(new DescribeSecurityGroupsRequest{
          GroupIds = new List<string>() { createResponse.GroupId }
        });
      return describeResponse.SecurityGroups;
    }
```

## Código completo
<a name="create-sec-groups-complete-code"></a>

Esta seção mostra as referências relevantes e o código completo desse exemplo.

### Referências do SDK
<a name="w2aac19c15c17c13c15c23b5b1"></a>

NuGet pacotes:
+ [AWSSDK.EC2](https://www.nuget.org/packages/AWSSDK.EC2)

Elementos de programação:
+ Namespace [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2.html)

  Classe [Amazon EC2 Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TEC2Client.html)
+ Namespace [Amazon.EC2.model](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2Model.html)

  Classe [CreateSecurityGroupRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TCreateSecurityGroupRequest.html)

  Classe [CreateSecurityGroupResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TCreateSecurityGroupResponse.html)

  Classe [DescribeSecurityGroupsRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeSecurityGroupsRequest.html)

  Classe [DescribeSecurityGroupsResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeSecurityGroupsResponse.html)

  Classe [Filter ](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TFilter.html)

  Classe [SecurityGroup](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TSecurityGroup.html)

### O código
<a name="w2aac19c15c17c13c15c23b7b1"></a>

```
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Amazon.EC2;
using Amazon.EC2.Model;

namespace EC2CreateSecGroup
{
  // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  // Class to create a security group
  class Program
  {
    private const int MaxArgs = 2;

    static async Task Main(string[] args)
    {
      // Parse the command line and show help if necessary
      var parsedArgs = CommandLine.Parse(args);
      if(parsedArgs.Count == 0)
      {
        PrintHelp();
        return;
      }
      if(parsedArgs.Count > MaxArgs)
        CommandLine.ErrorExit("\nThe number of command-line arguments is incorrect." +
          "\nRun the command with no arguments to see help.");

      // Get the application arguments from the parsed list
      var groupName = CommandLine.GetArgument(parsedArgs, null, "-g", "--group-name");
      var vpcID = CommandLine.GetArgument(parsedArgs, null, "-v", "--vpc-id");
      if(string.IsNullOrEmpty(groupName))
        CommandLine.ErrorExit("\nYou must supply a name for the new group." +
          "\nRun the command with no arguments to see help.");
      if(!string.IsNullOrEmpty(vpcID) && !vpcID.StartsWith("vpc-"))
        CommandLine.ErrorExit($"\nNot a valid VPC ID: {vpcID}");

      // groupName has a value and vpcID either has a value or is null (which is fine)
      // Create the new security group and display information about it
      var securityGroups =
        await CreateSecurityGroup(new AmazonEC2Client(), groupName, vpcID);
      Console.WriteLine("Information about the security group(s):");
      foreach(var group in securityGroups)
      {
        Console.WriteLine($"\nGroupName: {group.GroupName}");
        Console.WriteLine($"GroupId: {group.GroupId}");
        Console.WriteLine($"Description: {group.Description}");
        Console.WriteLine($"VpcId (if any): {group.VpcId}");
      }
    }


    //
    // Method to create a new security group (either EC2-Classic or EC2-VPC)
    // If vpcID is empty, the security group will be for EC2-Classic
    private static async Task<List<SecurityGroup>> CreateSecurityGroup(
      IAmazonEC2 ec2Client, string groupName, string vpcID)
    {
      // See if one or more security groups with that name
      // already exist in the given VPC. If so, return the list of them.
      var securityGroups = await FindSecurityGroups(ec2Client, groupName, vpcID);
      if (securityGroups.Count > 0)
      {
        Console.WriteLine(
          $"\nOne or more security groups with name {groupName} already exist.\n");
        return securityGroups;
      }

      // If the security group doesn't already exists, create it.
      var createRequest = new CreateSecurityGroupRequest{
        GroupName = groupName
      };
      if(string.IsNullOrEmpty(vpcID))
      {
        createRequest.Description = "Security group for .NET code example (no VPC specified)";
      }
      else
      {
        createRequest.VpcId = vpcID;
        createRequest.Description = "Security group for .NET code example (VPC: " + vpcID + ")";
      }
      CreateSecurityGroupResponse createResponse =
        await ec2Client.CreateSecurityGroupAsync(createRequest);

      // Return the new security group
      DescribeSecurityGroupsResponse describeResponse =
        await ec2Client.DescribeSecurityGroupsAsync(new DescribeSecurityGroupsRequest{
          GroupIds = new List<string>() { createResponse.GroupId }
        });
      return describeResponse.SecurityGroups;
    }


    //
    // Method to determine if a security group with the specified name
    // already exists in the VPC
    private static async Task<List<SecurityGroup>> FindSecurityGroups(
      IAmazonEC2 ec2Client, string groupName, string vpcID)
    {
      var request = new DescribeSecurityGroupsRequest();
      request.Filters.Add(new Filter{
        Name = "group-name",
        Values = new List<string>() { groupName }
      });
      if(!string.IsNullOrEmpty(vpcID))
        request.Filters.Add(new Filter{
          Name = "vpc-id",
          Values = new List<string>() { vpcID }
        });

      var response = await ec2Client.DescribeSecurityGroupsAsync(request);
      return response.SecurityGroups;
    }


    //
    // Command-line help
    private static void PrintHelp()
    {
      Console.WriteLine(
        "\nUsage: EC2CreateSecGroup -g <group-name> [-v <vpc-id>]" +
        "\n  -g, --group-name: The name you would like the new security group to have." +
        "\n  -v, --vpc-id: The ID of a VPC to which the new security group will belong." +
        "\n     If vpc-id isn't present, the security group will be" +
        "\n     for EC2-Classic (if your AWS account supports this)" +
        "\n     or will use the default VCP for EC2-VPC.");
    }
  }


  // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  // Class that represents a command line on the console or terminal.
  // (This is the same for all examples. When you have seen it once, you can ignore it.)
  static class CommandLine
  {
    //
    // Method to parse a command line of the form: "--key value" or "-k value".
    //
    // Parameters:
    // - args: The command-line arguments passed into the application by the system.
    //
    // Returns:
    // A Dictionary with string Keys and Values.
    //
    // If a key is found without a matching value, Dictionary.Value is set to the key
    //  (including the dashes).
    // If a value is found without a matching key, Dictionary.Key is set to "--NoKeyN",
    //  where "N" represents sequential numbers.
    public static Dictionary<string,string> Parse(string[] args)
    {
      var parsedArgs = new Dictionary<string,string>();
      int i = 0, n = 0;
      while(i < args.Length)
      {
        // If the first argument in this iteration starts with a dash it's an option.
        if(args[i].StartsWith("-"))
        {
          var key = args[i++];
          var value = key;

          // Check to see if there's a value that goes with this option?
          if((i < args.Length) && (!args[i].StartsWith("-"))) value = args[i++];
          parsedArgs.Add(key, value);
        }

        // If the first argument in this iteration doesn't start with a dash, it's a value
        else
        {
          parsedArgs.Add("--NoKey" + n.ToString(), args[i++]);
          n++;
        }
      }

      return parsedArgs;
    }

    //
    // Method to get an argument from the parsed command-line arguments
    //
    // Parameters:
    // - parsedArgs: The Dictionary object returned from the Parse() method (shown above).
    // - defaultValue: The default string to return if the specified key isn't in parsedArgs.
    // - keys: An array of keys to look for in parsedArgs.
    public static string GetArgument(
      Dictionary<string,string> parsedArgs, string defaultReturn, params string[] keys)
    {
      string retval = null;
      foreach(var key in keys)
        if(parsedArgs.TryGetValue(key, out retval)) break;
      return retval ?? defaultReturn;
    }

    //
    // Method to exit the application with an error.
    public static void ErrorExit(string msg, int code=1)
    {
      Console.WriteLine("\nError");
      Console.WriteLine(msg);
      Environment.Exit(code);
    }
  }

}
```

# Como atualizar Grupos de Segurança
<a name="authorize-ingress"></a>

Este exemplo mostra como usar o AWS SDK para .NET para adicionar uma regra a um grupo de segurança. Em particular, o exemplo adiciona uma regra para permitir tráfego de entrada em uma determinada porta TCP, que pode ser usada, por exemplo, para conexões remotas com uma instância do EC2. O aplicativo usa a ID de um grupo de segurança existente, um endereço IP (ou intervalo de endereços) no formato CIDR e, opcionalmente, um número de porta TCP. Em seguida, ele adiciona uma regra de entrada ao grupo de segurança fornecido.

**nota**  
Para usar esse exemplo, você precisa de um endereço IP (ou intervalo de endereços) no formato CIDR. Consulte **Considerações adicionais** no final deste tópico para obter o endereço IP do seu computador local.

As seções a seguir fornecem snippets desse exemplo. O [código completo do exemplo](#authorize-ingress-complete-code) é mostrado depois e pode ser criado e executado como está.

**Topics**
+ [Como adicionar uma regra de entrada](#authorize-ingress-add-rule)
+ [Código completo](#authorize-ingress-complete-code)
+ [Considerações adicionais](#authorize-ingress-additional)

## Como adicionar uma regra de entrada
<a name="authorize-ingress-add-rule"></a>

O trecho a seguir adiciona uma regra de entrada a um grupo de segurança para um determinado endereço IP (ou intervalo) e porta TCP.

O exemplo [no final deste tópico](#authorize-ingress-complete-code) mostra o snippet em uso.

```
    //
    // Method that adds a TCP ingress rule to a security group
    private static async Task AddIngressRule(
      IAmazonEC2 eC2Client, string groupID, string ipAddress, int port)
    {
      // Create an object to hold the request information for the rule.
      // It uses an IpPermission object to hold the IP information for the rule.
      var ingressRequest = new AuthorizeSecurityGroupIngressRequest{
        GroupId = groupID};
      ingressRequest.IpPermissions.Add(new IpPermission{
        IpProtocol = "tcp",
        FromPort = port,
        ToPort = port,
        Ipv4Ranges = new List<IpRange>() { new IpRange { CidrIp = ipAddress } }
      });

      // Create the inbound rule for the security group
      AuthorizeSecurityGroupIngressResponse responseIngress =
        await eC2Client.AuthorizeSecurityGroupIngressAsync(ingressRequest);
      Console.WriteLine($"\nNew RDP rule was written in {groupID} for {ipAddress}.");
      Console.WriteLine($"Result: {responseIngress.HttpStatusCode}");
    }
```

## Código completo
<a name="authorize-ingress-complete-code"></a>

Esta seção mostra as referências relevantes e o código completo desse exemplo.

### Referências do SDK
<a name="w2aac19c15c17c13c17c17b5b1"></a>

NuGet pacotes:
+ [AWSSDK.EC2](https://www.nuget.org/packages/AWSSDK.EC2)

Elementos de programação:
+ Namespace [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2.html)

  Classe [Amazon EC2 Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TEC2Client.html)
+ Namespace [Amazon.EC2.model](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2Model.html)

  Classe [AuthorizeSecurityGroupIngressRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TAuthorizeSecurityGroupIngressRequest.html)

  Classe [AuthorizeSecurityGroupIngressResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TAuthorizeSecurityGroupIngressResponse.html)

  Classe [IpPermission](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TIpPermission.html)

  Classe [IpRange](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TIpRange.html)

### O código
<a name="w2aac19c15c17c13c17c17b7b1"></a>

```
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Amazon.EC2;
using Amazon.EC2.Model;

namespace EC2AddRuleForRDP
{
  // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  // Class to add a rule that allows inbound traffic on TCP a port
  class Program
  {
    private const int DefaultPort = 3389;

    static async Task Main(string[] args)
    {
      // Parse the command line and show help if necessary
      var parsedArgs = CommandLine.Parse(args);
      if(parsedArgs.Count == 0)
      {
        PrintHelp();
        return;
      }

      // Get the application arguments from the parsed list
      var groupID = CommandLine.GetArgument(parsedArgs, null, "-g", "--group-id");
      var ipAddress = CommandLine.GetArgument(parsedArgs, null, "-i", "--ip-address");
      var portStr = CommandLine.GetArgument(parsedArgs, DefaultPort.ToString(), "-p", "--port");
      if(string.IsNullOrEmpty(ipAddress))
        CommandLine.ErrorExit("\nYou must supply an IP address in CIDR format.");
      if(string.IsNullOrEmpty(groupID) || !groupID.StartsWith("sg-"))
        CommandLine.ErrorExit("\nThe ID for a security group is missing or incorrect.");
      if(int.Parse(portStr) == 0)
        CommandLine.ErrorExit($"\nThe given TCP port number, {portStr}, isn't allowed.");

      // Add a rule to the given security group that allows
      // inbound traffic on a TCP port
      await AddIngressRule(
        new AmazonEC2Client(), groupID, ipAddress, int.Parse(portStr));
    }


    //
    // Method that adds a TCP ingress rule to a security group
    private static async Task AddIngressRule(
      IAmazonEC2 eC2Client, string groupID, string ipAddress, int port)
    {
      // Create an object to hold the request information for the rule.
      // It uses an IpPermission object to hold the IP information for the rule.
      var ingressRequest = new AuthorizeSecurityGroupIngressRequest{
        GroupId = groupID};
      ingressRequest.IpPermissions.Add(new IpPermission{
        IpProtocol = "tcp",
        FromPort = port,
        ToPort = port,
        Ipv4Ranges = new List<IpRange>() { new IpRange { CidrIp = ipAddress } }
      });

      // Create the inbound rule for the security group
      AuthorizeSecurityGroupIngressResponse responseIngress =
        await eC2Client.AuthorizeSecurityGroupIngressAsync(ingressRequest);
      Console.WriteLine($"\nNew RDP rule was written in {groupID} for {ipAddress}.");
      Console.WriteLine($"Result: {responseIngress.HttpStatusCode}");
    }


    //
    // Command-line help
    private static void PrintHelp()
    {
      Console.WriteLine(
        "\nUsage: EC2AddRuleForRDP -g <group-id> -i <ip-address> [-p <port>]" +
        "\n  -g, --group-id: The ID of the security group to which you want to add the inbound rule." +
        "\n  -i, --ip-address: An IP address or address range in CIDR format." +
        "\n  -p, --port: The TCP port number. Defaults to 3389.");
    }
  }


  // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  // Class that represents a command line on the console or terminal.
  // (This is the same for all examples. When you have seen it once, you can ignore it.)
  static class CommandLine
  {
    //
    // Method to parse a command line of the form: "--key value" or "-k value".
    //
    // Parameters:
    // - args: The command-line arguments passed into the application by the system.
    //
    // Returns:
    // A Dictionary with string Keys and Values.
    //
    // If a key is found without a matching value, Dictionary.Value is set to the key
    //  (including the dashes).
    // If a value is found without a matching key, Dictionary.Key is set to "--NoKeyN",
    //  where "N" represents sequential numbers.
    public static Dictionary<string,string> Parse(string[] args)
    {
      var parsedArgs = new Dictionary<string,string>();
      int i = 0, n = 0;
      while(i < args.Length)
      {
        // If the first argument in this iteration starts with a dash it's an option.
        if(args[i].StartsWith("-"))
        {
          var key = args[i++];
          var value = key;

          // Check to see if there's a value that goes with this option?
          if((i < args.Length) && (!args[i].StartsWith("-"))) value = args[i++];
          parsedArgs.Add(key, value);
        }

        // If the first argument in this iteration doesn't start with a dash, it's a value
        else
        {
          parsedArgs.Add("--NoKey" + n.ToString(), args[i++]);
          n++;
        }
      }

      return parsedArgs;
    }

    //
    // Method to get an argument from the parsed command-line arguments
    //
    // Parameters:
    // - parsedArgs: The Dictionary object returned from the Parse() method (shown above).
    // - defaultValue: The default string to return if the specified key isn't in parsedArgs.
    // - keys: An array of keys to look for in parsedArgs.
    public static string GetArgument(
      Dictionary<string,string> parsedArgs, string defaultReturn, params string[] keys)
    {
      string retval = null;
      foreach(var key in keys)
        if(parsedArgs.TryGetValue(key, out retval)) break;
      return retval ?? defaultReturn;
    }

    //
    // Method to exit the application with an error.
    public static void ErrorExit(string msg, int code=1)
    {
      Console.WriteLine("\nError");
      Console.WriteLine(msg);
      Environment.Exit(code);
    }
  }

}
```

## Considerações adicionais
<a name="authorize-ingress-additional"></a>
+ Se você não fornecer um número de porta, o aplicativo usará como padrão a porta 3389. Essa é a porta do Windows RDP, que permite que você se conecte a uma instância do EC2 executando o Windows. Se você iniciar uma instância EC2 do Linux, use a porta TCP 22 (SSH).
+ Observe que o exemplo é definido como `IpProtocol` “tcp”. Os valores de `IpProtocol` podem ser encontrados na descrição da `IpProtocol` propriedade da [IpPermission](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TIpPermission.html)classe.
+ Talvez você queira o endereço IP do computador local ao usar este exemplo. A seguir estão algumas das maneiras pelas quais você pode obter o endereço.
  + Se seu computador local (do qual você se conectará à instância do EC2) tiver um endereço IP público estático, você poderá usar um serviço para obter esse endereço. Um desses serviços é o [http://checkip.amazonaws.com/](http://checkip.amazonaws.com/). Para ler mais sobre a autorização de tráfego de entrada, consulte [Regras de grupos de segurança](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/working-with-security-groups.html#adding-security-group-rule) e [Regras de grupo de segurança para diferentes casos de uso](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-rules-reference.html) no [Guia do usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).
  + Outra maneira de obter o endereço IP do seu computador local é usar o [console do Amazon EC2](https://console.aws.amazon.com/ec2/v2/home#SecurityGroups).

    Selecione um dos seus grupos de segurança, selecione a guia **Regras de entrada** e escolha **Editar regras de entrada**. Em uma regra de entrada, abra o menu suspenso na coluna **Fonte** e escolha **Meu IP** para ver o endereço IP do seu computador local no formato CIDR. Certifique-se de **cancelar** a operação.
+ Você pode verificar os resultados desse exemplo examinando a lista de grupos de segurança no [console do Amazon EC2](https://console.aws.amazon.com/ec2/v2/home#SecurityGroups).

# Trabalhar com pares de chaves do Amazon EC2
<a name="key-pairs"></a>

O Amazon EC2 utiliza criptografia de chave pública para criptografar e descriptografar as informações de login. A criptografia de chave pública usa uma chave pública para criptografar dados e, em seguida, o destinatário usa a chave privada para descriptografar os dados. As chaves pública e privada são conhecidas como par de chaves. Se quiser fazer login em uma instância do EC2, você deve especificar um par de chaves ao iniciá-la e, em seguida, fornecer a chave privada do par ao se conectar a ela.

Ao iniciar uma instância do EC2, é possível criar um par de chave para ela ou usar um que já foi usado ao iniciar outras instâncias. Para ler mais sobre pares de chaves do Amazon EC2, consulte [Working with Amazon EC2 key pairs](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) no [Guia do usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).

Para obter informações sobre os pré-requisitos APIs e, consulte a seção principal (). [Trabalhar com o Amazon EC2](ec2-apis-intro.md)

**Topics**
+ [Criar e exibir pares de chaves](create-save-key-pair.md)
+ [Excluir pares de chaves](delete-key-pairs.md)

# Criar e exibir pares de chaves
<a name="create-save-key-pair"></a>

Este exemplo mostra como usar o AWS SDK para .NET para criar um par de chaves. O aplicativo usa o nome do novo par de chaves e o nome de um arquivo PEM (com a extensão “.pem”). Ele cria o par de chaves, grava a chave privada no arquivo PEM e exibe todos os pares de chaves disponíveis. Se você não fornecer argumentos de linha de comando, o aplicativo apenas exibirá todos os pares de chaves disponíveis.

As seções a seguir fornecem snippets desse exemplo. O [código completo do exemplo](#create-save-key-pair-complete-code) é mostrado depois e pode ser criado e executado como está.

**Topics**
+ [Criar o par de chaves](#create-save-key-pair-create)
+ [Exibir pares de chaves disponíveis](#create-save-key-pair-display)
+ [Código completo](#create-save-key-pair-complete-code)
+ [Considerações adicionais](#create-save-key-pair-additional)

## Criar o par de chaves
<a name="create-save-key-pair-create"></a>

O snippet a seguir cria um par de chaves e, em seguida, armazena a chave privada no arquivo PEM fornecido.

O exemplo [no final deste tópico](#create-save-key-pair-complete-code) mostra o snippet em uso.

```
    //
    // Method to create a key pair and save the key material in a PEM file
    private static async Task CreateKeyPair(
      IAmazonEC2 ec2Client, string keyPairName, string pemFileName)
    {
      // Create the key pair
      CreateKeyPairResponse response =
        await ec2Client.CreateKeyPairAsync(new CreateKeyPairRequest{
          KeyName = keyPairName
        });
      Console.WriteLine($"\nCreated new key pair: {response.KeyPair.KeyName}");

      // Save the private key in a PEM file
      using (var s = new FileStream(pemFileName, FileMode.Create))
      using (var writer = new StreamWriter(s))
      {
        writer.WriteLine(response.KeyPair.KeyMaterial);
      }
    }
```

## Exibir pares de chaves disponíveis
<a name="create-save-key-pair-display"></a>

O snippet a seguir exibe uma lista dos pares de chaves disponíveis.

O exemplo [no final deste tópico](#create-save-key-pair-complete-code) mostra o snippet em uso.

```
    //
    // Method to show the key pairs that are available
    private static async Task EnumerateKeyPairs(IAmazonEC2 ec2Client)
    {
      DescribeKeyPairsResponse response = await ec2Client.DescribeKeyPairsAsync();
      Console.WriteLine("Available key pairs:");
      foreach (KeyPairInfo item in response.KeyPairs)
        Console.WriteLine($"  {item.KeyName}");
    }
```

## Código completo
<a name="create-save-key-pair-complete-code"></a>

Esta seção mostra as referências relevantes e o código completo desse exemplo.

### Referências do SDK
<a name="w2aac19c15c17c15c11c19b5b1"></a>

NuGet pacotes:
+ [AWSSDK.EC2](https://www.nuget.org/packages/AWSSDK.EC2)

Elementos de programação:
+ Namespace [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2.html)

  Classe [Amazon EC2 Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TEC2Client.html)
+ Namespace [Amazon.EC2.model](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2Model.html)

  Classe [CreateKeyPairRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TCreateKeyPairRequest.html)

  Classe [CreateKeyPairResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TCreateKeyPairResponse.html)

  Classe [DescribeKeyPairsResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeKeyPairsResponse.html)

  Classe [KeyPairInfo](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TKeyPairInfo.html)

### O código
<a name="w2aac19c15c17c15c11c19b7b1"></a>

```
using System;
using System.Threading.Tasks;
using System.IO;
using Amazon.EC2;
using Amazon.EC2.Model;
using System.Collections.Generic;

namespace EC2CreateKeyPair
{
  // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  // Class to create and store a key pair
  class Program
  {
    static async Task Main(string[] args)
    {
      // Create the EC2 client
      var ec2Client = new AmazonEC2Client();

      // Parse the command line and show help if necessary
      var parsedArgs = CommandLine.Parse(args);
      if(parsedArgs.Count == 0)
      {
        // In the case of no command-line arguments,
        // just show help and the existing key pairs
        PrintHelp();
        Console.WriteLine("\nNo arguments specified.");
        Console.Write(
          "Do you want to see a list of the existing key pairs? ((y) or n): ");
        string response = Console.ReadLine();
        if((string.IsNullOrEmpty(response)) || (response.ToLower() == "y"))
          await EnumerateKeyPairs(ec2Client);
        return;
      }

      // Get the application arguments from the parsed list
      string keyPairName =
        CommandLine.GetArgument(parsedArgs, null, "-k", "--keypair-name");
      string pemFileName =
        CommandLine.GetArgument(parsedArgs, null, "-p", "--pem-filename");
      if(string.IsNullOrEmpty(keyPairName))
        CommandLine.ErrorExit("\nNo key pair name specified." +
          "\nRun the command with no arguments to see help.");
      if(string.IsNullOrEmpty(pemFileName) || !pemFileName.EndsWith(".pem"))
        CommandLine.ErrorExit("\nThe PEM filename is missing or incorrect." +
          "\nRun the command with no arguments to see help.");

      // Create the key pair
      await CreateKeyPair(ec2Client, keyPairName, pemFileName);
      await EnumerateKeyPairs(ec2Client);
    }


    //
    // Method to create a key pair and save the key material in a PEM file
    private static async Task CreateKeyPair(
      IAmazonEC2 ec2Client, string keyPairName, string pemFileName)
    {
      // Create the key pair
      CreateKeyPairResponse response =
        await ec2Client.CreateKeyPairAsync(new CreateKeyPairRequest{
          KeyName = keyPairName
        });
      Console.WriteLine($"\nCreated new key pair: {response.KeyPair.KeyName}");

      // Save the private key in a PEM file
      using (var s = new FileStream(pemFileName, FileMode.Create))
      using (var writer = new StreamWriter(s))
      {
        writer.WriteLine(response.KeyPair.KeyMaterial);
      }
    }


    //
    // Method to show the key pairs that are available
    private static async Task EnumerateKeyPairs(IAmazonEC2 ec2Client)
    {
      DescribeKeyPairsResponse response = await ec2Client.DescribeKeyPairsAsync();
      Console.WriteLine("Available key pairs:");
      foreach (KeyPairInfo item in response.KeyPairs)
        Console.WriteLine($"  {item.KeyName}");
    }


    //
    // Command-line help
    private static void PrintHelp()
    {
      Console.WriteLine(
        "\nUsage: EC2CreateKeyPair -k <keypair-name> -p <pem-filename>" +
        "\n  -k, --keypair-name: The name you want to assign to the key pair." +
        "\n  -p, --pem-filename: The name of the PEM file to create, with a \".pem\" extension.");
    }
  }


  // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  // Class that represents a command line on the console or terminal.
  // (This is the same for all examples. When you have seen it once, you can ignore it.)
  static class CommandLine
  {
    //
    // Method to parse a command line of the form: "--key value" or "-k value".
    //
    // Parameters:
    // - args: The command-line arguments passed into the application by the system.
    //
    // Returns:
    // A Dictionary with string Keys and Values.
    //
    // If a key is found without a matching value, Dictionary.Value is set to the key
    //  (including the dashes).
    // If a value is found without a matching key, Dictionary.Key is set to "--NoKeyN",
    //  where "N" represents sequential numbers.
    public static Dictionary<string,string> Parse(string[] args)
    {
      var parsedArgs = new Dictionary<string,string>();
      int i = 0, n = 0;
      while(i < args.Length)
      {
        // If the first argument in this iteration starts with a dash it's an option.
        if(args[i].StartsWith("-"))
        {
          var key = args[i++];
          var value = key;

          // Check to see if there's a value that goes with this option?
          if((i < args.Length) && (!args[i].StartsWith("-"))) value = args[i++];
          parsedArgs.Add(key, value);
        }

        // If the first argument in this iteration doesn't start with a dash, it's a value
        else
        {
          parsedArgs.Add("--NoKey" + n.ToString(), args[i++]);
          n++;
        }
      }

      return parsedArgs;
    }

    //
    // Method to get an argument from the parsed command-line arguments
    //
    // Parameters:
    // - parsedArgs: The Dictionary object returned from the Parse() method (shown above).
    // - defaultValue: The default string to return if the specified key isn't in parsedArgs.
    // - keys: An array of keys to look for in parsedArgs.
    public static string GetArgument(
      Dictionary<string,string> parsedArgs, string defaultReturn, params string[] keys)
    {
      string retval = null;
      foreach(var key in keys)
        if(parsedArgs.TryGetValue(key, out retval)) break;
      return retval ?? defaultReturn;
    }

    //
    // Method to exit the application with an error.
    public static void ErrorExit(string msg, int code=1)
    {
      Console.WriteLine("\nError");
      Console.WriteLine(msg);
      Environment.Exit(code);
    }
  }

}
```

## Considerações adicionais
<a name="create-save-key-pair-additional"></a>
+ Depois de executar o exemplo, você pode ver o novo par de chaves no [console do Amazon EC2](https://console.aws.amazon.com/ec2/#KeyPairs).
+ Ao criar um par de chaves, você deve salvar a chave privada que é retornada, pois não vai poder recuperá-la depois.

# Excluir pares de chaves
<a name="delete-key-pairs"></a>

Este exemplo mostra como usar o AWS SDK para .NET para excluir um par de chaves. O aplicativo usa o nome de um par de chave. Ele exclui o par de chave e, em seguida, exibe todos os pares de chaves disponíveis. Se você não fornecer argumentos de linha de comando, o aplicativo apenas exibirá todos os pares de chaves disponíveis.

As seções a seguir fornecem snippets desse exemplo. O [código completo do exemplo](#delete-key-pairs-complete-code) é mostrado depois e pode ser criado e executado como está.

**Topics**
+ [Criar pares de chaves](#delete-key-pairs-create)
+ [Exibir pares de chaves disponíveis](#delete-key-pairs-display)
+ [Código completo](#delete-key-pairs-complete-code)

## Criar pares de chaves
<a name="delete-key-pairs-create"></a>

O snippet a seguir exclui um par de chave.

O exemplo [no final deste tópico](#delete-key-pairs-complete-code) mostra o snippet em uso.

```
    //
    // Method to delete a key pair
    private static async Task DeleteKeyPair(IAmazonEC2 ec2Client, string keyName)
    {
      await ec2Client.DeleteKeyPairAsync(new DeleteKeyPairRequest{
        KeyName = keyName});
      Console.WriteLine($"\nKey pair {keyName} has been deleted (if it existed).");
    }
```

## Exibir pares de chaves disponíveis
<a name="delete-key-pairs-display"></a>

O snippet a seguir exibe uma lista dos pares de chaves disponíveis.

O exemplo [no final deste tópico](#delete-key-pairs-complete-code) mostra o snippet em uso.

```
    //
    // Method to show the key pairs that are available
    private static async Task EnumerateKeyPairs(IAmazonEC2 ec2Client)
    {
      DescribeKeyPairsResponse response = await ec2Client.DescribeKeyPairsAsync();
      Console.WriteLine("Available key pairs:");
      foreach (KeyPairInfo item in response.KeyPairs)
        Console.WriteLine($"  {item.KeyName}");
    }
```

## Código completo
<a name="delete-key-pairs-complete-code"></a>

Esta seção mostra as referências relevantes e o código completo desse exemplo.

### Referências do SDK
<a name="w2aac19c15c17c15c13c19b5b1"></a>

NuGet pacotes:
+ [AWSSDK.EC2](https://www.nuget.org/packages/AWSSDK.EC2)

Elementos de programação:
+ Namespace [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2.html)

  Classe [Amazon EC2 Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TEC2Client.html)
+ Namespace [Amazon.EC2.model](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2Model.html)

  Classe [https://docs.aws.amazon.com/sdkfornet/v3/apidocs/](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/)

  Classe [DescribeKeyPairsResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeKeyPairsResponse.html)

  Classe [KeyPairInfo](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TKeyPairInfo.html)

### O código
<a name="w2aac19c15c17c15c13c19b7b1"></a>

```
using System;
using System.Threading.Tasks;
using Amazon.EC2;
using Amazon.EC2.Model;

namespace EC2DeleteKeyPair
{
  class Program
  {
    static async Task Main(string[] args)
    {
      // Create the EC2 client
      var ec2Client = new AmazonEC2Client();

      if(args.Length == 1)
      {
        // Delete a key pair (if it exists)
        await DeleteKeyPair(ec2Client, args[0]);

        // Display the key pairs that are left
        await EnumerateKeyPairs(ec2Client);
      }
      else
      {
        Console.WriteLine("\nUsage: EC2DeleteKeyPair keypair-name");
        Console.WriteLine("  keypair-name - The name of the key pair you want to delete.");
        Console.WriteLine("\nNo arguments specified.");
        Console.Write(
          "Do you want to see a list of the existing key pairs? ((y) or n): ");
        string response = Console.ReadLine();
        if((string.IsNullOrEmpty(response)) || (response.ToLower() == "y"))
          await EnumerateKeyPairs(ec2Client);
      }
    }


    //
    // Method to delete a key pair
    private static async Task DeleteKeyPair(IAmazonEC2 ec2Client, string keyName)
    {
      await ec2Client.DeleteKeyPairAsync(new DeleteKeyPairRequest{
        KeyName = keyName});
      Console.WriteLine($"\nKey pair {keyName} has been deleted (if it existed).");
    }


    //
    // Method to show the key pairs that are available
    private static async Task EnumerateKeyPairs(IAmazonEC2 ec2Client)
    {
      DescribeKeyPairsResponse response = await ec2Client.DescribeKeyPairsAsync();
      Console.WriteLine("Available key pairs:");
      foreach (KeyPairInfo item in response.KeyPairs)
        Console.WriteLine($"  {item.KeyName}");
    }
  }
}
```

# Consulte regiões e zonas de disponibilidade (AZs) no Amazon EC2
<a name="using-regions-and-availability-zones"></a>

O Amazon EC2 está hospedado em vários locais do mundo. Esses locais são compostos por regiões da e zonas de disponibilidade. Cada região é uma área geográfica separada, com vários locais isolados, conhecidos como zonas de disponibilidade.

Para ler mais sobre regiões e zonas de disponibilidade, consulte [Regiões e zonas de disponibilidade](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) no [Guia do usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).

Este exemplo mostra como usar o AWS SDK para .NET para obter detalhes sobre as regiões e zonas de disponibilidade relacionadas a um cliente EC2. O aplicativo exibe listas das regiões e zonas de disponibilidade disponíveis para um cliente EC2.

## Referências do SDK
<a name="w2aac19c15c17c17b9b1"></a>

NuGet pacotes:
+ [AWSSDK.EC2](https://www.nuget.org/packages/AWSSDK.EC2)

Elementos de programação:
+ Namespace [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2.html)

  Classe [Amazon EC2 Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TEC2Client.html)
+ Namespace [Amazon.EC2.model](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2Model.html)

  Classe [DescribeAvailabilityZonesResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeAvailabilityZonesResponse.html)

  Classe [DescribeRegionsResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeRegionsResponse.html)

  Classe [AvailabilityZone](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TAvailabilityZone.html)

  Classe [Region](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TRegion.html)

```
using System;
using System.Threading.Tasks;
using Amazon.EC2;
using Amazon.EC2.Model;

namespace EC2RegionsAndZones
{
  class Program
  {
    static async Task Main(string[] args)
    {
      Console.WriteLine(
        "Finding the Regions and Availability Zones available to an EC2 client...");

      // Create the EC2 client
      var ec2Client = new AmazonEC2Client();

      // Display the Regions and Availability Zones
      await DescribeRegions(ec2Client);
      await DescribeAvailabilityZones(ec2Client);
    }


    //
    // Method to display Regions
    private static async Task DescribeRegions(IAmazonEC2 ec2Client)
    {
      Console.WriteLine("\nRegions that are enabled for the EC2 client:");
      DescribeRegionsResponse response = await ec2Client.DescribeRegionsAsync();
      foreach (Region region in response.Regions)
        Console.WriteLine(region.RegionName);
    }


    //
    // Method to display Availability Zones
    private static async Task DescribeAvailabilityZones(IAmazonEC2 ec2Client)
    {
      Console.WriteLine("\nAvailability Zones for the EC2 client's region:");
      DescribeAvailabilityZonesResponse response =
        await ec2Client.DescribeAvailabilityZonesAsync();
      foreach (AvailabilityZone az in response.AvailabilityZones)
        Console.WriteLine(az.ZoneName);
    }
  }
}
```

# Trabalhar com as instâncias do Amazon EC2
<a name="how-to-ec2"></a>

Você pode usar o AWS SDK para .NET para controlar instâncias do Amazon EC2 com operações como criar, iniciar e encerrar. Os tópicos nesta seção fornecem alguns exemplos de como fazer isso. Para ler mais sobre instâncias do EC2, consulte as [Instâncias do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Instances.html) no [Guia do usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).

Para obter informações sobre os pré-requisitos APIs e, consulte a seção principal (). [Trabalhar com o Amazon EC2](ec2-apis-intro.md)

**Topics**
+ [Iniciar uma instância do EC2](run-instance.md)
+ [Encerramento de uma instância do EC2](terminate-instance.md)

# Iniciar uma instância do Amazon EC2
<a name="run-instance"></a>

Este exemplo mostra como usar o AWS SDK para .NET para iniciar uma ou mais instâncias do Amazon EC2 configuradas de forma idêntica a partir da mesma Amazon Machine Image (AMI). Ao usar [várias entradas](#run-instance-gather) que você fornece, o aplicativo executa uma instância do EC2 e monitora a instância até que ela saia do estado “Pendente”.

Quando a instância do EC2 estiver em execução, será possível se conectar a ela remotamente, conforme descrito em [(opcional) Conecte-se à instância](#connect-to-instance).

**Atenção**  
O EC2-Classic foi removido em 15 de agosto de 2022. É recomendável migrar do EC2-Classic para uma VPC. Para acessar mais informações, consulte a postagem do blog [EC2-Classic Networking is Retiring - Here's How to Prepare](https://aws.amazon.com/blogs/aws/ec2-classic-is-retiring-heres-how-to-prepare/).

As seções a seguir fornecem snippets e outras informações para este exemplo. O [código completo do exemplo](#run-instance-complete-code) é mostrado após os snippets e pode ser criado e executado como está.

**Topics**
+ [Colete o que você precisa](#run-instance-gather)
+ [Iniciar uma instância](#run-instance-launch)
+ [Monitorar instância](#run-instance-monitor)
+ [Código completo](#run-instance-complete-code)
+ [Considerações adicionais](#run-instance-additional)
+ [(opcional) Conecte-se à instância](#connect-to-instance)
+ [Limpeza](#run-instance-cleanup)

## Colete o que você precisa
<a name="run-instance-gather"></a>

Para iniciar uma instância do EC2, você precisará de várias coisas.
+ Uma [VPC](https://docs.aws.amazon.com/vpc/latest/userguide/) onde a instância será iniciada. Se for uma instância do Windows e você estiver se conectando a ela por meio de RDP, a VPC provavelmente precisará de um gateway da Internet anexado a ela, bem como uma entrada para o gateway de Internet na tabela de rotas. Para obter mais informações, consulte [Gateways da Internet](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html) no *Guia do usuário da Amazon VPC*.
+ O ID da sub-rede na qual a instância será iniciada. Uma maneira fácil de encontrar ou criar isso é fazer login no [console da Amazon VPC](https://console.aws.amazon.com/vpc/home#subnets), mas você também pode obtê-lo programaticamente usando os métodos e. [CreateSubnetAsync[DescribeSubnetsAsync](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/MEC2DescribeSubnetsAsyncDescribeSubnetsRequestCancellationToken.html)](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/MEC2CreateSubnetAsyncCreateSubnetRequestCancellationToken.html)
**nota**  
Se você não fornecer esse parâmetro, a nova instância será executada na VPC padrão da conta.
+ O ID de um grupo de segurança existente que pertence à VPC em que a instância será iniciada. Para obter mais informações, consulte [Como trabalhar com grupos de segurança no Amazon EC2](security-groups.md).
+ Se você quiser se conectar à nova instância, o grupo de segurança mencionado anteriormente deve ter uma regra de entrada apropriada que permita tráfego SSH na porta 22 (instância Linux) ou tráfego RDP na porta 3389 (instância do Windows). Para obter informações sobre como fazer isso, consulte [Como atualizar Grupos de Segurança](authorize-ingress.md), inclusive o [Considerações adicionais](authorize-ingress.md#authorize-ingress-additional) próximo ao final desse tópico.
+ A imagem de máquina da Amazon (AMI) que será usada para criar a instância. Para obter informações sobre AMIs, consulte [Amazon Machine Images (AMIs)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) no Guia do [usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/). Em particular, consulte [Encontre uma AMI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html) e [compartilhe AMIs](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/sharing-amis.html).
+ O nome de um par de chave do EC2 existente, que é usado para se conectar à nova instância. Para obter mais informações, consulte [Trabalhar com pares de chaves do Amazon EC2](key-pairs.md).
+ O nome do arquivo PEM que contém a chave privada do par de chave EC2 mencionado anteriormente. O arquivo PEM é usado quando você se [conecta remotamente](#connect-to-instance) à instância.

## Iniciar uma instância
<a name="run-instance-launch"></a>

O seguinte snippet inicia uma instância do EC2.

Os exemplos [no final deste tópico](#run-instance-complete-code) mostram o snippet em uso.

```
    //
    // Method to launch the instances
    // Returns a list with the launched instance IDs
    private static async Task<List<string>> LaunchInstances(
      IAmazonEC2 ec2Client, RunInstancesRequest requestLaunch)
    {
      var instanceIds = new List<string>();
      RunInstancesResponse responseLaunch =
        await ec2Client.RunInstancesAsync(requestLaunch);

      Console.WriteLine("\nNew instances have been created.");
      foreach (Instance item in responseLaunch.Reservation.Instances)
      {
        instanceIds.Add(item.InstanceId);
        Console.WriteLine($"  New instance: {item.InstanceId}");
      }

      return instanceIds;
    }
```

## Monitorar instância
<a name="run-instance-monitor"></a>

O snippet a seguir monitora a instância até que ela saia do estado “Pendente”.

Os exemplos [no final deste tópico](#run-instance-complete-code) mostram o snippet em uso.

Consulte a [InstanceState](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TInstanceState.html)classe para ver os valores válidos da `Instance.State.Code` propriedade.

```
    //
    // Method to wait until the instances are running (or at least not pending)
    private static async Task CheckState(IAmazonEC2 ec2Client, List<string> instanceIds)
    {
      Console.WriteLine(
        "\nWaiting for the instances to start." +
        "\nPress any key to stop waiting. (Response might be slightly delayed.)");

      int numberRunning;
      DescribeInstancesResponse responseDescribe;
      var requestDescribe = new DescribeInstancesRequest{
        InstanceIds = instanceIds};

      // Check every couple of seconds
      int wait = 2000;
      while(true)
      {
        // Get and check the status for each of the instances to see if it's past pending.
        // Once all instances are past pending, break out.
        // (For this example, we are assuming that there is only one reservation.)
        Console.Write(".");
        numberRunning = 0;
        responseDescribe = await ec2Client.DescribeInstancesAsync(requestDescribe);
        foreach(Instance i in responseDescribe.Reservations[0].Instances)
        {
          // Check the lower byte of State.Code property
          // Code == 0 is the pending state
          if((i.State.Code & 255) > 0) numberRunning++;
        }
        if(numberRunning == responseDescribe.Reservations[0].Instances.Count)
          break;

        // Wait a bit and try again (unless the user wants to stop waiting)
        Thread.Sleep(wait);
        if(Console.KeyAvailable)
          break;
      }

      Console.WriteLine("\nNo more instances are pending.");
      foreach(Instance i in responseDescribe.Reservations[0].Instances)
      {
        Console.WriteLine($"For {i.InstanceId}:");
        Console.WriteLine($"  VPC ID: {i.VpcId}");
        Console.WriteLine($"  Instance state: {i.State.Name}");
        Console.WriteLine($"  Public IP address: {i.PublicIpAddress}");
        Console.WriteLine($"  Public DNS name: {i.PublicDnsName}");
        Console.WriteLine($"  Key pair name: {i.KeyName}");
      }
    }
```

## Código completo
<a name="run-instance-complete-code"></a>

Esta seção mostra as referências relevantes e o código completo desse exemplo.

### Referências do SDK
<a name="w2aac19c15c17c19b9c27b5b1"></a>

NuGet pacotes:
+ [AWSSDK.EC2](https://www.nuget.org/packages/AWSSDK.EC2)

Elementos de programação:
+ Namespace [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2.html)

  Classe [Amazon EC2 Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TEC2Client.html)

  Classe [InstanceType](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TInstanceType.html)
+ Namespace [Amazon.EC2.model](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2Model.html)

  Classe [DescribeInstancesRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeInstancesRequest.html)

  Classe [DescribeInstancesResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeInstancesResponse.html)

  Classe [Instância](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TInstance.html)

  Classe [InstanceNetworkInterfaceSpecification](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TInstanceNetworkInterfaceSpecification.html)

  Classe [RunInstancesRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TRunInstancesRequest.html)

  Classe [RunInstancesResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TRunInstancesResponse.html)

### O código
<a name="w2aac19c15c17c19b9c27b7b1"></a>

```
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using Amazon.EC2;
using Amazon.EC2.Model;

namespace EC2LaunchInstance
{
  // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  // Class to launch an EC2 instance
  class Program
  {
    static async Task Main(string[] args)
    {
      // Parse the command line and show help if necessary
      var parsedArgs = CommandLine.Parse(args);
      if(parsedArgs.Count == 0)
      {
        PrintHelp();
        return;
      }

      // Get the application arguments from the parsed list
      string groupID =
        CommandLine.GetArgument(parsedArgs, null, "-g", "--group-id");
      string ami =
        CommandLine.GetArgument(parsedArgs, null, "-a", "--ami-id");
      string keyPairName =
        CommandLine.GetArgument(parsedArgs, null, "-k", "--keypair-name");
      string subnetID =
        CommandLine.GetArgument(parsedArgs, null, "-s", "--subnet-id");
      if(   (string.IsNullOrEmpty(groupID) || !groupID.StartsWith("sg-"))
         || (string.IsNullOrEmpty(ami) || !ami.StartsWith("ami-"))
         || (string.IsNullOrEmpty(keyPairName))
         || (!string.IsNullOrEmpty(subnetID) && !subnetID.StartsWith("subnet-")))
        CommandLine.ErrorExit(
          "\nOne or more of the required arguments is missing or incorrect." +
          "\nRun the command with no arguments to see help.");

      // Create an EC2 client
      var ec2Client = new AmazonEC2Client();

      // Create an object with the necessary properties
      RunInstancesRequest request = GetRequestData(groupID, ami, keyPairName, subnetID);

      // Launch the instances and wait for them to start running
      var instanceIds = await LaunchInstances(ec2Client, request);
      await CheckState(ec2Client, instanceIds);
    }


    //
    // Method to put together the properties needed to launch the instance.
    private static RunInstancesRequest GetRequestData(
      string groupID, string ami, string keyPairName, string subnetID)
    {
      // Common properties
      var groupIDs = new List<string>() { groupID };
      var request = new RunInstancesRequest()
      {
        // The first three of these would be additional command-line arguments or similar.
        InstanceType = InstanceType.T1Micro,
        MinCount = 1,
        MaxCount = 1,
        ImageId = ami,
        KeyName = keyPairName
      };

      // Properties specifically for EC2 in a VPC.
      if(!string.IsNullOrEmpty(subnetID))
      {
        request.NetworkInterfaces =
          new List<InstanceNetworkInterfaceSpecification>() {
            new InstanceNetworkInterfaceSpecification() {
              DeviceIndex = 0,
              SubnetId = subnetID,
              Groups = groupIDs,
              AssociatePublicIpAddress = true
            }
          };
      }

      // Properties specifically for EC2-Classic
      else
      {
        request.SecurityGroupIds = groupIDs;
      }
      return request;
    }


    //
    // Method to launch the instances
    // Returns a list with the launched instance IDs
    private static async Task<List<string>> LaunchInstances(
      IAmazonEC2 ec2Client, RunInstancesRequest requestLaunch)
    {
      var instanceIds = new List<string>();
      RunInstancesResponse responseLaunch =
        await ec2Client.RunInstancesAsync(requestLaunch);

      Console.WriteLine("\nNew instances have been created.");
      foreach (Instance item in responseLaunch.Reservation.Instances)
      {
        instanceIds.Add(item.InstanceId);
        Console.WriteLine($"  New instance: {item.InstanceId}");
      }

      return instanceIds;
    }


    //
    // Method to wait until the instances are running (or at least not pending)
    private static async Task CheckState(IAmazonEC2 ec2Client, List<string> instanceIds)
    {
      Console.WriteLine(
        "\nWaiting for the instances to start." +
        "\nPress any key to stop waiting. (Response might be slightly delayed.)");

      int numberRunning;
      DescribeInstancesResponse responseDescribe;
      var requestDescribe = new DescribeInstancesRequest{
        InstanceIds = instanceIds};

      // Check every couple of seconds
      int wait = 2000;
      while(true)
      {
        // Get and check the status for each of the instances to see if it's past pending.
        // Once all instances are past pending, break out.
        // (For this example, we are assuming that there is only one reservation.)
        Console.Write(".");
        numberRunning = 0;
        responseDescribe = await ec2Client.DescribeInstancesAsync(requestDescribe);
        foreach(Instance i in responseDescribe.Reservations[0].Instances)
        {
          // Check the lower byte of State.Code property
          // Code == 0 is the pending state
          if((i.State.Code & 255) > 0) numberRunning++;
        }
        if(numberRunning == responseDescribe.Reservations[0].Instances.Count)
          break;

        // Wait a bit and try again (unless the user wants to stop waiting)
        Thread.Sleep(wait);
        if(Console.KeyAvailable)
          break;
      }

      Console.WriteLine("\nNo more instances are pending.");
      foreach(Instance i in responseDescribe.Reservations[0].Instances)
      {
        Console.WriteLine($"For {i.InstanceId}:");
        Console.WriteLine($"  VPC ID: {i.VpcId}");
        Console.WriteLine($"  Instance state: {i.State.Name}");
        Console.WriteLine($"  Public IP address: {i.PublicIpAddress}");
        Console.WriteLine($"  Public DNS name: {i.PublicDnsName}");
        Console.WriteLine($"  Key pair name: {i.KeyName}");
      }
    }


    //
    // Command-line help
    private static void PrintHelp()
    {
      Console.WriteLine(
        "\nUsage: EC2LaunchInstance -g <group-id> -a <ami-id> -k <keypair-name> [-s <subnet-id>]" +
        "\n  -g, --group-id: The ID of the security group." +
        "\n  -a, --ami-id: The ID of an Amazon Machine Image." +
        "\n  -k, --keypair-name - The name of a key pair." +
        "\n  -s, --subnet-id: The ID of a subnet. Required only for EC2 in a VPC.");
    }
  }


  // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  // Class that represents a command line on the console or terminal.
  // (This is the same for all examples. When you have seen it once, you can ignore it.)
  static class CommandLine
  {
    //
    // Method to parse a command line of the form: "--key value" or "-k value".
    //
    // Parameters:
    // - args: The command-line arguments passed into the application by the system.
    //
    // Returns:
    // A Dictionary with string Keys and Values.
    //
    // If a key is found without a matching value, Dictionary.Value is set to the key
    //  (including the dashes).
    // If a value is found without a matching key, Dictionary.Key is set to "--NoKeyN",
    //  where "N" represents sequential numbers.
    public static Dictionary<string,string> Parse(string[] args)
    {
      var parsedArgs = new Dictionary<string,string>();
      int i = 0, n = 0;
      while(i < args.Length)
      {
        // If the first argument in this iteration starts with a dash it's an option.
        if(args[i].StartsWith("-"))
        {
          var key = args[i++];
          var value = key;

          // Check to see if there's a value that goes with this option?
          if((i < args.Length) && (!args[i].StartsWith("-"))) value = args[i++];
          parsedArgs.Add(key, value);
        }

        // If the first argument in this iteration doesn't start with a dash, it's a value
        else
        {
          parsedArgs.Add("--NoKey" + n.ToString(), args[i++]);
          n++;
        }
      }

      return parsedArgs;
    }

    //
    // Method to get an argument from the parsed command-line arguments
    //
    // Parameters:
    // - parsedArgs: The Dictionary object returned from the Parse() method (shown above).
    // - defaultValue: The default string to return if the specified key isn't in parsedArgs.
    // - keys: An array of keys to look for in parsedArgs.
    public static string GetArgument(
      Dictionary<string,string> parsedArgs, string defaultReturn, params string[] keys)
    {
      string retval = null;
      foreach(var key in keys)
        if(parsedArgs.TryGetValue(key, out retval)) break;
      return retval ?? defaultReturn;
    }

    //
    // Method to exit the application with an error.
    public static void ErrorExit(string msg, int code=1)
    {
      Console.WriteLine("\nError");
      Console.WriteLine(msg);
      Environment.Exit(code);
    }
  }

}
```

## Considerações adicionais
<a name="run-instance-additional"></a>
+ Ao verificar o estado de uma instância do EC2, você pode adicionar um filtro à `Filter` propriedade do [DescribeInstancesRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeInstancesRequest.html)objeto. Usando essa técnica, você pode limitar a solicitação a determinadas instâncias; por exemplo, instâncias com uma tag específica determinada pelo usuário.
+ Para resumir, algumas propriedades receberam valores típicos. Em vez disso, qualquer uma, ou todas essas propriedades, podem ser determinadas programaticamente ou por meio da entrada do usuário.
+ Os valores que você pode usar para as `MaxCount` propriedades `MinCount` e do [RunInstancesRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TRunInstancesRequest.html)objeto são determinados pela zona de disponibilidade de destino e pelo número máximo de instâncias permitidas para o tipo de instância. Para obter mais informações, consulte [Quantas instâncias posso executar no Amazon EC2?](https://aws.amazon.com/ec2/faqs/#How_many_instances_can_I_run_in_Amazon_EC2) nas perguntas frequentes (FAQs) do Amazon EC2.
+ Se você quiser usar um tipo de instância diferente deste exemplo, há alguns tipos para escolher. Para acessar mais informações, consulte [Tipos de instâncias do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) no [Guia do usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/). Consulte também [Detalhes do tipo de instância](https://aws.amazon.com/ec2/instance-types/) e [Explorador de tipos de instância](https://aws.amazon.com/ec2/instance-explorer/).
+ Você também pode anexar um [perfil do IAM](net-dg-hosm.md) a uma instância ao iniciá-la. Para fazer isso, crie um [IamInstanceProfileSpecification](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TIamInstanceProfileSpecification.html)objeto cuja `Name` propriedade esteja definida como o nome de uma função do IAM. Em seguida, adicione esse objeto à `IamInstanceProfile` propriedade do [RunInstancesRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TRunInstancesRequest.html)objeto.
**nota**  
Para iniciar uma instância do EC2 com um perfil do IAM anexado, uma configuração de um usuário do IAM deve incluir determinadas permissões. Para acessar mais informações sobre as permissões necessárias, consulte [Conceder permissão a um usuário para passar um perfil do IAM para uma instância](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#permission-to-pass-iam-roles) no [Guia do usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).

## (opcional) Conecte-se à instância
<a name="connect-to-instance"></a>

Depois que uma instância estiver sendo executada, você pode conectar-se a ela remotamente usando o cliente remoto apropriado. Para instâncias Linux e Windows, você precisa do endereço IP público ou do nome DNS público da instância. Você precisará também dos seguintes itens:

**Para instâncias do Linux**

Também é possível usar um cliente SSH para conectar-se à sua instância do Linux. Certifique-se de que o grupo de segurança que você usou ao iniciar a instância permita tráfego SSH na porta 22, conforme descrito em [Como atualizar Grupos de Segurança](authorize-ingress.md).

Você também precisa da parte privada do par de chaves que você usou para iniciar a instância, ou seja, o arquivo PEM.

Para acessar mais informações, consulte [Conectar-se à instância do Linux](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connect-to-linux-instance.html) no Guia do usuário do Amazon EC2.

**Para instâncias do Windows**

Também é possível usar um cliente RDP para conectar-se à sua instância. Certifique-se de que o grupo de segurança que você usou ao iniciar a instância permita tráfego RDP na porta 3389, conforme descrito em [Como atualizar Grupos de Segurança](authorize-ingress.md).

Você precisará também da senha do administrador. Você pode obter isso usando o código de exemplo a seguir, que exige o ID da instância e a parte privada do par de chave usado para iniciar a instância, ou seja, o arquivo PEM.

Para acessar mais informações, consulte [Conectar-se à sua instância do Windows](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connecting_to_windows_instance.html) no Guia do usuário do Amazon EC2.

**Atenção**  
Esse código de exemplo retorna a senha de administrador em texto simples para sua instância.

### Referências do SDK
<a name="w2aac19c15c17c19b9c35c23b1"></a>

NuGet pacotes:
+ [AWSSDK.EC2](https://www.nuget.org/packages/AWSSDK.EC2)

Elementos de programação:
+ Namespace [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2.html)

  Classe [Amazon EC2 Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TEC2Client.html)
+ Namespace [Amazon.EC2.model](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2Model.html)

  Classe [GetPasswordDataRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TGetPasswordDataRequest.html)

  Classe [GetPasswordDataResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TGetPasswordDataResponse.html)

### O código
<a name="w2aac19c15c17c19b9c35c25b1"></a>

```
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Amazon.EC2;
using Amazon.EC2.Model;

namespace EC2GetWindowsPassword
{
  // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  // Class to get the Administrator password of a Windows EC2 instance
  class Program
  {
    static async Task Main(string[] args)
    {
      // Parse the command line and show help if necessary
      var parsedArgs = CommandLine.Parse(args);
      if(parsedArgs.Count == 0)
      {
        PrintHelp();
        return;
      }

      // Get the application arguments from the parsed list
      string instanceID =
        CommandLine.GetArgument(parsedArgs, null, "-i", "--instance-id");
      string pemFileName =
        CommandLine.GetArgument(parsedArgs, null, "-p", "--pem-filename");
      if(   (string.IsNullOrEmpty(instanceID) || !instanceID.StartsWith("i-"))
         || (string.IsNullOrEmpty(pemFileName) || !pemFileName.EndsWith(".pem")))
        CommandLine.ErrorExit(
          "\nOne or more of the required arguments is missing or incorrect." +
          "\nRun the command with no arguments to see help.");

      // Create the EC2 client
      var ec2Client = new AmazonEC2Client();

      // Get and display the password
      string password = await GetPassword(ec2Client, instanceID, pemFileName);
      Console.WriteLine($"\nPassword: {password}");
    }


    //
    // Method to get the administrator password of a Windows EC2 instance
    private static async Task<string> GetPassword(
      IAmazonEC2 ec2Client, string instanceID, string pemFilename)
    {
      string password = string.Empty;
      GetPasswordDataResponse response =
        await ec2Client.GetPasswordDataAsync(new GetPasswordDataRequest{
          InstanceId = instanceID});
      if(response.PasswordData != null)
      {
        password = response.GetDecryptedPassword(File.ReadAllText(pemFilename));
      }
      else
      {
        Console.WriteLine($"\nThe password is not available for instance {instanceID}.");
        Console.WriteLine($"If this is a Windows instance, the password might not be ready.");
      }
      return password;
    }


    //
    // Command-line help
    private static void PrintHelp()
    {
      Console.WriteLine(
        "\nUsage: EC2GetWindowsPassword -i <instance-id> -p pem-filename" +
        "\n  -i, --instance-id: The name of the EC2 instance." +
        "\n  -p, --pem-filename: The name of the PEM file with the private key.");
    }
  }

  // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  // Class that represents a command line on the console or terminal.
  // (This is the same for all examples. When you have seen it once, you can ignore it.)
  static class CommandLine
  {
    //
    // Method to parse a command line of the form: "--key value" or "-k value".
    //
    // Parameters:
    // - args: The command-line arguments passed into the application by the system.
    //
    // Returns:
    // A Dictionary with string Keys and Values.
    //
    // If a key is found without a matching value, Dictionary.Value is set to the key
    //  (including the dashes).
    // If a value is found without a matching key, Dictionary.Key is set to "--NoKeyN",
    //  where "N" represents sequential numbers.
    public static Dictionary<string,string> Parse(string[] args)
    {
      var parsedArgs = new Dictionary<string,string>();
      int i = 0, n = 0;
      while(i < args.Length)
      {
        // If the first argument in this iteration starts with a dash it's an option.
        if(args[i].StartsWith("-"))
        {
          var key = args[i++];
          var value = key;

          // Check to see if there's a value that goes with this option?
          if((i < args.Length) && (!args[i].StartsWith("-"))) value = args[i++];
          parsedArgs.Add(key, value);
        }

        // If the first argument in this iteration doesn't start with a dash, it's a value
        else
        {
          parsedArgs.Add("--NoKey" + n.ToString(), args[i++]);
          n++;
        }
      }

      return parsedArgs;
    }

    //
    // Method to get an argument from the parsed command-line arguments
    //
    // Parameters:
    // - parsedArgs: The Dictionary object returned from the Parse() method (shown above).
    // - defaultValue: The default string to return if the specified key isn't in parsedArgs.
    // - keys: An array of keys to look for in parsedArgs.
    public static string GetArgument(
      Dictionary<string,string> parsedArgs, string defaultReturn, params string[] keys)
    {
      string retval = null;
      foreach(var key in keys)
        if(parsedArgs.TryGetValue(key, out retval)) break;
      return retval ?? defaultReturn;
    }

    //
    // Method to exit the application with an error.
    public static void ErrorExit(string msg, int code=1)
    {
      Console.WriteLine("\nError");
      Console.WriteLine(msg);
      Environment.Exit(code);
    }
  }

}
```

## Limpeza
<a name="run-instance-cleanup"></a>

Quando você não precisar mais da instância do EC2, encerre-a, conforme descrito em [Encerramento de uma instância Amazon EC2](terminate-instance.md).

# Encerramento de uma instância Amazon EC2
<a name="terminate-instance"></a>

Quando uma ou mais instâncias do Amazon EC2 não forem mais necessárias, é possível encerrá-las.

Este exemplo mostra como usar o para AWS SDK para .NET encerrar instâncias do EC2. A entrada requer um ID de instância.

## Referências do SDK
<a name="w2aac19c15c17c19c11b7b1"></a>

NuGet pacotes:
+ [AWSSDK.EC2](https://www.nuget.org/packages/AWSSDK.EC2)

Elementos de programação:
+ Namespace [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2.html)

  Classe [Amazon EC2 Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TEC2Client.html)
+ Namespace [Amazon.EC2.model](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2Model.html)

  Classe [TerminateInstancesRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TTerminateInstancesRequest.html)

  Classe [TerminateInstancesResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TTerminateInstancesResponse.html)

```
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Amazon.EC2;
using Amazon.EC2.Model;

namespace EC2TerminateInstance
{
  class Program
  {
    static async Task Main(string[] args)
    {
      if((args.Length == 1) && (args[0].StartsWith("i-")))
      {
        // Terminate the instance
        var ec2Client = new AmazonEC2Client();
        await TerminateInstance(ec2Client, args[0]);
      }
      else
      {
        Console.WriteLine("\nCommand-line argument missing or incorrect.");
        Console.WriteLine("\nUsage: EC2TerminateInstance instance-ID");
        Console.WriteLine("  instance-ID - The EC2 instance you want to terminate.");
        return;
      }
    }

    //
    // Method to terminate an EC2 instance
    private static async Task TerminateInstance(IAmazonEC2 ec2Client, string instanceID)
    {
      var request = new TerminateInstancesRequest{
        InstanceIds = new List<string>() { instanceID }};
      TerminateInstancesResponse response =
        await ec2Client.TerminateInstancesAsync(new TerminateInstancesRequest{
          InstanceIds = new List<string>() { instanceID }
        });
      foreach (InstanceStateChange item in response.TerminatingInstances)
      {
        Console.WriteLine("Terminated instance: " + item.InstanceId);
        Console.WriteLine("Instance state: " + item.CurrentState.Name);
      }
    }
  }
}
```

Depois de executar o exemplo, é uma boa ideia fazer login no [console do Amazon EC2](https://console.aws.amazon.com/ec2/) para verificar se a [instância do EC2](https://console.aws.amazon.com/ec2/v2/home#Instances) foi encerrada.

# Tutorial de instância spot do Amazon EC2
<a name="how-to-spot-instances"></a>

Este tutorial mostra como usar o AWS SDK para .NET para gerenciar instâncias spot do Amazon EC2.

## Visão geral do
<a name="tutor-spot-net-overview"></a>

Instâncias spot permitem solicitar capacidade não utilizada do Amazon EC2 por um valor mais baixo que o preço sob demanda. Isso pode reduzir significativamente os custos do EC2 para aplicativos que podem ser interrompidos.

O resumo a seguir detalha como as instâncias spot são solicitadas e usadas.

1. Criação uma solicitação de instância spot, especificando o preço máximo que está disposto a pagar.

1. Quando a solicitação for atendida, execute a instância como faria com qualquer outra instância do Amazon EC2.

1. Execute a instância por quanto tempo quiser e, em seguida, encerre-a, a menos que o *preço de spot* mude de maneira que a instância fique encerrada para você.

1. Limpe a solicitação da Instância Spot quando não for mais necessária, para que as Instâncias Spot não sejam mais criadas.

Essa tem sido uma visão geral de alto nível das Instâncias Spot. Para ter uma melhor compreensão das instâncias spot, consulte [Instâncias spot](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html) no [Guia do usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).

## Sobre este tutorial
<a name="about-spot-instances-tutorial"></a>

Ao seguir este tutorial, você usa o AWS SDK para .NET para fazer o seguinte:
+ Criar uma solicitação de instância spot
+ Determinar quando a solicitação de instância spot é atendida
+ Cancelar a solicitação de instância spot
+ Encerrar as instâncias associadas

As seções a seguir fornecem snippets e outras informações para este exemplo. O [código completo do exemplo](#tutor-spot-net-main) é mostrado após os snippets e pode ser criado e executado como está.

**Topics**
+ [Visão geral do](#tutor-spot-net-overview)
+ [Sobre este tutorial](#about-spot-instances-tutorial)
+ [Pré-requisitos](#tutor-spot-net-prereq)
+ [Colete o que você precisa](#tutor-spot-net-gather)
+ [Como criar uma solicitação de instância spot](#tutor-spot-net-submit)
+ [Determinar o estado da solicitação de instância spot](#tutor-spot-net-request-state)
+ [Limpar suas solicitações de instância spot](#tutor-spot-net-clean-up-request)
+ [Limpar as instâncias spot](#tutor-spot-net-clean-up-instance)
+ [Código completo](#tutor-spot-net-main)
+ [Considerações adicionais](#tutor-spot-net-additional)

## Pré-requisitos
<a name="tutor-spot-net-prereq"></a>

Para obter informações sobre os pré-requisitos APIs e, consulte a seção principal (). [Trabalhar com o Amazon EC2](ec2-apis-intro.md)

## Colete o que você precisa
<a name="tutor-spot-net-gather"></a>

Para criar uma solicitação de instância spot, você precisará de várias coisas. 
+ O número da instância e o seu tipo. Há alguns tipos de instância a escolher. Para obter mais informações, consulte [Tipos de instâncias do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) no [Guia do usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/). Consulte também [Detalhes do tipo de instância](https://aws.amazon.com/ec2/instance-types/) e [Explorador de tipos de instância](https://aws.amazon.com/ec2/instance-explorer/).

  Para número padrão para este tutorial é o 1.
+ A imagem de máquina da Amazon (AMI) que será usada para criar a instância. Para obter informações sobre AMIs, consulte [Amazon Machine Images (AMIs)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) no Guia do [usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/). Em particular, consulte [Encontre uma AMI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html) e [compartilhe AMIs](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/sharing-amis.html).
+ O preço máximo que você está disposto a pagar por hora por instância. Você pode ver os preços de todos os tipos de instâncias (tanto para instâncias sob demanda quanto para instâncias spot) na [página de preços do Amazon EC2](https://aws.amazon.com/ec2/pricing/). O preço padrão deste tutorial será explicado posteriormente.
+ Se você quiser se conectar remotamente a uma instância, a um grupo de segurança com a configuração e os recursos adequados. Isso está descrito em [Como trabalhar com grupos de segurança no Amazon EC2](security-groups.md) e as informações sobre como [coletar o que você precisa](run-instance.md#run-instance-gather) e [conectar-se a uma instância](run-instance.md#connect-to-instance) em [Iniciar uma instância do Amazon EC2](run-instance.md). Para simplificar, este tutorial usa o grupo de segurança chamado **padrão**, que todas as contas AWS mais recentes possuem.

Há muitas maneiras de abordar a solicitação de instâncias spot. Estas são estratégias comuns:
+ Faça solicitações que certamente custarão menos que os preços sob demanda.
+ Solicitar com base no valor da computação resultante.
+ Solicitar para adquirir capacidade de computação o mais rápido possível.

As explicações a seguir se referem ao [histórico de preços de instâncias spot](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances-history.html) no [Guia do usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).

### Reduzir custos abaixo sob demanda
<a name="reduce-cost"></a>

Você tem um job de processamento em lote que modera determinado número de horas ou dias para ser executado. Contudo, você tem flexibilidade em relação ao início e ao fim. Você quer ver se pode o concluído por um custo inferior ao das instâncias sob demanda.

Você examina o histórico de preços spot para tipos de instância usando o console da Amazon EC2 ou a API do Amazon EC2. Depois de analisar o histórico de preços do tipo de instância desejado em determinada zona de disponibilidade, há duas abordagens alternativas para sua solicitação:
+ Especificar uma solicitação na extremidade superior do intervalo de preços spot que ainda estão abaixo do preço sob demanda, prevendo que sua solicitação instância spot única seria provavelmente cumprida e executada pelo tempo de computação consecutivo suficiente para concluir o trabalho.
+ Especificar uma solicitação na extremidade inferior do intervalo de preço e planejar a combinação de várias instâncias executadas ao longo do tempo por meio de uma requisição persistente. As instâncias seriam executadas por tempo suficiente, ao todo, para concluir o trabalho com um custo total ainda inferior.

### Não pagar mais que o valor do resultado
<a name="value-of-result"></a>

Você tem um job de processamento de dados para ser executado. Você entende o valor dos resultados do trabalho bem o suficiente para saber o quanto valem em termos de custos computação.

Após analisar o histórico de preços spot para seu tipo de instância, escolha o preço de lance no qual o custo do tempo computacional não é mais que o valor dos resultados do job. Você cria uma requisição persistente e a deixa ser executada de forma intermitente, à medida que o preço spot flutua acima ou abaixo da sua solicitação.

### Adquirir capacidade de computação rapidamente
<a name="acquire-quickly"></a>

Você tem uma necessidade imprevista e de curto prazo para capacidade adicional indisponível pelas instâncias sob demanda. Depois de analisar o histórico de preços spot para seu tipo de instância, você escolhe um preço acima do preço histórico mais alto para aumentar significativamente a probabilidade de sua solicitação ser atendida com rapidez e continuar a computação até a conclusão.

Depois de coletar o que precisa e escolher uma estratégia, você está pronto para solicitar uma Instância Spot. Para este tutorial, o preço máximo da instância spot padrão está definido para ser o mesmo que o preço da instância sob demanda (que é 0,003 USD para este tutorial). Definir o preço desta forma maximiza as chances de que o pedido seja atendido.

## Como criar uma solicitação de instância spot
<a name="tutor-spot-net-submit"></a>

O snippet a seguir mostra como criar uma solicitação de instância spot com os elementos coletados anteriormente.

O exemplo [no final deste tópico](#tutor-spot-net-main) mostra o snippet em uso.

```
    //
    // Method to create a Spot Instance request
    private static async Task<SpotInstanceRequest> CreateSpotInstanceRequest(
      IAmazonEC2 ec2Client, string amiId, string securityGroupName,
      InstanceType instanceType, string spotPrice, int instanceCount)
    {
      var launchSpecification = new LaunchSpecification{
        ImageId = amiId,
        InstanceType = instanceType
      };
      launchSpecification.SecurityGroups.Add(securityGroupName);
      var request = new RequestSpotInstancesRequest{
        SpotPrice = spotPrice,
        InstanceCount = instanceCount,
        LaunchSpecification = launchSpecification
      };

      RequestSpotInstancesResponse result =
        await ec2Client.RequestSpotInstancesAsync(request);
      return result.SpotInstanceRequests[0];
    }
```

O valor importante retornado desse método é o ID da solicitação da Instância Spot, que está contido no `SpotInstanceRequestId` membro do [SpotInstanceRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TSpotInstanceRequest.html)objeto retornado.

**nota**  
Você será cobrado por todas as instâncias spot que forem iniciadas. Para evitar custos desnecessários, certifique-se de [cancelar todas as solicitações](#tutor-spot-net-clean-up-request) e [encerrar todas as instâncias](#tutor-spot-net-clean-up-instance).

## Determinar o estado da solicitação de instância spot
<a name="tutor-spot-net-request-state"></a>

O snippet a seguir mostra como obter informações sobre sua solicitação de instância spot. Você pode usar essas informações para tomar certas decisões em seu código, como decidir continuar esperando o atendimento de uma solicitação de instância spot.

O exemplo [no final deste tópico](#tutor-spot-net-main) mostra o snippet em uso.

```
    //
    // Method to get information about a Spot Instance request, including the status,
    // instance ID, etc.
    // It gets the information for a specific request (as opposed to all requests).
    private static async Task<SpotInstanceRequest> GetSpotInstanceRequestInfo(
      IAmazonEC2 ec2Client, string requestId)
    {
      var describeRequest = new DescribeSpotInstanceRequestsRequest();
      describeRequest.SpotInstanceRequestIds.Add(requestId);

      DescribeSpotInstanceRequestsResponse describeResponse =
        await ec2Client.DescribeSpotInstanceRequestsAsync(describeRequest);
      return describeResponse.SpotInstanceRequests[0];
    }
```

O método retorna informações sobre a solicitação da instância spot, como o ID da instância, seu estado e o código de status. Para acessar mais informações sobre os códigos de status das solicitações de Instância spot, consulte [Spot request status](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-bid-status.html#spot-instance-bid-status-understand) no [Guia do usuário do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).

## Limpar suas solicitações de instância spot
<a name="tutor-spot-net-clean-up-request"></a>

Quando você não precisar mais solicitar instâncias spot, é importante cancelar todas as solicitações pendentes para evitar que essas solicitações sejam atendidas novamente. O snippet a seguir mostra como cancelar uma solicitação de instância spot.

O exemplo [no final deste tópico](#tutor-spot-net-main) mostra o snippet em uso.

```
    //
    // Method to cancel a Spot Instance request
    private static async Task CancelSpotInstanceRequest(
      IAmazonEC2 ec2Client, string requestId)
    {
      var cancelRequest = new CancelSpotInstanceRequestsRequest();
      cancelRequest.SpotInstanceRequestIds.Add(requestId);

      await ec2Client.CancelSpotInstanceRequestsAsync(cancelRequest);
    }
```

## Limpar as instâncias spot
<a name="tutor-spot-net-clean-up-instance"></a>

Para evitar custos desnecessários, é importante que você encerre todas as instâncias que foram iniciadas a partir de solicitações de instância spot. Apenas cancelar a solicitação de instância spot não encerrará as instâncias, o que significa que você continuará a ser cobrado por elas. O snippet a seguir mostra como encerrar uma instância depois de obter o identificador da instância para uma instância spot ativa.

O exemplo [no final deste tópico](#tutor-spot-net-main) mostra o snippet em uso.

```
    //
    // Method to terminate a Spot Instance
    private static async Task TerminateSpotInstance(
      IAmazonEC2 ec2Client, string requestId)
    {
      var describeRequest = new DescribeSpotInstanceRequestsRequest();
      describeRequest.SpotInstanceRequestIds.Add(requestId);

      // Retrieve the Spot Instance request to check for running instances.
      DescribeSpotInstanceRequestsResponse describeResponse =
        await ec2Client.DescribeSpotInstanceRequestsAsync(describeRequest);

      // If there are any running instances, terminate them
      if(   (describeResponse.SpotInstanceRequests[0].Status.Code
              == "request-canceled-and-instance-running")
         || (describeResponse.SpotInstanceRequests[0].State == SpotInstanceState.Active))
      {
        TerminateInstancesResponse response =
          await ec2Client.TerminateInstancesAsync(new TerminateInstancesRequest{
            InstanceIds = new List<string>(){
              describeResponse.SpotInstanceRequests[0].InstanceId } });
        foreach (InstanceStateChange item in response.TerminatingInstances)
        {
          Console.WriteLine($"\n  Terminated instance: {item.InstanceId}");
          Console.WriteLine($"  Instance state: {item.CurrentState.Name}\n");
        }
      }
    }
```

## Código completo
<a name="tutor-spot-net-main"></a>

O exemplo de código a seguir chama os métodos descritos anteriormente para criar e cancelar uma solicitação de instância spot e encerrar uma instância spot.

### Referências do SDK
<a name="w2aac19c15c17c21c43b5b1"></a>

NuGet pacotes:
+ [AWSSDK.EC2](https://www.nuget.org/packages/AWSSDK.EC2)

Elementos de programação:
+ Namespace [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2.html)

  Classe [Amazon EC2 Client](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TEC2Client.html)

  Classe [InstanceType](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TInstanceType.html)
+ Namespace [Amazon.EC2.model](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/NEC2Model.html)

  Classe [CancelSpotInstanceRequestsRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TCancelSpotInstanceRequestsRequest.html)

  Classe [DescribeSpotInstanceRequestsRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeSpotInstanceRequestsRequest.html)

  Classe [DescribeSpotInstanceRequestsResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TDescribeSpotInstanceRequestsResponse.html)

  Classe [InstanceStateChange](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TInstanceStateChange.html)

  Classe [LaunchSpecification](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TLaunchSpecification.html)

  Classe [RequestSpotInstancesRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TRequestSpotInstancesRequest.html)

  Classe [RequestSpotInstancesResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TRequestSpotInstancesResponse.html)

  Classe [SpotInstanceRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TSpotInstanceRequest.html)

  Classe [TerminateInstancesRequest](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TTerminateInstancesRequest.html)

  Classe [TerminateInstancesResponse](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/EC2/TTerminateInstancesResponse.html)

### O código
<a name="w2aac19c15c17c21c43b7b1"></a>

```
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using Amazon.EC2;
using Amazon.EC2.Model;

namespace EC2SpotInstanceRequests
{
  class Program
  {
    static async Task Main(string[] args)
    {
      // Some default values.
      // These could be made into command-line arguments instead.
      var instanceType = InstanceType.T1Micro;
      string securityGroupName = "default";
      string spotPrice = "0.003";
      int instanceCount = 1;

      // Parse the command line arguments
      if((args.Length != 1) || (!args[0].StartsWith("ami-")))
      {
        Console.WriteLine("\nUsage: EC2SpotInstanceRequests ami");
        Console.WriteLine("  ami: the Amazon Machine Image to use for the Spot Instances.");
        return;
      }

      // Create the Amazon EC2 client.
      var ec2Client = new AmazonEC2Client();

      // Create the Spot Instance request and record its ID
      Console.WriteLine("\nCreating spot instance request...");
      var req = await CreateSpotInstanceRequest(
        ec2Client, args[0], securityGroupName, instanceType, spotPrice, instanceCount);
      string requestId = req.SpotInstanceRequestId;

      // Wait for an EC2 Spot Instance to become active
      Console.WriteLine(
        $"Waiting for Spot Instance request with ID {requestId} to become active...");
      int wait = 1;
      var start = DateTime.Now;
      while(true)
      {
        Console.Write(".");

        // Get and check the status to see if the request has been fulfilled.
        var requestInfo = await GetSpotInstanceRequestInfo(ec2Client, requestId);
        if(requestInfo.Status.Code == "fulfilled")
        {
          Console.WriteLine($"\nSpot Instance request {requestId} " +
            $"has been fulfilled by instance {requestInfo.InstanceId}.\n");
          break;
        }

        // Wait a bit and try again, longer each time (1, 2, 4, ...)
        Thread.Sleep(wait);
        wait = wait * 2;
      }

      // Show the user how long it took to fulfill the Spot Instance request.
      TimeSpan span = DateTime.Now.Subtract(start);
      Console.WriteLine($"That took {span.TotalMilliseconds} milliseconds");

      // Perform actions here as needed.
      // For this example, simply wait for the user to hit a key.
      // That gives them a chance to look at the EC2 console to see
      // the running instance if they want to.
      Console.WriteLine("Press any key to start the cleanup...");
      Console.ReadKey(true);

      // Cancel the request.
      // Do this first to make sure that the request can't be re-fulfilled
      // once the Spot Instance has been terminated.
      Console.WriteLine("Canceling Spot Instance request...");
      await CancelSpotInstanceRequest(ec2Client, requestId);

      // Terminate the Spot Instance that's running.
      Console.WriteLine("Terminating the running Spot Instance...");
      await TerminateSpotInstance(ec2Client, requestId);

      Console.WriteLine("Done. Press any key to exit...");
      Console.ReadKey(true);
    }


    //
    // Method to create a Spot Instance request
    private static async Task<SpotInstanceRequest> CreateSpotInstanceRequest(
      IAmazonEC2 ec2Client, string amiId, string securityGroupName,
      InstanceType instanceType, string spotPrice, int instanceCount)
    {
      var launchSpecification = new LaunchSpecification{
        ImageId = amiId,
        InstanceType = instanceType
      };
      launchSpecification.SecurityGroups.Add(securityGroupName);
      var request = new RequestSpotInstancesRequest{
        SpotPrice = spotPrice,
        InstanceCount = instanceCount,
        LaunchSpecification = launchSpecification
      };

      RequestSpotInstancesResponse result =
        await ec2Client.RequestSpotInstancesAsync(request);
      return result.SpotInstanceRequests[0];
    }


    //
    // Method to get information about a Spot Instance request, including the status,
    // instance ID, etc.
    // It gets the information for a specific request (as opposed to all requests).
    private static async Task<SpotInstanceRequest> GetSpotInstanceRequestInfo(
      IAmazonEC2 ec2Client, string requestId)
    {
      var describeRequest = new DescribeSpotInstanceRequestsRequest();
      describeRequest.SpotInstanceRequestIds.Add(requestId);

      DescribeSpotInstanceRequestsResponse describeResponse =
        await ec2Client.DescribeSpotInstanceRequestsAsync(describeRequest);
      return describeResponse.SpotInstanceRequests[0];
    }


    //
    // Method to cancel a Spot Instance request
    private static async Task CancelSpotInstanceRequest(
      IAmazonEC2 ec2Client, string requestId)
    {
      var cancelRequest = new CancelSpotInstanceRequestsRequest();
      cancelRequest.SpotInstanceRequestIds.Add(requestId);

      await ec2Client.CancelSpotInstanceRequestsAsync(cancelRequest);
    }


    //
    // Method to terminate a Spot Instance
    private static async Task TerminateSpotInstance(
      IAmazonEC2 ec2Client, string requestId)
    {
      var describeRequest = new DescribeSpotInstanceRequestsRequest();
      describeRequest.SpotInstanceRequestIds.Add(requestId);

      // Retrieve the Spot Instance request to check for running instances.
      DescribeSpotInstanceRequestsResponse describeResponse =
        await ec2Client.DescribeSpotInstanceRequestsAsync(describeRequest);

      // If there are any running instances, terminate them
      if(   (describeResponse.SpotInstanceRequests[0].Status.Code
              == "request-canceled-and-instance-running")
         || (describeResponse.SpotInstanceRequests[0].State == SpotInstanceState.Active))
      {
        TerminateInstancesResponse response =
          await ec2Client.TerminateInstancesAsync(new TerminateInstancesRequest{
            InstanceIds = new List<string>(){
              describeResponse.SpotInstanceRequests[0].InstanceId } });
        foreach (InstanceStateChange item in response.TerminatingInstances)
        {
          Console.WriteLine($"\n  Terminated instance: {item.InstanceId}");
          Console.WriteLine($"  Instance state: {item.CurrentState.Name}\n");
        }
      }
    }
  }
}
```

## Considerações adicionais
<a name="tutor-spot-net-additional"></a>
+ Depois de executar o tutorial, é uma boa ideia fazer login no [console do Amazon EC2](https://console.aws.amazon.com/ec2/) para verificar se a [solicitação da Instância Spot](https://console.aws.amazon.com/ec2/home#SpotInstances:) foi cancelada e se a [Instância Spot](https://console.aws.amazon.com/ec2/v2/home#Instances) foi encerrada.