Example #1
0
        public static void SetRoutes(FargateResourceV2 resource,
                                     FargateResourceV2 resourceNew, ELBHelper elb, Route53Helper r53, CloudWatchHelper cw)
        {
            Console.WriteLine("Fetching DNS Private Record...");
            var newPrivateRecord = r53.GetCNameRecordSet(resourceNew.ZonePrivate, resourceNew.DNSCName, throwIfNotFound: true)
                                   .Result.PrintResponse();

            Console.WriteLine($"Upserting Health Check...");
            var healthCheck = r53.UpsertCloudWatchHealthCheckAsync(
                resource.HealthCheckName,
                alarmName: resourceNew.ELBHealthyMetricAlarmName,
                alarmRegion: resource.Region,
                throwIfNotFound: false,
                insufficientDataHealthStatus: Amazon.Route53.InsufficientDataHealthStatus.Healthy,
                inverted: false
                ).Result.PrintResponse();

            ResourceRecordSet newPublicRecord = null;

            Console.WriteLine("Updating Private Route53 Record Set (PRIMARY)...");
            var t1 = r53.UpsertCNameRecordAsync(resource.ZonePrivate, resource.DNSCName, newPrivateRecord.ResourceRecords.Single().Value, ttl: resourceNew.TTL,
                                                failover: "PRIMARY", setIdentifier: "PRIMARY-PRIVATE", healthCheckId: healthCheck.Id);

            Console.WriteLine("Updating Private Route53 Record Set (SECONDARY)...");
            var t2 = r53.UpsertCNameRecordAsync(resourceNew.ZonePrivate, resource.DNSCName, newPrivateRecord.ResourceRecords.Single().Value, ttl: resourceNew.TTL,
                                                failover: "SECONDARY", setIdentifier: "SECONDARY-PRIVATE");

            if (resourceNew.IsPublic)
            {
                Console.WriteLine("Fetching DNS Public Record...");
                newPublicRecord = r53.GetCNameRecordSet(resourceNew.ZonePublic, resourceNew.DNSCName, throwIfNotFound: resourceNew.IsPublic)
                                  .Result.PrintResponse();

                Console.WriteLine("Updating Public Route53 Record Set (PRIMARY)...");
                var t3 = r53.UpsertCNameRecordAsync(resource.ZonePublic, resource.DNSCName, newPublicRecord.ResourceRecords.Single().Value, ttl: resourceNew.TTL,
                                                    failover: "PRIMARY", setIdentifier: "PRIMARY-PUBLIC", healthCheckId: healthCheck.Id);

                Console.WriteLine("Updating Public Route53 Record Set (SECONDARY)...");
                var t4 = r53.UpsertCNameRecordAsync(resourceNew.ZonePublic, resource.DNSCName, newPublicRecord.ResourceRecords.Single().Value, ttl: resourceNew.TTL,
                                                    failover: "SECONDARY", setIdentifier: "SECONDARY-PUBLIC");

                Task.WhenAll(t1, t3);
                Task.WhenAll(t2, t4);
            }

            t1.Await();
            t2.Await();

            Console.WriteLine($"Awaiting {(resource.TTL + 1) * 2} [s] for DNS route update based on TTL...");
            Thread.Sleep((resource.TTL + 1) * 2 * 1000);

            Console.WriteLine($"Awaiting Health Check Healthy Status...");
            r53.WaitForHealthCheckAsync(name: healthCheck.Id, status: Route53Helper.HealthCheckStatus.Healthy, timeout_s: resource.HealthCheckTimeout).Result.PrintResponse();

            Console.WriteLine($"Ensuring DNS Route53 Resolution into new address after Health Check change...");
            AwaitDnsUpsert(resource, resourceNew, r53, resource.DnsResolveTimeout).PrintResponse();
        }
Example #2
0
        public async Task <List <string> > GetCurrentPublicDnsList()
        {
            var list = await GetAvailableDnsList();

            //var lbHelper = new ALBHelper(GlobalVariables.Enviroment, GlobalVariables.Region, GlobalVariables.Color);
            var lbHelper = new ELBHelper(GlobalVariables.Enviroment, GlobalVariables.Region, GlobalVariables.Color);
            var lbs      = await lbHelper.GetLoadBalancerList();

            string rootDns    = GlobalVariables.EnvironmentAccounts[GlobalVariables.Enviroment].DNS + ".";
            var    dnsHelper  = new Route53Helper(GlobalVariables.Enviroment, GlobalVariables.Region, GlobalVariables.Color);
            string hostZoneId = await dnsHelper.GetHostZoneId();

            var dnsList = await dnsHelper.GetRecorSetValues(hostZoneId, new List <string>() { $"admin.{rootDns}", $"super.{rootDns}" });

            //var dnsList = await dnsHelper.GetRecorSetValues(hostZoneId, new List<string>() { $"admin.{rootDns}", $"api.{rootDns}", $"super.{rootDns}", $"customer.{rootDns}" });
            return(dnsList);
        }
Example #3
0
        public static async Task <MetricAlarm> UpsertAELBMetricAlarmAsync(
            this CloudWatchHelper cwh, ELBHelper elb,
            string name,
            string loadBalancer,
            string targetGroup,
            ELBMetricName metric,
            ComparisonOperator comparisonOperator,
            int treshold,
            Statistic statistic  = null,
            int dataPointToAlarm = 1,
            int evaluationPeriod = 1,
            int requestDelay     = 1000,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var alb = (await elb.GetLoadBalancersByName(loadBalancer, throwIfNotFound: true)).Single();
            var tg  = await elb.GetTargetGroupByName(targetGroup, alb, throwIfNotFound : true);

            var loadBalanceValue = alb.LoadBalancerArn.SplitByLast(':')[1].TrimStartSingle("loadbalancer/");
            var targetGroupValue = tg.TargetGroupArn.SplitByLast(':')[1];
            var stat             = statistic != null ? statistic :
                                   (comparisonOperator == ComparisonOperator.GreaterThanOrEqualToThreshold || comparisonOperator == ComparisonOperator.GreaterThanThreshold)
                ? Statistic.Maximum : Statistic.Minimum;

            var deleteAlarm = await cwh.DeleteMetricAlarmAsync(name, throwIfNotFound : false);

            if (deleteAlarm.HttpStatusCode != System.Net.HttpStatusCode.NotFound)
            {
                await Task.Delay(requestDelay); //lets ensure metric was removed before we push new request
            }
            var mar = await cwh.PutAELBMetricAlarmAsync(
                name, loadBalanceValue, targetGroupValue,
                metric : metric,
                comparisonOperator : comparisonOperator,
                statistic : stat,
                treshold : treshold,
                dataPointToAlarm : dataPointToAlarm,
                evaluationPeriod : evaluationPeriod,
                cancellationToken : cancellationToken);

            await Task.Delay(requestDelay); //lets ensure metric exists before we search for it

            return(await cwh.GetMetricAlarmAsync(name : name, throwIfNotFound : true, cancellationToken : cancellationToken));
        }
Example #4
0
        public async Task <List <DeployDnsModel> > GetAvailableDnsList()
        {
            var availableDnsList = new List <DeployDnsModel>();
            List <SA_LoadBalancer> loadBalancers;
            //For version compatable. When Blue/Green deploy is ready, only ALB is available.
            //Previous comment is very old. I will consider this later

            /*if (isMultipleColorEnvsCreated())
             * {
             *  var helper = new ALBHelper(GlobalVariables.Enviroment, GlobalVariables.Region, GlobalVariables.Color);
             *  loadBalancers = await helper.GetLoadBalancerList();
             * }
             * else
             * {
             *  var helper = new ELBHelper(GlobalVariables.Enviroment, GlobalVariables.Region, GlobalVariables.Color);
             *  loadBalancers = await helper.GetLoadBalancerList();
             * }*/

            var helper = new ELBHelper(GlobalVariables.Enviroment, GlobalVariables.Region, GlobalVariables.Color);

            loadBalancers = await helper.GetLoadBalancerList();

            var applicationList = new List <string>()
            {
                "Admin", "Super"
            };

            //var applicationList = new List<string>() { "Admin", "API", "Super", "Customer" };
            foreach (var application in applicationList)
            {
                var loadBalancer = loadBalancers.Find(o => o.LoadBalancerName.Contains(application));
                var dns          = new DeployDnsModel()
                {
                    Application         = application,
                    LiveEndpoint        = (loadBalancer == null)? "Unknown": loadBalancer.DNSName,
                    MaintenanceEndpoint = GenerateMaintanenceEndpoint(application)
                };
                availableDnsList.Add(dns);
            }
            return(availableDnsList);
        }
Example #5
0
 public Function()
 {
     _EC2 = new EC2Helper();
     _ELB = new ELBHelper();
 }
Example #6
0
        private static void executeFargate(string[] args, Credentials credentials)
        {
            var nArgs = CLIHelper.GetNamedArguments(args);

            var elb = new ELBHelper();
            var r53 = new Route53Helper();
            var ecs = new ECSHelper();
            var cw  = new CloudWatchHelper();
            var kms = new KMSHelper(credentials);
            var iam = new IAMHelper(credentials);
            var acm = new ACMHelper();

            switch (args[1])
            {
            case "create-resources":
            {
                bool catchDisable          = nArgs.GetValueOrDefault("catch-disable", "false").ToBool();
                int  resourceCreateTimeout = nArgs["resource-create-timeout"].ToInt32();

                var resource = new FargateResourceV2(nArgs);

                string prefix_new = "a-";
                string prefix_old = "b-";
                bool   setRoutes  = true;

                Console.WriteLine("Determining Temporary Resource Naming Conventions...");
                var record = r53.GetCNameRecordSet(resource.IsPublic ? resource.ZonePublic : resource.ZonePrivate, resource.DNSCName,
                                                   failover: "PRIMARY",
                                                   throwIfNotFound: false).Result;

                if (record?.ResourceRecords.IsNullOrEmpty() == false)
                {
                    var a_alb = elb.GetLoadBalancersByName(loadBalancerName: $"a-{resource.LoadBalancerName}", throwIfNotFound: false).Result.SingleOrDefault();
                    var b_alb = elb.GetLoadBalancersByName(loadBalancerName: $"b-{resource.LoadBalancerName}", throwIfNotFound: false).Result.SingleOrDefault();

                    if (a_alb != null && record.ResourceRecords.Any(r => r.Value == a_alb.DNSName))
                    {
                        prefix_new = "b-";
                        prefix_old = "a-";
                        setRoutes  = false;
                    }
                    else if (b_alb != null && record.ResourceRecords.Any(r => r.Value == b_alb.DNSName))
                    {
                        prefix_new = "a-";
                        prefix_old = "b-";
                        setRoutes  = false;
                    }
                    else
                    {
                        Console.WriteLine("WARNING!!! Record was present, but could NOT find any associated loadbalancers.");
                    }
                }

                var resourceNew = resource.DeepCopy();
                resourceNew.SetName($"{prefix_new}{resource.Name}");
                resourceNew.SetDNSCName($"{prefix_new}{resource.DNSCName}");

                var resourceOld = resource.DeepCopy();
                resourceOld.SetName($"{prefix_old}{resource.Name}");
                resourceOld.SetDNSCName($"{prefix_old}{resource.DNSCName}");

                Console.WriteLine("Destroying Temporary Resources...");
                FargateResourceHelperV2.Destroy(resourceNew, elb, r53, ecs, cw, kms, iam, throwOnFailure: true, catchDisable: catchDisable).Await();

                try
                {
                    Console.WriteLine("Creating New Resources...");
                    FargateResourceHelperV2.Create(resourceNew, elb, r53, ecs, cw, kms, iam, acm);

                    Console.WriteLine($"Awaiting up to {resourceCreateTimeout} [s] for Tasks Desired Status...");
                    ecs.WaitForServiceToStart(resourceNew.ClusterName, resourceNew.ServiceName, resourceCreateTimeout).Await();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Failed New Resource Deployment with exception: {ex.JsonSerializeAsPrettyException(Formatting.Indented)}");

                    Console.WriteLine("Destroying New Resources...");
                    FargateResourceHelperV2.Destroy(resourceNew, elb, r53, ecs, cw, kms, iam, throwOnFailure: true, catchDisable: catchDisable).Await();

                    throw new Exception("New Resource Deployment Failure", ex);
                }

                if (setRoutes ||
                    record?.HealthCheckId == null ||
                    record.HealthCheckId != r53.GetHealthCheckAsync(resource.HealthCheckName, throwIfNotFound: false).Result?.Id)
                {
                    Console.WriteLine("DNS Route Initialization...");
                    FargateResourceHelperV2.SetRoutes(resource, resourceNew, elb, r53, cw);
                }
                else
                {
                    Console.WriteLine("DNS Route Swap...");
                    FargateResourceHelperV2.SwapRoutes(resource, resourceNew, elb, r53, cw);
                }

                Console.WriteLine("Destroying Old Resources...");
                FargateResourceHelperV2.Destroy(resourceOld, elb, r53, ecs, cw, kms, iam, throwOnFailure: true, catchDisable: catchDisable).Await();
            }
                ; break;

            case "destroy-resources":
            {
                bool catchDisable = nArgs.GetValueOrDefault("catch-disable", "false").ToBool();

                var resource = new FargateResourceV2(nArgs);

                var resourceA = resource.DeepCopy();
                resourceA.SetName($"a-{resource.Name}");
                resourceA.SetDNSCName($"a-{resource.DNSCName}");

                var resourceB = resource.DeepCopy();
                resourceB.SetName($"b-{resource.Name}");
                resourceB.SetDNSCName($"b-{resource.DNSCName}");

                var t0 = FargateResourceHelperV2.Destroy(resource, elb, r53, ecs, cw, kms, iam, throwOnFailure: true, catchDisable: catchDisable);
                var t1 = FargateResourceHelperV2.Destroy(resourceA, elb, r53, ecs, cw, kms, iam, throwOnFailure: true, catchDisable: catchDisable);
                var t2 = FargateResourceHelperV2.Destroy(resourceB, elb, r53, ecs, cw, kms, iam, throwOnFailure: true, catchDisable: catchDisable);

                var result = Task.WhenAll(t0, t1, t2).Result;

                Console.WriteLine($"Destroying Health Check'{resource.ELBHealthyMetricAlarmName}'...");
                r53.DeleteHealthCheckByNameAsync(resource.HealthCheckName, throwIfNotFound: false)
                .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult();
            }
            break;

            case "help":
            case "--help":
            case "-help":
            case "-h":
            case "h":
                HelpPrinter($"{args[0]}", "Amazon Fargate",
                            ("create-service", "Accepts params:"));
                break;

            default:
            {
                Console.WriteLine($"Try '{args[0]} help' to find out list of available commands.");
                throw new Exception($"Unknown Fargate command: '{args[0]} {args[1]}'");
            }
            }
        }
Example #7
0
        public static void Create(
            FargateResourceV2 resource,
            ELBHelper elb, Route53Helper e53, ECSHelper ecs, CloudWatchHelper cw, KMSHelper kms, IAMHelper iam, ACMHelper acm)
        {
            var errList = new List <Exception>();

            Console.WriteLine("Crating S3 Access Policy...");
            var policyS3 = iam.CreatePolicyS3Async(
                name: resource.PolicyNameAccessS3,
                paths: resource.PathsS3,
                permissions: resource.PermissionsS3,
                description: $"S3 Access Policy '{resource.PolicyNameAccessS3}' to '{resource.PathsS3.JsonSerialize()}' auto generated by AWSHelper").Result.PrintResponse();

            Console.WriteLine($"Crating Execution Role '{resource.RoleName}'...");
            var roleEcs = iam.CreateRoleWithPoliciesAsync(
                roleName: resource.RoleName,
                policies: new string[] { resource.ExecutionPolicy, resource.PolicyNameAccessS3 },
                roleDescription: $"Role '{resource.RoleName}' auto generated by AWSHelper").Result.PrintResponse();

            Console.WriteLine($"Awaiting {resource.RoleCreateAwaitDelay / 1000} [s] to ensure that role was indexed...");
            Thread.Sleep(resource.RoleCreateAwaitDelay);

            Console.WriteLine($"Crating Default S3 Storage Grant '{resource.StorageGrantDefaultS3}' created for role '{resource.RoleName}'...");
            var defaultGrantResult = kms.CreateRoleGrantByName(
                keyName: resource.StorageKeyDefaultS3,
                grantName: resource.StorageGrantDefaultS3,
                roleName: resource.RoleName,
                grant: KMSHelper.GrantType.EncryptDecrypt).Result.PrintResponse();

            Console.WriteLine($"Crating Internal S3 Storage Grant '{resource.StorageGrantInternalS3}' created for role '{resource.RoleName}'...");
            var internalGrantResult = kms.CreateRoleGrantByName(
                keyName: resource.StorageKeyInternalS3,
                grantName: resource.StorageGrantInternalS3,
                roleName: resource.RoleName,
                grant: KMSHelper.GrantType.EncryptDecrypt).Result.PrintResponse();

            Console.WriteLine("Crating Application Load Balancer...");
            var loadBalancer = elb.CreateApplicationLoadBalancerAsync(resource.LoadBalancerName, resource.Subnets, resource.SecurityGroups, !resource.IsPublic).Result.PrintResponse();

            Console.WriteLine("Retriving Certificate...");
            var cert = acm.DescribeCertificateByDomainName(resource.CertificateDomainName).Result.PrintResponse();

            Console.WriteLine("Creating HTTP Target Group...");
            var targetGroup_http = elb.CreateHttpTargetGroupAsync(resource.TargetGroupName, resource.Port, resource.VPC, resource.HealthCheckPath).Result.PrintResponse();

            Console.WriteLine("Creating HTTPS Listener...");
            var listener_https = elb.CreateHttpsListenerAsync(loadBalancer.LoadBalancerArn, targetGroup_http.TargetGroupArn, certificateArn: cert.CertificateArn).Result.PrintResponse();

            Console.WriteLine("Creating HTTP Listener...");
            var listener_http = elb.CreateHttpListenerAsync(loadBalancer.LoadBalancerArn, targetGroup_http.TargetGroupArn, resource.Port).Result.PrintResponse();

            if (resource.IsPublic && !resource.ZonePublic.IsNullOrWhitespace())
            {
                Console.WriteLine("Creating Route53 DNS Record for the public zone...");
                e53.UpsertCNameRecordAsync(
                    resource.ZonePublic,
                    name: resource.DNSCName,
                    value: loadBalancer.DNSName,
                    ttl: 60).Await();
            }

            if (!resource.ZonePrivate.IsNullOrWhitespace())
            {
                Console.WriteLine("Creating Route53 DNS Record for the private zone...");
                e53.UpsertCNameRecordAsync(
                    resource.ZonePrivate,
                    name: resource.DNSCName,
                    value: loadBalancer.DNSName,
                    ttl: 60).Await();
            }

            Console.WriteLine("Initializeing Cluster...");
            var createClusterResponse = ecs.CreateClusterAsync(resource.ClusterName).Result.PrintResponse();

            Console.WriteLine("Creating Log Group...");
            cw.CreateLogGroupAsync(resource.LogGroupName).Await();

            Console.WriteLine("Creating Task Definitions...");
            var taskDefinition = ecs.RegisterFargateTaskAsync(
                executionRoleArn: resource.RoleName,
                family: resource.TaskFamily,
                cpu: resource.CPU,
                memory: resource.Memory,
                name: resource.TaskDefinitionName,
                image: resource.Image,
                envVariables: resource.Environment,
                logGroup: resource.LogGroupName,
                ports: resource.Ports).Result.PrintResponse();

            Console.WriteLine("Creating Service...");
            var service = ecs.CreateFargateServiceAsync(
                name: resource.ServiceName,
                taskDefinition: taskDefinition,
                desiredCount: resource.DesiredCount,
                cluster: resource.ClusterName,
                targetGroup: targetGroup_http,
                assignPublicIP: resource.IsPublic,
                securityGroups: resource.SecurityGroups,
                subnets: resource.Subnets
                ).Result.PrintResponse();

            Console.WriteLine($"Creating Cloud Watch Metric '{resource.ELBHealthyMetricAlarmName}'...");
            var metricAlarm = cw.UpsertAELBMetricAlarmAsync(elb,
                                                            name: resource.ELBHealthyMetricAlarmName,
                                                            loadBalancer: resource.LoadBalancerName, targetGroup: resource.TargetGroupName,
                                                            metric: CloudWatchHelper.ELBMetricName.HealthyHostCount,
                                                            comparisonOperator: Amazon.CloudWatch.ComparisonOperator.LessThanThreshold,
                                                            treshold: 1).Result.PrintResponse();
        }
Example #8
0
        public static void SwapRoutes(FargateResourceV2 resource,
                                      FargateResourceV2 resourceNew, ELBHelper elb, Route53Helper r53, CloudWatchHelper cw)
        {
            Console.WriteLine("Fetching DNS Private Record...");
            var newPrivateRecord = r53.GetCNameRecordSet(resourceNew.ZonePrivate, resourceNew.DNSCName, throwIfNotFound: true)
                                   .Result.PrintResponse();

            ResourceRecordSet newPublicRecord = null;

            Console.WriteLine("Updating Private Route53 Record Set (SECONDARY)...");
            r53.UpsertCNameRecordAsync(resourceNew.ZonePrivate, resource.DNSCName, newPrivateRecord.ResourceRecords.Single().Value, ttl: resourceNew.TTL,
                                       failover: "SECONDARY", setIdentifier: "SECONDARY-PRIVATE").Result.PrintResponse();

            if (resourceNew.IsPublic)
            {
                Console.WriteLine("Fetching DNS Public Record...");
                newPublicRecord = r53.GetCNameRecordSet(resourceNew.ZonePublic, resourceNew.DNSCName, throwIfNotFound: resourceNew.IsPublic)
                                  .Result.PrintResponse();

                Console.WriteLine("Updating Public Route53 Record Set (SECONDARY)...");
                r53.UpsertCNameRecordAsync(resourceNew.ZonePublic, resource.DNSCName, newPublicRecord.ResourceRecords.Single().Value, ttl: resourceNew.TTL,
                                           failover: "SECONDARY", setIdentifier: "SECONDARY-PUBLIC").Result.PrintResponse();
            }

            var recordsExist              = false;
            ResourceRecordSet rrsPrivate  = null;
            ResourceRecordSet rrsPublic   = null;
            HealthCheck       healthCheck = null;

            Console.WriteLine($"Veryfying PRIMARY Record and Health Check...");
            if ((rrsPrivate = r53.GetCNameRecordSet(resource.ZonePrivate, resource.DNSCName, failover: "PRIMARY", throwIfNotFound: false).Result) != null &&
                (healthCheck = r53.GetHealthCheckAsync(rrsPrivate.HealthCheckId, throwIfNotFound: false).Result) != null)
            {
                if (resource.IsPublic &&
                    (rrsPublic = r53.GetCNameRecordSet(resource.ZonePublic, resource.DNSCName, failover: "PRIMARY", throwIfNotFound: false).Result) != null &&
                    rrsPublic.HealthCheckId == healthCheck.Id)
                {
                    recordsExist = true;
                }
                else
                {
                    recordsExist = true;
                }
            }
            Console.WriteLine($"DNS PRIMARY Record and Health Check were {(recordsExist ? "" : "NOT ")}present.");

            Console.WriteLine($"Awaiting Desired State of the Cloud Watch Metric Alarm '{resourceNew.ELBHealthyMetricAlarmName}'...");
            cw.WaitForMetricState(resourceNew.ELBHealthyMetricAlarmName, Amazon.CloudWatch.StateValue.OK, resource.HealthCheckTimeout)
            .Result.PrintResponse();

            Console.WriteLine($"Upserting Health Check...");
            healthCheck = r53.UpsertCloudWatchHealthCheckAsync(
                healthCheck?.Id ?? resource.HealthCheckName,
                alarmName: resourceNew.ELBHealthyMetricAlarmName,
                alarmRegion: resource.Region,
                throwIfNotFound: false,
                insufficientDataHealthStatus: Amazon.Route53.InsufficientDataHealthStatus.Healthy,
                inverted: true //OK as long as old health check is failed
                ).Result.PrintResponse();

            if (recordsExist)
            {
                Console.WriteLine($"Awaiting Health Check Unhealthy Status...");
                r53.WaitForHealthCheckAsync(name: healthCheck.Id, status: Route53Helper.HealthCheckStatus.Unhealthy, timeout_s: resource.HealthCheckTimeout)
                .Result.PrintResponse();

                Console.WriteLine($"Awaiting DNS Route53 Resolution into new address...");
                AwaitDnsUpsert(resource, resourceNew, r53, resource.DnsResolveTimeout).PrintResponse();

                Console.WriteLine($"Awaiting {(resource.TTL + 1) * 2} [s] for DNS route update based on TTL...");
                Thread.Sleep((resource.TTL + 1) * 2 * 1000);
            }

            Console.WriteLine("Updating Private Route53 Record Set (PRIMARY)...");
            r53.UpsertCNameRecordAsync(resource.ZonePrivate, resource.DNSCName, newPrivateRecord.ResourceRecords.Single().Value, ttl: resourceNew.TTL,
                                       failover: "PRIMARY", setIdentifier: "PRIMARY-PRIVATE", healthCheckId: healthCheck.Id).Result.PrintResponse();

            if (resource.IsPublic)
            {
                Console.WriteLine("Updating Public Route53 Record Set (PRIMARY)...");
                r53.UpsertCNameRecordAsync(resource.ZonePublic, resource.DNSCName, newPublicRecord.ResourceRecords.Single().Value, ttl: resourceNew.TTL,
                                           failover: "PRIMARY", setIdentifier: "PRIMARY-PUBLIC", healthCheckId: healthCheck.Id).Result.PrintResponse();
            }

            Console.WriteLine($"Awaiting {resourceNew.DnsUpdateDelay} [ms] for PRIMARY DNS Record update...");
            Thread.Sleep(resourceNew.DnsUpdateDelay);

            Console.WriteLine($"Upserting Health Check...");
            healthCheck = r53.UpsertCloudWatchHealthCheckAsync(
                healthCheck?.Id,
                alarmName: resourceNew.ELBHealthyMetricAlarmName,
                alarmRegion: resource.Region,
                throwIfNotFound: false,
                insufficientDataHealthStatus: Amazon.Route53.InsufficientDataHealthStatus.Unhealthy,
                inverted: false
                ).Result.PrintResponse();

            Console.WriteLine($"Awaiting Health Check Healthy Status...");
            r53.WaitForHealthCheckAsync(name: healthCheck.Id, status: Route53Helper.HealthCheckStatus.Healthy, timeout_s: 240).Result.PrintResponse();

            Console.WriteLine($"Awaiting {(resource.TTL+1)*2} [s] for DNS route update based on TTL...");
            Thread.Sleep((resource.TTL + 1) * 2 * 1000);

            Console.WriteLine($"Ensuring DNS Route53 Resolution into new address after Health Check change...");
            AwaitDnsUpsert(resource, resourceNew, r53, resource.DnsResolveTimeout).PrintResponse();
        }
Example #9
0
        public static async Task <List <Exception> > Destroy(
            FargateResourceV2 resource,
            ELBHelper elb, Route53Helper e53, ECSHelper ecs, CloudWatchHelper cw, KMSHelper kms, IAMHelper iam,
            bool throwOnFailure,
            bool catchDisable)
        {
            var errList    = new List <Exception>();
            int maxRepeats = throwOnFailure ? 1 : 3;
            int delay_ms   = throwOnFailure ? 500 : 10000;

            Console.WriteLine($"Destroying Role '{resource.RoleName}'...");
            (await iam.DeleteRoleAsync(resource.RoleName, detachPolicies: true)
             .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms).CatchExceptionAsync()).PrintResult();

            Console.WriteLine($"Destroying Policy '{resource.PolicyNameAccessS3}'...");
            errList.Add(iam.DeletePolicyByNameAsync(resource.PolicyNameAccessS3, throwIfNotFound: false)
                        .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms)
                        .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult());

            Console.WriteLine($"Destroying Default Grant '{resource.StorageGrantDefaultS3}' for key '{resource.StorageKeyDefaultS3}'...");
            errList.Add(kms.RemoveGrantsByName(keyName: resource.StorageKeyDefaultS3, grantName: resource.StorageGrantDefaultS3, throwIfNotFound: false)
                        .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms)
                        .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult());

            Console.WriteLine($"Destroying Internal Grant '{resource.StorageGrantInternalS3}' for key '{resource.StorageKeyInternalS3}'...");
            errList.Add(kms.RemoveGrantsByName(keyName: resource.StorageKeyInternalS3, grantName: resource.StorageGrantInternalS3, throwIfNotFound: false)
                        .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms)
                        .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult());

            Console.WriteLine($"Destroying Application Load Balancer '{resource.LoadBalancerName}'...");
            errList.Add(elb.DestroyLoadBalancer(loadBalancerName: resource.LoadBalancerName, throwIfNotFound: false)
                        .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms)
                        .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult());

            if (resource.IsPublic && !resource.ZonePublic.IsNullOrWhitespace())
            {
                Console.WriteLine($"Destroying Route53 DNS Record: '{resource.DNSCName}' of '{resource.ZonePublic}' zone...");
                errList.Add(e53.DestroyCNameRecord(resource.ZonePublic, resource.DNSCName, throwIfNotFound: false)
                            .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms)
                            .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult());
            }

            if (!resource.ZonePrivate.IsNullOrWhitespace())
            {
                Console.WriteLine($"Destroying Route53 DNS Record: '{resource.DNSCName}' of '{resource.ZonePrivate}' zone...");
                errList.Add(e53.DestroyCNameRecord(resource.ZonePrivate, resource.DNSCName, throwIfNotFound: false)
                            .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms)
                            .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult());
            }

            Console.WriteLine($"Destroying Log Group '{resource.LogGroupName}'...");
            errList.Add(cw.DeleteLogGroupAsync(resource.LogGroupName, throwIfNotFound: false)
                        .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms)
                        .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult());

            Console.WriteLine($"Destroying Task Definitions of Family'{resource.TaskFamily}'...");
            errList.Add(ecs.DestroyTaskDefinitions(familyPrefix: resource.TaskFamily)
                        .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms)
                        .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult());

            Console.WriteLine($"Destroying Service '{resource.ServiceName}'...");
            errList.Add(ecs.DestroyService(cluster: resource.ClusterName, serviceName: resource.ServiceName, throwIfNotFound: false)
                        .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms)
                        .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult());

            Console.WriteLine($"Destroying Cluster '{resource.ClusterName}'...");
            errList.Add(ecs.DeleteClusterAsync(name: resource.ClusterName, throwIfNotFound: false)
                        .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms)
                        .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult());

            Console.WriteLine($"Destroying Metric Alarm '{resource.ELBHealthyMetricAlarmName}'...");
            errList.Add(cw.DeleteMetricAlarmAsync(resource.ELBHealthyMetricAlarmName, throwIfNotFound: false)
                        .TryCatchRetryAsync(maxRepeats: maxRepeats, delay: delay_ms)
                        .CatchExceptionAsync(catchDisable: catchDisable).Result.PrintResult());

            if (throwOnFailure && errList.Any(x => x != null))
            {
                throw new AggregateException("Failed Fargate Resource Destruction", errList.ToArray());
            }

            return(errList);
        }
Example #10
0
        private static void executeELB(string[] args)
        {
            var nArgs = CLIHelper.GetNamedArguments(args);

            var elb = new ELBHelper();
            var ec2 = new EC2Helper();

            switch (args[1])
            {
            case "destroy-load-balancer":
                elb.DestroyLoadBalancer(nArgs["name"], throwIfNotFound: true).Wait();
                ; break;

            case "register-target-instance":
            {
                var tgName       = nArgs["tg-name"];
                var instanceName = nArgs["instance"];
                var port         = nArgs["port"].ToInt32();
                var tg           = elb.GetTargetGroupByNameAsync(
                    targetGroupName: tgName,
                    throwIfNotFound: true).Result;

                var instance = ec2.ListInstancesByName(name: instanceName,
                                                       stateExclude: new List <Amazon.EC2.InstanceStateName>()
                    {
                        Amazon.EC2.InstanceStateName.ShuttingDown,
                        Amazon.EC2.InstanceStateName.Terminated
                    }
                                                       ).Result.SingleOrDefault();

                if (instance == null)
                {
                    throw new Exception($"Could not find instance with name '{instanceName}' or found more then one.");
                }

                var result = elb.RegisterTargetAsync(tg, instance, port: port).Result;

                Console.WriteLine($"Successfully Registered Instance '{instance.InstanceId}' into Target Group '{tg.TargetGroupArn}', response metadata: {result.ResponseMetadata?.JsonSerialize() ?? "undefined"}");
            }
                ; break;

            case "deregister-target-instance":
            {
                var tgName       = nArgs["tg-name"];
                var instanceName = nArgs["instance"];
                var tg           = elb.GetTargetGroupByNameAsync(
                    targetGroupName: tgName,
                    throwIfNotFound: true).Result;

                var instance = ec2.ListInstancesByName(name: instanceName,
                                                       stateExclude: new List <Amazon.EC2.InstanceStateName>()
                    {
                        Amazon.EC2.InstanceStateName.ShuttingDown,
                        Amazon.EC2.InstanceStateName.Terminated
                    }
                                                       ).Result.SingleOrDefault();

                if (instance == null)
                {
                    throw new Exception($"Could not find instance with name '{instanceName}' or found more then one.");
                }

                var result = elb.DeregisterTargetAsync(tg, instance).Result;

                Console.WriteLine($"Successfully Deregistered Instance '{instance.InstanceId}' from Target Group '{tg.TargetGroupArn}', response metadata: {result.ResponseMetadata?.JsonSerialize() ?? "undefined"}");
            }
                ; break;

            case "help":
            case "--help":
            case "-help":
            case "-h":
            case "h":
                HelpPrinter($"{args[0]}", "Amazon Elastic Load Balancer",
                            ("destroy-load-balancer", "Accepts params: name"),
                            ("register-target-instance", "Accepts params: tg-name, instance, port"),
                            ("deregister-target-instance", "Accepts params: tg-name, instance"));
                break;

            default: throw new Exception($"Unknown ELB command: '{args[1]}'");
            }
        }