public static async System.Threading.Tasks.Task SetupAwsVpcNetworkConfigurationCloudwatchEventAsync(
            ECSBaseDeployCommand command, Amazon.CloudWatchEvents.Model.NetworkConfiguration networkConfiguration)
        {
            if (networkConfiguration.AwsvpcConfiguration == null)
            {
                networkConfiguration.AwsvpcConfiguration = new Amazon.CloudWatchEvents.Model.AwsVpcConfiguration();
            }

            string defaultVpcId = null;

            bool noExistingSubnets = networkConfiguration.AwsvpcConfiguration.Subnets.Count == 0;
            var  vpcSubnetWrapper  = await SetupAwsVpcNetworkConfigurationSubnets(command, defaultVpcId, noExistingSubnets);

            var subnets = vpcSubnetWrapper.Subnets;

            defaultVpcId = vpcSubnetWrapper.VpcId;

            if (subnets != null)
            {
                networkConfiguration.AwsvpcConfiguration.Subnets = new List <string>(subnets);
            }

            bool noExistingSecurityGroups = networkConfiguration.AwsvpcConfiguration.SecurityGroups.Count == 0;
            var  securityGroups           = await SetupAwsVpcNetworkConfigurationSecurityGroups(command, defaultVpcId, noExistingSecurityGroups);

            if (securityGroups != null)
            {
                networkConfiguration.AwsvpcConfiguration.SecurityGroups = new List <string>(securityGroups);
            }

            var assignPublicIp = command.GetBoolValueOrDefault(command.ClusterProperties.AssignPublicIpAddress, ECSDefinedCommandOptions.ARGUMENT_LAUNCH_ASSIGN_PUBLIC_IP, false);

            if (assignPublicIp.HasValue)
            {
                networkConfiguration.AwsvpcConfiguration.AssignPublicIp = assignPublicIp.Value ? Amazon.CloudWatchEvents.AssignPublicIp.ENABLED : Amazon.CloudWatchEvents.AssignPublicIp.DISABLED;
            }
            else if (networkConfiguration?.AwsvpcConfiguration?.AssignPublicIp == null)
            {
                // Enable by default if not set to make the common case easier
                networkConfiguration.AwsvpcConfiguration.AssignPublicIp = Amazon.CloudWatchEvents.AssignPublicIp.ENABLED;
                command.Logger?.WriteLine("Enabling \"Assign Public IP\" for tasks");
            }
        }
        private static async Task <string[]> SetupAwsVpcNetworkConfigurationSecurityGroups(ECSBaseDeployCommand command,
                                                                                           string defaultVpcId, bool noExistingSecurityGroups)
        {
            var securityGroups = command.GetStringValuesOrDefault(command.ClusterProperties.SecurityGroupIds, ECSDefinedCommandOptions.ARGUMENT_LAUNCH_SECURITYGROUPS, false);

            if ((securityGroups == null || securityGroups.Length == 0) && noExistingSecurityGroups)
            {
                command.Logger?.WriteLine("No security group specified, looking for default VPC and security group");
                if (defaultVpcId == null)
                {
                    try
                    {
                        var describeVpcResponse = await command.EC2Client.DescribeVpcsAsync();

                        var defaultVpc = describeVpcResponse.Vpcs.FirstOrDefault(x => x.IsDefault);
                        if (defaultVpc != null)
                        {
                            command.Logger?.WriteLine("Default VPC: " + defaultVpc.VpcId);
                            defaultVpcId = defaultVpc.VpcId;
                        }
                        else
                        {
                            command.Logger?.WriteLine("Unable to determine default VPC");
                        }
                    }
                    catch (Exception e)
                    {
                        command.Logger?.WriteLine("Warning: Unable to determine default VPC: " + e.Message);
                    }
                }


                if (defaultVpcId != null)
                {
                    try
                    {
                        var describeSecurityGroupResponse = await command.EC2Client.DescribeSecurityGroupsAsync(new DescribeSecurityGroupsRequest
                        {
                            Filters = new List <Filter> {
                                new Filter {
                                    Name = "vpc-id", Values = new List <string> {
                                        defaultVpcId
                                    }
                                }
                            }
                        });

                        var defaultSecurityGroup = describeSecurityGroupResponse.SecurityGroups.FirstOrDefault(x => string.Equals(x.GroupName, "default", StringComparison.OrdinalIgnoreCase));

                        if (defaultSecurityGroup != null)
                        {
                            securityGroups = new string[] { defaultSecurityGroup.GroupId };
                            command.Logger?.WriteLine("Using default security group " + defaultSecurityGroup.GroupId);
                        }
                        else
                        {
                            command.Logger?.WriteLine("Unable to determine default security group for VPC");
                        }
                    }
                    catch (Exception e)
                    {
                        command.Logger?.WriteLine("Warning: Unable to determine default security group for VPC: " + e.Message);
                    }
                }

                if (securityGroups == null)
                {
                    securityGroups = command.GetStringValuesOrDefault(command.ClusterProperties.SecurityGroupIds, ECSDefinedCommandOptions.ARGUMENT_LAUNCH_SECURITYGROUPS, true);
                }
            }

            return(securityGroups);
        }
        private static async Task <VpcSubnetWrapper> SetupAwsVpcNetworkConfigurationSubnets(ECSBaseDeployCommand command,
                                                                                            string defaultVpcId, bool noExistingSubnets)
        {
            var subnets = command.GetStringValuesOrDefault(command.ClusterProperties.SubnetIds, ECSDefinedCommandOptions.ARGUMENT_LAUNCH_SUBNETS, false);

            if ((subnets == null || subnets.Length == 0) && noExistingSubnets)
            {
                command.Logger?.WriteLine("No subnets specified, looking for default VPC and subnets");
                var defaultSubnets = new List <string>();
                try
                {
                    var describeSubnetResponse = await command.EC2Client.DescribeSubnetsAsync();

                    foreach (var subnet in describeSubnetResponse.Subnets)
                    {
                        if (subnet.DefaultForAz)
                        {
                            if (defaultVpcId == null)
                            {
                                command.Logger?.WriteLine("Default VPC: " + subnet.VpcId);
                                defaultVpcId = subnet.VpcId;
                            }

                            command.Logger?.WriteLine($"... Using subnet {subnet.SubnetId} ({subnet.AvailabilityZone})");
                            defaultSubnets.Add(subnet.SubnetId);
                        }
                    }
                }
                catch (Exception e)
                {
                    command.Logger?.WriteLine("Warning: Unable to determine default subnets for VPC: " + e.Message);
                }

                if (defaultSubnets.Count != 0)
                {
                    subnets = defaultSubnets.ToArray();
                }
                else
                {
                    subnets = command.GetStringValuesOrDefault(command.ClusterProperties.SubnetIds, ECSDefinedCommandOptions.ARGUMENT_LAUNCH_SUBNETS, true);
                }
            }

            return(new VpcSubnetWrapper {
                VpcId = defaultVpcId, Subnets = subnets
            });
        }
        public static async System.Threading.Tasks.Task SetupAwsVpcNetworkConfigurationAsync(ECSBaseDeployCommand command, NetworkConfiguration networkConfiguration)
        {
            if (networkConfiguration.AwsvpcConfiguration == null)
            {
                networkConfiguration.AwsvpcConfiguration = new AwsVpcConfiguration();
            }

            string defaultVpcId = null;
            var    subnets      = command.GetStringValuesOrDefault(command.ClusterProperties.SubnetIds, ECSDefinedCommandOptions.ARGUMENT_LAUNCH_SUBNETS, false);

            bool noExistingSubnets = networkConfiguration == null || networkConfiguration.AwsvpcConfiguration == null || networkConfiguration.AwsvpcConfiguration.Subnets.Count == 0;

            if (subnets == null && noExistingSubnets)
            {
                command.Logger?.WriteLine("No subnets specified, looking for default VPC and subnets");
                var defaultSubnets = new List <string>();
                try
                {
                    var describeSubnetResponse = await command.EC2Client.DescribeSubnetsAsync();

                    foreach (var subnet in describeSubnetResponse.Subnets)
                    {
                        if (subnet.DefaultForAz)
                        {
                            if (defaultVpcId == null)
                            {
                                command.Logger?.WriteLine("Default VPC: " + subnet.VpcId);
                                defaultVpcId = subnet.VpcId;
                            }

                            command.Logger?.WriteLine($"... Using subnet {subnet.SubnetId} ({subnet.AvailabilityZone})");
                            defaultSubnets.Add(subnet.SubnetId);
                        }
                    }
                }
                catch (Exception e)
                {
                    command.Logger?.WriteLine("Warning: Unable to determine default subnets for VPC: " + e.Message);
                }

                if (defaultSubnets.Count != 0)
                {
                    subnets = defaultSubnets.ToArray();
                }
                else
                {
                    subnets = command.GetStringValuesOrDefault(command.ClusterProperties.SubnetIds, ECSDefinedCommandOptions.ARGUMENT_LAUNCH_SUBNETS, true);
                }
            }


            if (subnets != null)
            {
                networkConfiguration.AwsvpcConfiguration.Subnets = new List <string>(subnets);
            }

            var securityGroups = command.GetStringValuesOrDefault(command.ClusterProperties.SecurityGroupIds, ECSDefinedCommandOptions.ARGUMENT_LAUNCH_SECURITYGROUPS, false);

            bool noExistingSecurityGroups = networkConfiguration == null || networkConfiguration.AwsvpcConfiguration == null || networkConfiguration.AwsvpcConfiguration.SecurityGroups.Count == 0;

            if (securityGroups == null && noExistingSecurityGroups)
            {
                command.Logger?.WriteLine("No security group specified, looking for default VPC and security group");
                if (defaultVpcId == null)
                {
                    try
                    {
                        var describeVpcResponse = await command.EC2Client.DescribeVpcsAsync();

                        var defaultVpc = describeVpcResponse.Vpcs.FirstOrDefault(x => x.IsDefault);
                        if (defaultVpc != null)
                        {
                            command.Logger?.WriteLine("Default VPC: " + defaultVpc.VpcId);
                            defaultVpcId = defaultVpc.VpcId;
                        }
                        else
                        {
                            command.Logger?.WriteLine("Unable to determine default VPC");
                        }
                    }
                    catch (Exception e)
                    {
                        command.Logger?.WriteLine("Warning: Unable to determine default VPC: " + e.Message);
                    }
                }


                if (defaultVpcId != null)
                {
                    try
                    {
                        var describeSecurityGroupResponse = await command.EC2Client.DescribeSecurityGroupsAsync(new DescribeSecurityGroupsRequest
                        {
                            Filters = new List <Filter> {
                                new Filter {
                                    Name = "vpc-id", Values = new List <string> {
                                        defaultVpcId
                                    }
                                }
                            }
                        });

                        var defaultSecurityGroup = describeSecurityGroupResponse.SecurityGroups.FirstOrDefault(x => string.Equals(x.GroupName, "default", StringComparison.OrdinalIgnoreCase));

                        if (defaultSecurityGroup != null)
                        {
                            securityGroups = new string[] { defaultSecurityGroup.GroupId };
                            command.Logger?.WriteLine("Using default security group " + defaultSecurityGroup.GroupId);
                        }
                        else
                        {
                            command.Logger?.WriteLine("Unable to determine default security group for VPC");
                        }
                    }
                    catch (Exception e)
                    {
                        command.Logger?.WriteLine("Warning: Unable to determine default security group for VPC: " + e.Message);
                    }
                }

                if (securityGroups == null)
                {
                    securityGroups = command.GetStringValuesOrDefault(command.ClusterProperties.SecurityGroupIds, ECSDefinedCommandOptions.ARGUMENT_LAUNCH_SECURITYGROUPS, true);
                }
            }


            if (securityGroups != null)
            {
                networkConfiguration.AwsvpcConfiguration.SecurityGroups = new List <string>(securityGroups);
            }

            var assignPublicIp = command.GetBoolValueOrDefault(command.ClusterProperties.AssignPublicIpAddress, ECSDefinedCommandOptions.ARGUMENT_LAUNCH_ASSIGN_PUBLIC_IP, false);

            if (assignPublicIp.HasValue)
            {
                networkConfiguration.AwsvpcConfiguration.AssignPublicIp = assignPublicIp.Value ? AssignPublicIp.ENABLED : AssignPublicIp.DISABLED;
            }
            else if (networkConfiguration?.AwsvpcConfiguration?.AssignPublicIp == null)
            {
                // Enable by default if not set to make the common case easier
                networkConfiguration.AwsvpcConfiguration.AssignPublicIp = AssignPublicIp.ENABLED;
                command.Logger?.WriteLine("Enabling \"Assign Public IP\" for tasks");
            }
        }