private async Task CreateOrUpdateService()

in src/Amazon.ECS.Tools/Commands/DeployServiceCommand.cs [160:292]


        private async Task CreateOrUpdateService(string ecsCluster, string ecsService, string taskDefinitionArn, string ecsContainer)
        {
            try
            { 
                var describeServiceResponse = await this.ECSClient.DescribeServicesAsync(new DescribeServicesRequest
                {
                    Cluster = ecsCluster,
                    Services = new List<string> { ecsService }
                });

                var desiredCount = this.GetIntValueOrDefault(this.DeployServiceProperties.DesiredCount, ECSDefinedCommandOptions.ARGUMENT_ECS_DESIRED_COUNT, false);
                var deploymentMaximumPercent = this.GetIntValueOrDefault(this.DeployServiceProperties.DeploymentMaximumPercent, ECSDefinedCommandOptions.ARGUMENT_DEPLOYMENT_MAXIMUM_PERCENT, false);
                var deploymentMinimumHealthyPercent = this.GetIntValueOrDefault(this.DeployServiceProperties.DeploymentMinimumHealthyPercent, ECSDefinedCommandOptions.ARGUMENT_DEPLOYMENT_MINIMUM_HEALTHY_PERCENT, false);


                var launchType = this.GetStringValueOrDefault(this.ClusterProperties.LaunchType, ECSDefinedCommandOptions.ARGUMENT_LAUNCH_TYPE, true);
                NetworkConfiguration networkConfiguration = null;
                if (IsFargateLaunch(this.ClusterProperties.LaunchType))
                {
                    if (describeServiceResponse.Services.Count != 0)
                        networkConfiguration = describeServiceResponse.Services[0].NetworkConfiguration;
                    else
                    {
                        networkConfiguration = new NetworkConfiguration();
                    }

                    await ECSUtilities.SetupAwsVpcNetworkConfigurationAsync(this, networkConfiguration);
                }

                DeploymentConfiguration deploymentConfiguration = null;
                if (deploymentMaximumPercent.HasValue || deploymentMinimumHealthyPercent.HasValue)
                {
                    deploymentConfiguration = new DeploymentConfiguration();
                    if (deploymentMaximumPercent.HasValue)
                        deploymentConfiguration.MaximumPercent = deploymentMaximumPercent.Value;
                    if (deploymentMinimumHealthyPercent.HasValue)
                        deploymentConfiguration.MinimumHealthyPercent = deploymentMinimumHealthyPercent.Value;
                }

                if (describeServiceResponse.Services.Count == 0 || describeServiceResponse.Services[0].Status == "INACTIVE")
                {
                    this.Logger?.WriteLine($"Creating new service: {ecsService}");
                    var request = new CreateServiceRequest
                    {
                        ClientToken = Guid.NewGuid().ToString(),
                        Cluster = ecsCluster,
                        ServiceName = ecsService,
                        TaskDefinition = taskDefinitionArn,
                        DesiredCount = desiredCount.HasValue ? desiredCount.Value : 1,
                        DeploymentConfiguration = deploymentConfiguration,
                        LaunchType = launchType,
                        NetworkConfiguration = networkConfiguration
                    };

                    if(IsFargateLaunch(this.ClusterProperties.LaunchType))
                    {
                        await this.AttemptToCreateServiceLinkRoleAsync();
                    }
                    else
                    {
                        request.PlacementConstraints = ECSUtilities.ConvertPlacementConstraint(this.GetStringValuesOrDefault(this.DeployServiceProperties.PlacementConstraints, ECSDefinedCommandOptions.ARGUMENT_PLACEMENT_CONSTRAINTS, false));
                        request.PlacementStrategy = ECSUtilities.ConvertPlacementStrategy(this.GetStringValuesOrDefault(this.DeployServiceProperties.PlacementStrategy, ECSDefinedCommandOptions.ARGUMENT_PLACEMENT_STRATEGY, false));
                    }

                    var elbTargetGroup = this.GetStringValueOrDefault(this.DeployServiceProperties.ELBTargetGroup, ECSDefinedCommandOptions.ARGUMENT_ELB_TARGET_GROUP_ARN, false);
                    if (!this.OverrideIgnoreTargetGroup && !string.IsNullOrWhiteSpace(elbTargetGroup))
                    {
                        if(!IsFargateLaunch(this.ClusterProperties.LaunchType))
                        {
                            request.Role = this.GetStringValueOrDefault(this.DeployServiceProperties.ELBServiceRole, ECSDefinedCommandOptions.ARGUMENT_ELB_SERVICE_ROLE, false);
                        }

                        var port = this.GetIntValueOrDefault(this.DeployServiceProperties.ELBContainerPort, ECSDefinedCommandOptions.ARGUMENT_ELB_CONTAINER_PORT, false);
                        if (!port.HasValue)
                            port = 80;
                        request.LoadBalancers.Add(new LoadBalancer
                        {
                            TargetGroupArn = elbTargetGroup,
                            ContainerName = ecsContainer,
                            ContainerPort = port.Value
                        });
                    }

                    try
                    {
                        await this.ECSClient.CreateServiceAsync(request);
                    }
                    catch(Amazon.ECS.Model.InvalidParameterException e)
                    {
                        if (e.Message.StartsWith("The target group") && !string.IsNullOrEmpty(elbTargetGroup) && string.IsNullOrEmpty(this.DeployServiceProperties.ELBTargetGroup))
                        {
                            request.LoadBalancers.Clear();
                            request.Role = null;

                            var defaultFile = string.IsNullOrEmpty(this.ConfigFile) ? ECSToolsDefaults.DEFAULT_FILE_NAME : this.ConfigFile;
                            this.Logger?.WriteLine($"Warning: ELB Target Group ARN specified in config file {defaultFile} does not exist.");
                            await this.ECSClient.CreateServiceAsync(request);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
                else
                {
                    this.Logger?.WriteLine($"Updating new service: {ecsService}");
                    var updateRequest = new UpdateServiceRequest
                    {
                        Cluster = ecsCluster,
                        Service = ecsService,
                        TaskDefinition = taskDefinitionArn,
                        DeploymentConfiguration = deploymentConfiguration,
                        NetworkConfiguration = networkConfiguration
                    };

                    if(desiredCount.HasValue)
                    {
                        updateRequest.DesiredCount = desiredCount.Value;
                    }

                    await this.ECSClient.UpdateServiceAsync(updateRequest);
                }
            }
            catch (DockerToolsException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new DockerToolsException($"Error updating ECS service {ecsService} on cluster {ecsCluster}: {e.Message}", DockerToolsException.ECSErrorCode.FailedToUpdateService);
            }
        }