

¡Se AWS SDK para .NET ha publicado la versión 4 (V4) del\$1

Para obtener información sobre los cambios más importantes y la migración de sus aplicaciones, consulte el [tema sobre migración](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html).

 [https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-v4.html)

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Uso de grupos de seguridad en Amazon EC2
<a name="security-groups"></a>

En Amazon EC2, un *grupo de seguridad* funciona como un firewall virtual que controla el tráfico de red de una o varias instancias EC2. De forma predeterminada, EC2 asocia las instancias con un grupo de seguridad que no permite el tráfico entrante. Puede crear un grupo de seguridad que permita a sus instancias EC2 aceptar un tráfico determinado. Por ejemplo, si necesita conectarse a una instancia EC2 Windows, debe configurar el grupo de seguridad para permitir el tráfico RDP.

Para obtener más información sobre los grupos de seguridad, consulte [Grupos de seguridad de Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html) en la [Guía del usuario de Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).

**aviso**  
EC2-Classic se retirará el 15 de agosto de 2022. Le recomendamos que migre de EC2-Classic a una VPC. Para obtener más información, consulte la entrada del 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 obtener información sobre los requisitos APIs y requisitos previos, consulte la sección principal ([Uso de Amazon EC2](ec2-apis-intro.md)).

**Topics**
+ [Enumeración de grupos de seguridad](enumerate-security-groups.md)
+ [Creación de grupos de seguridad](creating-security-group.md)
+ [Actualización de grupos de seguridad](authorize-ingress.md)

# Enumeración de grupos de seguridad
<a name="enumerate-security-groups"></a>

En este ejemplo, se muestra cómo utilizar el para AWS SDK para .NET enumerar los grupos de seguridad. Si proporciona un ID de [Amazon Virtual Private Cloud](https://docs.aws.amazon.com/vpc/latest/userguide/), la aplicación enumera los grupos de seguridad de esa VPC concreta. De lo contrario, la aplicación simplemente muestra una lista de todos los grupos de seguridad disponibles.

En las siguientes secciones se proporcionan fragmentos de código de este ejemplo. Tras ello, se muestra el [código completo del ejemplo](#enum-sec-groups-complete-code), que se puede compilar y ejecutar tal cual.

**Topics**
+ [Enumeración de grupos de seguridad](#enum-sec-groups-enum)
+ [Código completo](#enum-sec-groups-complete-code)
+ [Consideraciones adicionales](#enum-sec-groups-additional)

## Enumeración de grupos de seguridad
<a name="enum-sec-groups-enum"></a>

El siguiente fragmento de código enumera los grupos de seguridad. Enumera todos los grupos, o bien los grupos de una VPC concreta, si se indica alguna.

El ejemplo que aparece [al final de este tema](#enum-sec-groups-complete-code) muestra este fragmento de código en 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>

En esta sección se muestran las referencias relevantes y el código completo de este ejemplo.

### Referencias de SDK
<a name="w2aac19c15c21c13c13c15b5b1"></a>

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

Elementos de programación:
+ Espacio de nombres [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/NEC2.html)

  [EC2Cliente Class Amazon](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/TEC2Client.html)
+ Espacio de nombres [Amazon.EC2.Model](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/NEC2Model.html)

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

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

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

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

### El código
<a name="w2aac19c15c21c13c13c15b7b1"></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();
      }
    }
  }
}
```

## Consideraciones adicionales
<a name="enum-sec-groups-additional"></a>
+ Observe que, en el caso de la VPC, el filtro se crea con la parte `Name` del par nombre-valor establecida en “vpc-id”. Este nombre proviene de la descripción de la `Filters` propiedad de la [DescribeSecurityGroupsRequest](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/TDescribeSecurityGroupsRequest.html)clase.
+ Para obtener la lista completa de sus grupos de seguridad, también puede [ DescribeSecurityGroupsAsync utilizarlos sin parámetros](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/MEC2DescribeSecurityGroupsAsyncCancellationToken.html).
+ Para comprobar los resultados, puede consultar la lista de grupos de seguridad en la [consola de Amazon EC2](https://console.aws.amazon.com/ec2/v2/home#SecurityGroups).

# Creación de grupos de seguridad
<a name="creating-security-group"></a>

En este ejemplo, se muestra cómo utilizar el AWS SDK para .NET para crear un grupo de seguridad. Puede proporcionar el ID de una VPC existente para crear un grupo de seguridad para EC2 en una VPC. Si no proporciona dicho identificador, el nuevo grupo de seguridad será para EC2-Classic si su AWS cuenta lo admite.

Si no proporciona un ID de VPC y su AWS cuenta no es compatible con EC2-Classic, el nuevo grupo de seguridad pertenecerá a la VPC predeterminada de su cuenta.

**aviso**  
EC2-Classic se retirará el 15 de agosto de 2022. Le recomendamos que migre de EC2-Classic a una VPC. Para obtener más información, consulte la entrada del blog [EC2-Classic Networking se retira: cómo prepararse](https://aws.amazon.com/blogs/aws/ec2-classic-is-retiring-heres-how-to-prepare/).

En las siguientes secciones se proporcionan fragmentos de código de este ejemplo. Tras ello, se muestra el [código completo del ejemplo](#create-sec-groups-complete-code), que se puede compilar y ejecutar tal cual.

**Topics**
+ [Búsqueda de grupos de seguridad existentes](#create-sec-groups-find)
+ [Creación de un grupo de seguridad](#create-sec-groups-enum)
+ [Código completo](#create-sec-groups-complete-code)

## Búsqueda de grupos de seguridad existentes
<a name="create-sec-groups-find"></a>

El siguiente fragmento de código busca los grupos de seguridad existentes en la VPC indicada con el nombre especificado.

El ejemplo que aparece [al final de este tema](#create-sec-groups-complete-code) muestra este fragmento de código en 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;
    }
```

## Creación de un grupo de seguridad
<a name="create-sec-groups-enum"></a>

El siguiente fragmento de código crea un grupo de seguridad nuevo si no existe uno con ese nombre en la VPC indicada. Si no se proporciona ninguna VPC y hay uno o más grupos con ese nombre, el fragmento de código simplemente devuelve la lista de grupos.

El ejemplo que aparece [al final de este tema](#create-sec-groups-complete-code) muestra este fragmento de código en 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>

En esta sección se muestran las referencias relevantes y el código completo de este ejemplo.

### Referencias de SDK
<a name="w2aac19c15c21c13c15c23b5b1"></a>

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

Elementos de programación:
+ Espacio de nombres [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/NEC2.html)

  [EC2Cliente Class Amazon](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/TEC2Client.html)
+ Espacio de nombres [Amazon.EC2.Model](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/NEC2Model.html)

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

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

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

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

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

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

### El código
<a name="w2aac19c15c21c13c15c23b7b1"></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);
    }
  }

}
```

# Actualización de grupos de seguridad
<a name="authorize-ingress"></a>

En este ejemplo, se muestra cómo utilizar la AWS SDK para .NET para añadir una regla a un grupo de seguridad. En concreto, el ejemplo agrega una regla para permitir el tráfico entrante en un determinado puerto TCP, que se puede usar, por ejemplo, en las conexiones remotas a una instancia de EC2. La aplicación toma el ID de un grupo de seguridad existente, una dirección IP (o un intervalo de direcciones) en formato CIDR y, opcionalmente, un número de puerto TCP. A continuación, agrega una regla de entrada al grupo de seguridad en cuestión.

**nota**  
Para usar este ejemplo, necesita una dirección IP (o un intervalo de direcciones) en formato CIDR. Consulte la sección **Consideraciones adicionales** al final de este tema para conocer los métodos con los que obtener la dirección IP del equipo local.

En las siguientes secciones se proporcionan fragmentos de código de este ejemplo. Tras ello, se muestra el [código completo del ejemplo](#authorize-ingress-complete-code), que se puede compilar y ejecutar tal cual.

**Topics**
+ [Adición de una regla de entrada](#authorize-ingress-add-rule)
+ [Código completo](#authorize-ingress-complete-code)
+ [Consideraciones adicionales](#authorize-ingress-additional)

## Adición de una regla de entrada
<a name="authorize-ingress-add-rule"></a>

El siguiente fragmento de código agrega una regla de entrada a un grupo de seguridad para una dirección IP (o intervalo de direcciones) y un puerto TCP determinados.

El ejemplo que aparece [al final de este tema](#authorize-ingress-complete-code) muestra este fragmento de código en 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>

En esta sección se muestran las referencias relevantes y el código completo de este ejemplo.

### Referencias de SDK
<a name="w2aac19c15c21c13c17c17b5b1"></a>

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

Elementos de programación:
+ Espacio de nombres [Amazon.EC2](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/NEC2.html)

  [EC2Cliente Class Amazon](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/TEC2Client.html)
+ Espacio de nombres [Amazon.EC2.Model](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/NEC2Model.html)

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

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

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

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

### El código
<a name="w2aac19c15c21c13c17c17b7b1"></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);
    }
  }

}
```

## Consideraciones adicionales
<a name="authorize-ingress-additional"></a>
+ Si no se indica un número de puerto, la aplicación lo establece de forma predeterminada en 3389, que es el puerto de Windows RDP, con el que puede conectarse a una instancia de EC2 donde se ejecute Windows. En cambio, si lanza una instancia de EC2 que ejecuta Linux, utilice el puerto TCP 22 (SSH).
+ Observe que, en el ejemplo, `IpProtocol` está establecido en “tcp”. Los valores de `IpProtocol` se encuentran en la descripción de la `IpProtocol` propiedad de la [IpPermission](https://docs.aws.amazon.com/sdkfornet/v4/apidocs/items/EC2/TIpPermission.html)clase.
+ Es conveniente que tenga la dirección IP de su equipo local cuando utilice este ejemplo. Estas son algunas formas de obtener la dirección.
  + Si el equipo local (desde el que se conectará a la instancia de EC2) tiene una dirección IP pública estática, puede utilizar un servicio para obtener esa dirección. Uno de estos servicios es [http://checkip.amazonaws.com/](http://checkip.amazonaws.com/). Para obtener más información sobre la autorización del tráfico entrante, consulte [Agregar reglas a un grupo de seguridad](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/working-with-security-groups.html#adding-security-group-rule) y [Reglas de grupos de seguridad para diferentes casos de uso](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-rules-reference.html) en la [Guía del usuario de Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/).
  + Otra forma de obtener la dirección IP del equipo local consiste en utilizar la [consola de Amazon EC2](https://console.aws.amazon.com/ec2/v2/home#SecurityGroups).

    Seleccione uno de sus grupos de seguridad, seleccione la pestaña **Reglas de entrada** y, luego, seleccione **Editar reglas de entrada**. En una regla de entrada, abra el menú desplegable de la columna **Origen** y seleccione **Mi IP** para ver la dirección IP de su equipo local en formato CIDR. Asegúrese de **cancelar** la operación.
+ Para comprobar los resultados de este ejemplo, puede examinar la lista de grupos de seguridad en la [consola de Amazon EC2](https://console.aws.amazon.com/ec2/v2/home#SecurityGroups).