private void FrmMain_Load(object sender, EventArgs e) { List <KeyValuePair <string, string> > lstRegions = Regions.GetRegionList(); tsComboRegion.ComboBox.DataSource = lstRegions; tsComboRegion.ComboBox.DisplayMember = "Value"; tsComboRegion.ComboBox.ValueMember = "Key"; //tsComboRegion.ComboBox.SelectedIndex = 1; tsComboRegion.Enabled = false; tsComboEnv.ComboBox.DataSource = AwsUtilities.AwsCommon.GetEnvironmentList(); tsComboEnv.SelectedIndex = 0; tsComboColor.ComboBox.DataSource = Enum.GetValues(typeof(Model.Color)); tsComboColor.SelectedIndex = 0; MainStatusStrip = toolStripStatusLabel1; var computer = Application.CompanyName; IAMHelper helper = new IAMHelper(); helper.GetCurrentUser(); if (!Utils.IsSuperAdmin()) { infrastructureManagerToolStripMenuItem.Visible = false; greenBlueDeploymentToolStripMenuItem.Visible = false; helpToolStripMenuItem.Visible = false; } }
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]}'"); } } }
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(); }
private static void executeIAM(string[] args, Credentials credentials) { var nArgs = CLIHelper.GetNamedArguments(args); var helper = new IAMHelper(credentials); switch (args[1]) { case "create-policy": { if (!nArgs.ContainsKey("permissions")) { throw new NotSupportedException("permissions parameter was not specified"); } if (!nArgs.ContainsKey("paths")) { throw new NotSupportedException("paths parameter was not specified"); } var paths = nArgs["paths"].Split(',').Where(x => !x.IsNullOrWhitespace()).ToArray(); if (paths.IsNullOrEmpty()) { throw new Exception("At least one path must be specified in the paths parameter."); } var permissions = nArgs["permissions"].Split(',').Where(x => !x.IsNullOrWhitespace()) .ToArray().ToEnum <AWSWrapper.S3.S3Helper.Permissions>(); if (permissions.IsNullOrEmpty()) { throw new Exception("No permissions were found!"); } var result = helper.CreatePolicyS3Async( name: nArgs["name"], paths: paths, permissions: permissions, description: nArgs.FirstOrDefault(x => x.Key == "description").Value ?? $"Admin S3 Access Policy to '{nArgs["paths"].JsonSerialize()}' auto generated by AWSHelper").Result; Console.WriteLine($"SUCCESS, {nArgs["name"]} policy was created for path {nArgs["paths"].JsonSerialize()}, Arn: {result.Arn}."); } ; break; case "delete-policy": { var result = helper.DeletePolicyByNameAsync( name: nArgs["name"]).Result; Console.WriteLine($"SUCCESS, {nArgs["name"]} policy was removed."); } ; break; case "create-role": { if (!nArgs.ContainsKey("policies")) { throw new NotSupportedException("policies parameter was not specified"); } var policies = nArgs["policies"].Split(',').Where(x => !x.IsNullOrWhitespace()).ToArray(); if (policies.IsNullOrEmpty()) { throw new Exception($"No policies were found although flag was present, {nArgs["policies"]}, verify that names are separated by ','"); } var result = helper.CreateRoleWithPoliciesAsync( roleName: nArgs["name"], policies: policies, createInstanceProfile: nArgs.GetValueOrDefault("create-instance-profile").ToBoolOrDefault(false), roleDescription: nArgs.FirstOrDefault(x => x.Key == "description").Value ?? $"Role '{nArgs["name"]}' auto generated by AWSHelper").Result; Console.WriteLine($"SUCCESS, {nArgs["name"]} role was created, Result:\n{result.JsonSerialize(Newtonsoft.Json.Formatting.Indented)}."); } ; break; case "delete-role": { var result = helper.DeleteRoleAsync( roleName: nArgs["name"], detachPolicies: true, deleteInstanceProfiles: nArgs.GetValueOrDefault("delete-instance-profiles").ToBoolOrDefault(false) ).Result; Console.WriteLine($"SUCCESS, {nArgs["name"]} role was removed and all policies detatched."); } ; break; case "help": case "--help": case "-help": case "-h": case "h": HelpPrinter($"{args[0]}", "Amazon Identity and Access Management", ("create-policy", "Accepts params: permissions (',' separated, allowed: Read,Write,Delete,All,<s3-specyfic without 's3:', case sensitive>), name, paths (',' separated), description (optional)"), ("create-role", "Accepts params: name, policies (',' separated), description (optional)"), ("delete-policy", "Accepts params: name"), ("delete-role", "Accepts params: name")); break; default: { Console.WriteLine($"Try '{args[0]} help' to find out list of available commands."); throw new Exception($"Unknown IAM command: '{args[0]} {args[1]}'"); } } }
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); }
private static async Task executeEC2(string[] args, Credentials credentials) { var nArgs = CLIHelper.GetNamedArguments(args); var ec2 = new EC2Helper(); var iam = new IAMHelper(credentials); switch (args[1]) { case "create-instance": { var imageId = nArgs["image"]; var keyName = nArgs["key"]; var instanceType = nArgs["instance-type"].ToEnum <InstanceModel>().ToInstanceType(); var securityGroupId = nArgs["security-group"]; var subnet = nArgs["subnet"]; var role = nArgs["role"]; var shutdownTermination = nArgs.GetValueOrDefault("on-shutdown-termination").ToBoolOrDefault(false); var publicIp = nArgs.GetValueOrDefault("public-ip").ToBoolOrDefault(true); var name = nArgs["name"]; var autoKill = nArgs.GetValueOrDefault("auto-kill").ToIntOrDefault(100 * 365 * 24 * 60); var tt = DateTime.UtcNow.AddMinutes(autoKill); var tt2 = tt.AddMinutes(15); var tags = new System.Collections.Generic.Dictionary <string, string>() { { "Name", name }, { "Auto Kill", $"{tt.Minute}-{tt2.Minute} {tt.Hour}-{tt2.Hour} {tt.Day}-{tt2.Day} {tt.Month}-{tt2.Month} * {tt.Year}-{tt2.Year}" }, }; var cname = nArgs.GetValueOrDefault("cname"); var zones = nArgs.GetValueOrDefault("zones")?.Split(',')?.ToArray(); if (cname != null && zones != null) { for (int i = 0; i < zones.Length; i++) { var suffix = i > 0 ? $" {i + 1}" : ""; tags.Add($"Route53 Enable{suffix}", "true"); tags.Add($"Route53 Name{suffix}", cname); tags.Add($"Route53 Zone{suffix}", zones[i]); } } string instanceId; var ebsOptymalized = nArgs.GetValueOrDefault("ebs-optymalized").ToBoolOrDefault(); if (nArgs.Any(x => x.Key.IsWildcardMatch("ebs-root-"))) { Console.WriteLine("Advanced Instance Creation Initiated..."); var rootDeviceName = nArgs["ebs-root-dev-name"]; var rootSnapshotId = nArgs.GetValueOrDefault("ebs-root-snapshot-id"); var rootVolumeSize = nArgs["ebs-root-volume-size"].ToInt32(); var rootIOPS = nArgs["ebs-root-iops"].ToIntOrDefault(0); var rootVolumeType = nArgs["ebs-root-volume-type"]; instanceId = ec2.CreateInstanceAsync( imageId: imageId, instanceType: instanceType, keyName: keyName, securityGroupIDs: new string[] { securityGroupId }, subnetId: subnet, roleName: role, shutdownBehavior: shutdownTermination ? ShutdownBehavior.Terminate : ShutdownBehavior.Stop, associatePublicIpAddress: publicIp, ebsOptymalized: ebsOptymalized, rootDeviceName: rootDeviceName, rootSnapshotId: rootSnapshotId, rootVolumeSize: rootVolumeSize, rootIOPS: rootIOPS, rootVolumeType: rootVolumeType, tags: tags ).Result.Reservation.Instances.Single().InstanceId; } else { Console.WriteLine("Basic Instance Creation Initiated..."); instanceId = ec2.CreateInstanceAsync( imageId: imageId, instanceType: instanceType, keyName: keyName, securityGroupId: securityGroupId, subnetId: subnet, roleName: role, shutdownBehavior: shutdownTermination ? ShutdownBehavior.Terminate : ShutdownBehavior.Stop, associatePublicIpAddress: publicIp, ebsOptymalized: ebsOptymalized, tags: tags).Result.Reservation.Instances.Single().InstanceId; } if (nArgs.GetValueOrDefault("await-start").ToBoolOrDefault(false)) { var timeout_ms = nArgs.GetValueOrDefault("await-start-timeout").ToIntOrDefault(5 * 60 * 1000); Console.WriteLine($"Awaiting up to {timeout_ms} [ms] for instance '{instanceId}' to start..."); ec2.AwaitInstanceStateCode(instanceId, EC2Helper.InstanceStateCode.running, timeout_ms: timeout_ms).Wait(); } if (nArgs.GetValueOrDefault("await-system-start").ToBoolOrDefault(false)) { var timeout_ms = nArgs.GetValueOrDefault("await-system-start-timeout").ToIntOrDefault(5 * 60 * 1000); Console.WriteLine($"Awaiting up to {timeout_ms} [ms] for instance '{instanceId}' OS to start..."); ec2.AwaitInstanceStatus(instanceId, EC2Helper.InstanceSummaryStatus.Ok, timeout_ms: timeout_ms).Wait(); } Console.WriteLine($"SUCCESS, Instance '{instanceId}' was created."); } ; break; case "terminate-instance": { var name = nArgs.GetValueOrDefault("name"); Instance[] instances = null; if (!name.IsNullOrEmpty()) { instances = ec2.ListInstancesByName(name).Result; Console.WriteLine($"Found {instances?.Length ?? 0} instances with name: '{name}'."); } else { throw new Exception("Not Supported Arguments"); } instances.ParallelForEach(i => { void TryRemoveTags() { if (!nArgs.GetValueOrDefault("try-delete-tags").ToBoolOrDefault(false)) { return; } var err = ec2.DeleteAllInstanceTags(i.InstanceId).CatchExceptionAsync().Result; if (err == null) { Console.WriteLine("Removed instance tags."); } else { Console.WriteLine($"Failed to remove instance tags, Error: {err.JsonSerializeAsPrettyException()}"); } } if (i.State.Code == (int)InstanceStateCode.terminating || i.State.Code == (int)InstanceStateCode.terminated) { Console.WriteLine($"Instance {i.InstanceId} is already terminating or terminated."); TryRemoveTags(); return; } Console.WriteLine($"Terminating {i.InstanceId}..."); var result = ec2.TerminateInstance(i.InstanceId).Result; Console.WriteLine($"Instance {i.InstanceId} state changed {result.PreviousState.Name} -> {result.CurrentState.Name}"); TryRemoveTags(); }); Console.WriteLine($"SUCCESS, All Instances Are Terminated."); } ; break; case "describe-instance": { var name = nArgs.GetValueOrDefault("name"); Instance instance = null; if (name != null) { instance = ec2.ListInstancesByName(name: name).Result .SingleOrDefault(x => (x.State.Name != InstanceStateName.Terminated) && (x.State.Name != InstanceStateName.ShuttingDown)); if (instance == null) { throw new Exception($"No non terminated instance with name '{name}' was found."); } var property = nArgs.GetValueOrDefault("property"); var output = nArgs.GetValueOrDefault("output"); if (!property.IsNullOrEmpty()) { var value = instance.GetType().GetProperty(property).GetValue(instance, null); var strValue = TypeEx.IsSimple(value.GetType().GetTypeInfo()) ? value.ToString() : value.JsonSerialize(Newtonsoft.Json.Formatting.Indented); Console.WriteLine($"Instance '{instance.InstanceId}' Property '{property}', Value: '{strValue}'."); if (!output.IsNullOrEmpty()) { Console.WriteLine($"Saving Property Value into output file: '{output}'..."); output.ToFileInfo().WriteAllText(strValue); } } else { Console.WriteLine($"Instance '{instance.InstanceId}' properties: {instance.JsonSerialize(Newtonsoft.Json.Formatting.Indented)}"); if (!output.IsNullOrEmpty()) { Console.WriteLine($"Saving Properties into output file: '{output}'..."); output.ToFileInfo().WriteAllText(instance.JsonSerialize(Newtonsoft.Json.Formatting.Indented)); } } } else { throw new Exception("Only describe property by name option is available."); } Console.WriteLine($"SUCCESS, instance '{instance.InstanceId}' properties were found."); } ; break; case "help": case "--help": case "-help": case "-h": case "h": HelpPrinter($"{args[0]}", "Amazon Elastic Compute Cloud", ("create-instance", "Accepts params: "), ("terminate-instance", "Accepts params: name")); break; default: { Console.WriteLine($"Try '{args[0]} help' to find out list of available commands."); throw new Exception($"Unknown EC2 command: '{args[0]} {args[1]}'"); } } }