AWS SDK を使用して Auto Scaling グループとインスタンスを管理する - AWS SDK コードの例

Doc AWS SDK Examples リポジトリには、他にも SDK の例があります。 AWS GitHub

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

AWS SDK を使用して Auto Scaling グループとインスタンスを管理する

次のコード例は、以下を実行する方法を示しています。

  • 起動テンプレートとアベイラビリティーゾーンを使用して、Amazon EC2 Auto Scaling グループを作成し、実行中のインスタンスに関する情報を取得します。

  • Amazon CloudWatch メトリクスの収集を有効にします。

  • グループの希望するキャパシティを更新し、インスタンスが起動するのを待ちます。

  • グループ内の最も古いインスタンスを削除します。

  • ユーザーのリクエストやキャパシティの変更に応じて発生するスケーリングアクティビティを一覧表示します。

  • CloudWatch メトリクスの統計を取得してから、リソースをクリーンアップします。

.NET
AWS SDK for .NET
注記

については、「」を参照してください GitHub。AWS コード例リポジトリ で全く同じ例を見つけて、設定と実行の方法を確認してください。

global using Amazon.AutoScaling; global using Amazon.AutoScaling.Model; global using Amazon.CloudWatch; global using AutoScalingActions; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.Hosting; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Logging.Console; global using Microsoft.Extensions.Logging.Debug; using Amazon.EC2; using Microsoft.Extensions.Configuration; using Host = Microsoft.Extensions.Hosting.Host; namespace AutoScalingBasics; public class AutoScalingBasics { static async Task Main(string[] args) { // Set up dependency injection for Amazon EC2 Auto Scaling, Amazon // CloudWatch, and Amazon EC2. using var host = Host.CreateDefaultBuilder(args) .ConfigureLogging(logging => logging.AddFilter("System", LogLevel.Debug) .AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) .AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace)) .ConfigureServices((_, services) => services.AddAWSService<IAmazonAutoScaling>() .AddAWSService<IAmazonCloudWatch>() .AddAWSService<IAmazonEC2>() .AddTransient<AutoScalingWrapper>() .AddTransient<CloudWatchWrapper>() .AddTransient<EC2Wrapper>() .AddTransient<UIWrapper>() ) .Build(); var autoScalingWrapper = host.Services.GetRequiredService<AutoScalingWrapper>(); var cloudWatchWrapper = host.Services.GetRequiredService<CloudWatchWrapper>(); var ec2Wrapper = host.Services.GetRequiredService<EC2Wrapper>(); var uiWrapper = host.Services.GetRequiredService<UIWrapper>(); var configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("settings.json") // Load test settings from .json file. .AddJsonFile("settings.local.json", true) // Optionally load local settings. .Build(); var imageId = configuration["ImageId"]; var instanceType = configuration["InstanceType"]; var launchTemplateName = configuration["LaunchTemplateName"]; launchTemplateName += Guid.NewGuid().ToString(); // The name of the Auto Scaling group. var groupName = configuration["GroupName"]; uiWrapper.DisplayTitle("Auto Scaling Basics"); uiWrapper.DisplayAutoScalingBasicsDescription(); // Create the launch template and save the template Id to use when deleting the // launch template at the end of the application. var launchTemplateId = await ec2Wrapper.CreateLaunchTemplateAsync(imageId!, instanceType!, launchTemplateName); // Confirm that the template was created by asking for a description of it. await ec2Wrapper.DescribeLaunchTemplateAsync(launchTemplateName); uiWrapper.PressEnter(); var availabilityZones = await ec2Wrapper.ListAvailabilityZonesAsync(); Console.WriteLine($"Creating an Auto Scaling group named {groupName}."); await autoScalingWrapper.CreateAutoScalingGroupAsync( groupName!, launchTemplateName, availabilityZones.First().ZoneName); // Keep checking the details of the new group until its lifecycle state // is "InService". Console.WriteLine($"Waiting for the Auto Scaling group to be active."); List<AutoScalingInstanceDetails> instanceDetails; do { instanceDetails = await autoScalingWrapper.DescribeAutoScalingInstancesAsync(groupName!); } while (instanceDetails.Count <= 0); Console.WriteLine($"Auto scaling group {groupName} successfully created."); Console.WriteLine($"{instanceDetails.Count} instances were created for the group."); // Display the details of the Auto Scaling group. instanceDetails.ForEach(detail => { Console.WriteLine($"Group name: {detail.AutoScalingGroupName}"); }); uiWrapper.PressEnter(); uiWrapper.DisplayTitle("Metrics collection"); Console.WriteLine($"Enable metrics collection for {groupName}"); await autoScalingWrapper.EnableMetricsCollectionAsync(groupName!); // Show the metrics that are collected for the group. // Update the maximum size of the group to three instances. Console.WriteLine("--- Update the Auto Scaling group to increase max size to 3 ---"); int maxSize = 3; await autoScalingWrapper.UpdateAutoScalingGroupAsync(groupName!, launchTemplateName, maxSize); Console.WriteLine("--- Describe all Auto Scaling groups to show the current state of the group ---"); var groups = await autoScalingWrapper.DescribeAutoScalingGroupsAsync(groupName!); uiWrapper.DisplayGroupDetails(groups!); uiWrapper.PressEnter(); uiWrapper.DisplayTitle("Describe account limits"); await autoScalingWrapper.DescribeAccountLimitsAsync(); uiWrapper.WaitABit(60, "Waiting for the resources to be ready."); uiWrapper.DisplayTitle("Set desired capacity"); int desiredCapacity = 2; await autoScalingWrapper.SetDesiredCapacityAsync(groupName!, desiredCapacity); Console.WriteLine("Get the two instance Id values"); // Empty the group before getting the details again. groups!.Clear(); groups = await autoScalingWrapper.DescribeAutoScalingGroupsAsync(groupName!); if (groups is not null) { foreach (AutoScalingGroup group in groups) { Console.WriteLine($"The group name is {group.AutoScalingGroupName}"); Console.WriteLine($"The group ARN is {group.AutoScalingGroupARN}"); var instances = group.Instances; foreach (Amazon.AutoScaling.Model.Instance instance in instances) { Console.WriteLine($"The instance id is {instance.InstanceId}"); Console.WriteLine($"The lifecycle state is {instance.LifecycleState}"); } } } uiWrapper.DisplayTitle("Scaling Activities"); Console.WriteLine("Let's list the scaling activities that have occurred for the group."); var activities = await autoScalingWrapper.DescribeScalingActivitiesAsync(groupName!); if (activities is not null) { activities.ForEach(activity => { Console.WriteLine($"The activity Id is {activity.ActivityId}"); Console.WriteLine($"The activity details are {activity.Details}"); }); } // Display the Amazon CloudWatch metrics that have been collected. var metrics = await cloudWatchWrapper.GetCloudWatchMetricsAsync(groupName!); Console.WriteLine($"Metrics collected for {groupName}:"); metrics.ForEach(metric => { Console.Write($"Metric name: {metric.MetricName}\t"); Console.WriteLine($"Namespace: {metric.Namespace}"); }); var dataPoints = await cloudWatchWrapper.GetMetricStatisticsAsync(groupName!); Console.WriteLine("Details for the metrics collected:"); dataPoints.ForEach(detail => { Console.WriteLine(detail); }); // Disable metrics collection. Console.WriteLine("Disabling the collection of metrics for {groupName}."); var success = await autoScalingWrapper.DisableMetricsCollectionAsync(groupName!); if (success) { Console.WriteLine($"Successfully stopped metrics collection for {groupName}."); } else { Console.WriteLine($"Could not stop metrics collection for {groupName}."); } // Terminate all instances in the group. uiWrapper.DisplayTitle("Terminating Auto Scaling instances"); Console.WriteLine("Now terminating all instances in the Auto Scaling group."); if (groups is not null) { groups.ForEach(group => { // Only delete instances in the AutoScaling group we created. if (group.AutoScalingGroupName == groupName) { group.Instances.ForEach(async instance => { await autoScalingWrapper.TerminateInstanceInAutoScalingGroupAsync(instance.InstanceId); }); } }); } // After all instances are terminated, delete the group. uiWrapper.DisplayTitle("Clean up resources"); Console.WriteLine("Deleting the Auto Scaling group."); await autoScalingWrapper.DeleteAutoScalingGroupAsync(groupName!); // Delete the launch template. var deletedLaunchTemplateName = await ec2Wrapper.DeleteLaunchTemplateAsync(launchTemplateId); if (deletedLaunchTemplateName == launchTemplateName) { Console.WriteLine("Successfully deleted the launch template."); } Console.WriteLine("The demo is now concluded."); } } namespace AutoScalingBasics; /// <summary> /// A class to provide user interface methods for the EC2 AutoScaling Basics /// scenario. /// </summary> public class UIWrapper { public readonly string SepBar = new('-', Console.WindowWidth); /// <summary> /// Describe the steps in the EC2 AutoScaling Basics scenario. /// </summary> public void DisplayAutoScalingBasicsDescription() { Console.WriteLine("This code example performs the following operations:"); Console.WriteLine(" 1. Creates an Amazon EC2 launch template."); Console.WriteLine(" 2. Creates an Auto Scaling group."); Console.WriteLine(" 3. Shows the details of the new Auto Scaling group"); Console.WriteLine(" to show that only one instance was created."); Console.WriteLine(" 4. Enables metrics collection."); Console.WriteLine(" 5. Updates the Auto Scaling group to increase the"); Console.WriteLine(" capacity to three."); Console.WriteLine(" 6. Describes Auto Scaling groups again to show the"); Console.WriteLine(" current state of the group."); Console.WriteLine(" 7. Changes the desired capacity of the Auto Scaling"); Console.WriteLine(" group to use an additional instance."); Console.WriteLine(" 8. Shows that there are now instances in the group."); Console.WriteLine(" 9. Lists the scaling activities that have occurred for the group."); Console.WriteLine("10. Displays the Amazon CloudWatch metrics that have"); Console.WriteLine(" been collected."); Console.WriteLine("11. Disables metrics collection."); Console.WriteLine("12. Terminates all instances in the Auto Scaling group."); Console.WriteLine("13. Deletes the Auto Scaling group."); Console.WriteLine("14. Deletes the Amazon EC2 launch template."); PressEnter(); } /// <summary> /// Display information about the Amazon Ec2 AutoScaling groups passed /// in the list of AutoScalingGroup objects. /// </summary> /// <param name="groups">A list of AutoScalingGroup objects.</param> public void DisplayGroupDetails(List<AutoScalingGroup> groups) { if (groups is null) return; groups.ForEach(group => { Console.WriteLine($"Group name:\t{group.AutoScalingGroupName}"); Console.WriteLine($"Group created:\t{group.CreatedTime}"); Console.WriteLine($"Maximum number of instances:\t{group.MaxSize}"); Console.WriteLine($"Desired number of instances:\t{group.DesiredCapacity}"); }); } /// <summary> /// Display a message and wait until the user presses enter. /// </summary> public void PressEnter() { Console.Write("\nPress <Enter> to continue. "); _ = Console.ReadLine(); Console.WriteLine(); } /// <summary> /// Pad a string with spaces to center it on the console display. /// </summary> /// <param name="strToCenter">The string to be centered.</param> /// <returns>The padded string.</returns> public string CenterString(string strToCenter) { var padAmount = (Console.WindowWidth - strToCenter.Length) / 2; var leftPad = new string(' ', padAmount); return $"{leftPad}{strToCenter}"; } /// <summary> /// Display a line of hyphens, the centered text of the title and another /// line of hyphens. /// </summary> /// <param name="strTitle">The string to be displayed.</param> public void DisplayTitle(string strTitle) { Console.WriteLine(SepBar); Console.WriteLine(CenterString(strTitle)); Console.WriteLine(SepBar); } /// <summary> /// Display a countdown and wait for a number of seconds. /// </summary> /// <param name="numSeconds">The number of seconds to wait.</param> public void WaitABit(int numSeconds, string msg) { Console.WriteLine(msg); // Wait for the requested number of seconds. for (int i = numSeconds; i > 0; i--) { System.Threading.Thread.Sleep(1000); Console.Write($"{i}..."); } PressEnter(); } }

起動テンプレートとメトリクスを管理するためにシナリオによって呼び出される関数を定義します。これらの関数は、Auto Scaling 、Amazon EC2、および CloudWatch アクションをラップします。 Amazon EC2

namespace AutoScalingActions; using Amazon.AutoScaling; using Amazon.AutoScaling.Model; /// <summary> /// A class that includes methods to perform Amazon EC2 Auto Scaling /// actions. /// </summary> public class AutoScalingWrapper { private readonly IAmazonAutoScaling _amazonAutoScaling; /// <summary> /// Constructor for the AutoScalingWrapper class. /// </summary> /// <param name="amazonAutoScaling">The injected Amazon EC2 Auto Scaling client.</param> public AutoScalingWrapper(IAmazonAutoScaling amazonAutoScaling) { _amazonAutoScaling = amazonAutoScaling; } /// <summary> /// Create a new Amazon EC2 Auto Scaling group. /// </summary> /// <param name="groupName">The name to use for the new Auto Scaling /// group.</param> /// <param name="launchTemplateName">The name of the Amazon EC2 Auto Scaling /// launch template to use to create instances in the group.</param> /// <returns>A Boolean value indicating the success of the action.</returns> public async Task<bool> CreateAutoScalingGroupAsync( string groupName, string launchTemplateName, string availabilityZone) { var templateSpecification = new LaunchTemplateSpecification { LaunchTemplateName = launchTemplateName, }; var zoneList = new List<string> { availabilityZone, }; var request = new CreateAutoScalingGroupRequest { AutoScalingGroupName = groupName, AvailabilityZones = zoneList, LaunchTemplate = templateSpecification, MaxSize = 6, MinSize = 1 }; var response = await _amazonAutoScaling.CreateAutoScalingGroupAsync(request); Console.WriteLine($"{groupName} Auto Scaling Group created"); return response.HttpStatusCode == System.Net.HttpStatusCode.OK; } /// <summary> /// Retrieve information about Amazon EC2 Auto Scaling quotas to the /// active AWS account. /// </summary> /// <returns>A Boolean value indicating the success of the action.</returns> public async Task<bool> DescribeAccountLimitsAsync() { var response = await _amazonAutoScaling.DescribeAccountLimitsAsync(); Console.WriteLine("The maximum number of Auto Scaling groups is " + response.MaxNumberOfAutoScalingGroups); Console.WriteLine("The current number of Auto Scaling groups is " + response.NumberOfAutoScalingGroups); return response.HttpStatusCode == System.Net.HttpStatusCode.OK; } /// <summary> /// Retrieve a list of the Amazon EC2 Auto Scaling activities for an /// Amazon EC2 Auto Scaling group. /// </summary> /// <param name="groupName">The name of the Amazon EC2 Auto Scaling group.</param> /// <returns>A list of Amazon EC2 Auto Scaling activities.</returns> public async Task<List<Amazon.AutoScaling.Model.Activity>> DescribeScalingActivitiesAsync( string groupName) { var scalingActivitiesRequest = new DescribeScalingActivitiesRequest { AutoScalingGroupName = groupName, MaxRecords = 10, }; var response = await _amazonAutoScaling.DescribeScalingActivitiesAsync(scalingActivitiesRequest); return response.Activities; } /// <summary> /// Get data about the instances in an Amazon EC2 Auto Scaling group. /// </summary> /// <param name="groupName">The name of the Amazon EC2 Auto Scaling group.</param> /// <returns>A list of Amazon EC2 Auto Scaling details.</returns> public async Task<List<AutoScalingInstanceDetails>> DescribeAutoScalingInstancesAsync( string groupName) { var groups = await DescribeAutoScalingGroupsAsync(groupName); var instanceIds = new List<string>(); groups!.ForEach(group => { if (group.AutoScalingGroupName == groupName) { group.Instances.ForEach(instance => { instanceIds.Add(instance.InstanceId); }); } }); var scalingGroupsRequest = new DescribeAutoScalingInstancesRequest { MaxRecords = 10, InstanceIds = instanceIds, }; var response = await _amazonAutoScaling.DescribeAutoScalingInstancesAsync(scalingGroupsRequest); var instanceDetails = response.AutoScalingInstances; return instanceDetails; } /// <summary> /// Retrieve a list of information about Amazon EC2 Auto Scaling groups. /// </summary> /// <param name="groupName">The name of the Amazon EC2 Auto Scaling group.</param> /// <returns>A list of Amazon EC2 Auto Scaling groups.</returns> public async Task<List<AutoScalingGroup>?> DescribeAutoScalingGroupsAsync( string groupName) { var groupList = new List<string> { groupName, }; var request = new DescribeAutoScalingGroupsRequest { AutoScalingGroupNames = groupList, }; var response = await _amazonAutoScaling.DescribeAutoScalingGroupsAsync(request); var groups = response.AutoScalingGroups; return groups; } /// <summary> /// Delete an Auto Scaling group. /// </summary> /// <param name="groupName">The name of the Amazon EC2 Auto Scaling group.</param> /// <returns>A Boolean value indicating the success of the action.</returns> public async Task<bool> DeleteAutoScalingGroupAsync( string groupName) { var deleteAutoScalingGroupRequest = new DeleteAutoScalingGroupRequest { AutoScalingGroupName = groupName, ForceDelete = true, }; var response = await _amazonAutoScaling.DeleteAutoScalingGroupAsync(deleteAutoScalingGroupRequest); if (response.HttpStatusCode == System.Net.HttpStatusCode.OK) { Console.WriteLine($"You successfully deleted {groupName}"); return true; } Console.WriteLine($"Couldn't delete {groupName}."); return false; } /// <summary> /// Disable the collection of metric data for an Amazon EC2 Auto Scaling /// group. /// </summary> /// <param name="groupName">The name of the Auto Scaling group.</param> /// <returns>A Boolean value that indicates the success or failure of /// the operation.</returns> public async Task<bool> DisableMetricsCollectionAsync(string groupName) { var request = new DisableMetricsCollectionRequest { AutoScalingGroupName = groupName, }; var response = await _amazonAutoScaling.DisableMetricsCollectionAsync(request); return response.HttpStatusCode == System.Net.HttpStatusCode.OK; } /// <summary> /// Enable the collection of metric data for an Auto Scaling group. /// </summary> /// <param name="groupName">The name of the Auto Scaling group.</param> /// <returns>A Boolean value indicating the success of the action.</returns> public async Task<bool> EnableMetricsCollectionAsync(string groupName) { var listMetrics = new List<string> { "GroupMaxSize", }; var collectionRequest = new EnableMetricsCollectionRequest { AutoScalingGroupName = groupName, Metrics = listMetrics, Granularity = "1Minute", }; var response = await _amazonAutoScaling.EnableMetricsCollectionAsync(collectionRequest); return response.HttpStatusCode == System.Net.HttpStatusCode.OK; } /// <summary> /// Set the desired capacity of an Auto Scaling group. /// </summary> /// <param name="groupName">The name of the Auto Scaling group.</param> /// <param name="desiredCapacity">The desired capacity for the Auto /// Scaling group.</param> /// <returns>A Boolean value indicating the success of the action.</returns> public async Task<bool> SetDesiredCapacityAsync( string groupName, int desiredCapacity) { var capacityRequest = new SetDesiredCapacityRequest { AutoScalingGroupName = groupName, DesiredCapacity = desiredCapacity, }; var response = await _amazonAutoScaling.SetDesiredCapacityAsync(capacityRequest); Console.WriteLine($"You have set the DesiredCapacity to {desiredCapacity}."); return response.HttpStatusCode == System.Net.HttpStatusCode.OK; } /// <summary> /// Terminate all instances in the Auto Scaling group in preparation for /// deleting the group. /// </summary> /// <param name="instanceId">The instance Id of the instance to terminate.</param> /// <returns>A Boolean value that indicates the success or failure of /// the operation.</returns> public async Task<bool> TerminateInstanceInAutoScalingGroupAsync( string instanceId) { var request = new TerminateInstanceInAutoScalingGroupRequest { InstanceId = instanceId, ShouldDecrementDesiredCapacity = false, }; var response = await _amazonAutoScaling.TerminateInstanceInAutoScalingGroupAsync(request); if (response.HttpStatusCode == System.Net.HttpStatusCode.OK) { Console.WriteLine($"You have terminated the instance: {instanceId}"); return true; } Console.WriteLine($"Could not terminate {instanceId}"); return false; } /// <summary> /// Update the capacity of an Auto Scaling group. /// </summary> /// <param name="groupName">The name of the Auto Scaling group.</param> /// <param name="launchTemplateName">The name of the EC2 launch template.</param> /// <param name="maxSize">The maximum number of instances that can be /// created for the Auto Scaling group.</param> /// <returns>A Boolean value indicating the success of the action.</returns> public async Task<bool> UpdateAutoScalingGroupAsync( string groupName, string launchTemplateName, int maxSize) { var templateSpecification = new LaunchTemplateSpecification { LaunchTemplateName = launchTemplateName, }; var groupRequest = new UpdateAutoScalingGroupRequest { MaxSize = maxSize, AutoScalingGroupName = groupName, LaunchTemplate = templateSpecification, }; var response = await _amazonAutoScaling.UpdateAutoScalingGroupAsync(groupRequest); if (response.HttpStatusCode == System.Net.HttpStatusCode.OK) { Console.WriteLine($"You successfully updated the Auto Scaling group {groupName}."); return true; } else { return false; } } } namespace AutoScalingActions; using Amazon.EC2; using Amazon.EC2.Model; public class EC2Wrapper { private readonly IAmazonEC2 _amazonEc2; /// <summary> /// Constructor for the EC2Wrapper class. /// </summary> /// <param name="amazonEc2">The injected Amazon EC2 client.</param> public EC2Wrapper(IAmazonEC2 amazonEc2) { _amazonEc2 = amazonEc2; } /// <summary> /// Create a new Amazon EC2 launch template. /// </summary> /// <param name="imageId">The image Id to use for instances launched /// using the Amazon EC2 launch template.</param> /// <param name="instanceType">The type of EC2 instances to create.</param> /// <param name="launchTemplateName">The name of the launch template.</param> /// <returns>Returns the TemplateID of the new launch template.</returns> public async Task<string> CreateLaunchTemplateAsync( string imageId, string instanceType, string launchTemplateName) { var request = new CreateLaunchTemplateRequest { LaunchTemplateData = new RequestLaunchTemplateData { ImageId = imageId, InstanceType = instanceType, }, LaunchTemplateName = launchTemplateName, }; var response = await _amazonEc2.CreateLaunchTemplateAsync(request); return response.LaunchTemplate.LaunchTemplateId; } /// <summary> /// Delete an Amazon EC2 launch template. /// </summary> /// <param name="launchTemplateId">The TemplateId of the launch template to /// delete.</param> /// <returns>The name of the EC2 launch template that was deleted.</returns> public async Task<string> DeleteLaunchTemplateAsync(string launchTemplateId) { var request = new DeleteLaunchTemplateRequest { LaunchTemplateId = launchTemplateId, }; var response = await _amazonEc2.DeleteLaunchTemplateAsync(request); return response.LaunchTemplate.LaunchTemplateName; } /// <summary> /// Retrieve information about an EC2 launch template. /// </summary> /// <param name="launchTemplateName">The name of the EC2 launch template.</param> /// <returns>A Boolean value that indicates the success or failure of /// the operation.</returns> public async Task<bool> DescribeLaunchTemplateAsync(string launchTemplateName) { var request = new DescribeLaunchTemplatesRequest { LaunchTemplateNames = new List<string> { launchTemplateName, }, }; var response = await _amazonEc2.DescribeLaunchTemplatesAsync(request); if (response.LaunchTemplates is not null) { response.LaunchTemplates.ForEach(template => { Console.Write($"{template.LaunchTemplateName}\t"); Console.WriteLine(template.LaunchTemplateId); }); return true; } return false; } /// <summary> /// Retrieve the availability zones for the current region. /// </summary> /// <returns>A collection of availability zones.</returns> public async Task<List<AvailabilityZone>> ListAvailabilityZonesAsync() { var response = await _amazonEc2.DescribeAvailabilityZonesAsync( new DescribeAvailabilityZonesRequest()); return response.AvailabilityZones; } } namespace AutoScalingActions; using Amazon.CloudWatch; using Amazon.CloudWatch.Model; /// <summary> /// Contains methods to access Amazon CloudWatch metrics for the /// Amazon EC2 Auto Scaling basics scenario. /// </summary> public class CloudWatchWrapper { private readonly IAmazonCloudWatch _amazonCloudWatch; /// <summary> /// Constructor for the CloudWatchWrapper. /// </summary> /// <param name="amazonCloudWatch">The injected CloudWatch client.</param> public CloudWatchWrapper(IAmazonCloudWatch amazonCloudWatch) { _amazonCloudWatch = amazonCloudWatch; } /// <summary> /// Retrieve the metrics information collection for the Auto Scaling group. /// </summary> /// <param name="groupName">The name of the Auto Scaling group.</param> /// <returns>A list of Metrics collected for the Auto Scaling group.</returns> public async Task<List<Amazon.CloudWatch.Model.Metric>> GetCloudWatchMetricsAsync(string groupName) { var filter = new DimensionFilter { Name = "AutoScalingGroupName", Value = $"{groupName}", }; var request = new ListMetricsRequest { MetricName = "AutoScalingGroupName", Dimensions = new List<DimensionFilter> { filter }, Namespace = "AWS/AutoScaling", }; var response = await _amazonCloudWatch.ListMetricsAsync(request); return response.Metrics; } /// <summary> /// Retrieve the metric data collected for an Amazon EC2 Auto Scaling group. /// </summary> /// <param name="groupName">The name of the Amazon EC2 Auto Scaling group.</param> /// <returns>A list of data points.</returns> public async Task<List<Datapoint>> GetMetricStatisticsAsync(string groupName) { var metricDimensions = new List<Dimension> { new Dimension { Name = "AutoScalingGroupName", Value = $"{groupName}", }, }; // The start time will be yesterday. var startTime = DateTime.UtcNow.AddDays(-1); var request = new GetMetricStatisticsRequest { MetricName = "AutoScalingGroupName", Dimensions = metricDimensions, Namespace = "AWS/AutoScaling", Period = 60, // 60 seconds. Statistics = new List<string>() { "Minimum" }, StartTimeUtc = startTime, EndTimeUtc = DateTime.UtcNow, }; var response = await _amazonCloudWatch.GetMetricStatisticsAsync(request); return response.Datapoints; } }
C++
SDK for C++
注記

については、「」を参照してください GitHub。AWS コード例リポジトリ で全く同じ例を見つけて、設定と実行の方法を確認してください。

//! Routine which demonstrates using an Auto Scaling group //! to manage Amazon EC2 instances. /*! \sa groupsAndInstancesScenario() \param clientConfig: AWS client configuration. \return bool: Successful completion. */ bool AwsDoc::AutoScaling::groupsAndInstancesScenario( const Aws::Client::ClientConfiguration &clientConfig) { Aws::String templateName; Aws::EC2::EC2Client ec2Client(clientConfig); std::cout << std::setfill('*') << std::setw(ASTERISK_FILL_WIDTH) << " " << std::endl; std::cout << "Welcome to the Amazon Elastic Compute Cloud (Amazon EC2) Auto Scaling " << "demo for managing groups and instances." << std::endl; std::cout << std::setfill('*') << std::setw(ASTERISK_FILL_WIDTH) << " \n" << std::endl; std::cout << "This example requires an EC2 launch template." << std::endl; if (askYesNoQuestion( "Would you like to use an existing EC2 launch template (y/n)? ")) { // 1. Specify the name of an existing EC2 launch template. templateName = askQuestion( "Enter the name of the existing EC2 launch template. "); Aws::EC2::Model::DescribeLaunchTemplatesRequest request; request.AddLaunchTemplateNames(templateName); Aws::EC2::Model::DescribeLaunchTemplatesOutcome outcome = ec2Client.DescribeLaunchTemplates(request); if (outcome.IsSuccess()) { std::cout << "Validated the EC2 launch template '" << templateName << "' exists by calling DescribeLaunchTemplate." << std::endl; } else { std::cerr << "Error validating the existence of the launch template. " << outcome.GetError().GetMessage() << std::endl; } } else { // 2. Or create a new EC2 launch template. templateName = askQuestion("Enter the name for a new EC2 launch template: "); Aws::EC2::Model::CreateLaunchTemplateRequest request; request.SetLaunchTemplateName(templateName); Aws::EC2::Model::RequestLaunchTemplateData requestLaunchTemplateData; requestLaunchTemplateData.SetInstanceType(EC2_LAUNCH_TEMPLATE_INSTANCE_TYPE); requestLaunchTemplateData.SetImageId(EC2_LAUNCH_TEMPLATE_IMAGE_ID); request.SetLaunchTemplateData(requestLaunchTemplateData); Aws::EC2::Model::CreateLaunchTemplateOutcome outcome = ec2Client.CreateLaunchTemplate(request); if (outcome.IsSuccess()) { std::cout << "The EC2 launch template '" << templateName << " was created." << std::endl; } else if (outcome.GetError().GetExceptionName() == "InvalidLaunchTemplateName.AlreadyExistsException") { std::cout << "The EC2 template '" << templateName << "' already exists" << std::endl; } else { std::cerr << "Error with EC2::CreateLaunchTemplate. " << outcome.GetError().GetMessage() << std::endl; } } Aws::AutoScaling::AutoScalingClient autoScalingClient(clientConfig); std::cout << "Let's create an Auto Scaling group." << std::endl; Aws::String groupName = askQuestion( "Enter a name for the Auto Scaling group: "); // 3. Retrieve a list of EC2 Availability Zones. Aws::Vector<Aws::EC2::Model::AvailabilityZone> availabilityZones; { Aws::EC2::Model::DescribeAvailabilityZonesRequest request; Aws::EC2::Model::DescribeAvailabilityZonesOutcome outcome = ec2Client.DescribeAvailabilityZones(request); if (outcome.IsSuccess()) { std::cout << "EC2 instances can be created in the following Availability Zones:" << std::endl; availabilityZones = outcome.GetResult().GetAvailabilityZones(); for (size_t i = 0; i < availabilityZones.size(); ++i) { std::cout << " " << i + 1 << ". " << availabilityZones[i].GetZoneName() << std::endl; } } else { std::cerr << "Error with EC2::DescribeAvailabilityZones. " << outcome.GetError().GetMessage() << std::endl; cleanupResources("", templateName, autoScalingClient, ec2Client); return false; } } int availabilityZoneChoice = askQuestionForIntRange( "Choose an Availability Zone: ", 1, static_cast<int>(availabilityZones.size())); // 4. Create an Auto Scaling group with the specified Availability Zone. { Aws::AutoScaling::Model::CreateAutoScalingGroupRequest request; request.SetAutoScalingGroupName(groupName); Aws::Vector<Aws::String> availabilityGroupZones; availabilityGroupZones.push_back( availabilityZones[availabilityZoneChoice - 1].GetZoneName()); request.SetAvailabilityZones(availabilityGroupZones); request.SetMaxSize(1); request.SetMinSize(1); Aws::AutoScaling::Model::LaunchTemplateSpecification launchTemplateSpecification; launchTemplateSpecification.SetLaunchTemplateName(templateName); request.SetLaunchTemplate(launchTemplateSpecification); Aws::AutoScaling::Model::CreateAutoScalingGroupOutcome outcome = autoScalingClient.CreateAutoScalingGroup(request); if (outcome.IsSuccess()) { std::cout << "Created Auto Scaling group '" << groupName << "'..." << std::endl; } else if (outcome.GetError().GetErrorType() == Aws::AutoScaling::AutoScalingErrors::ALREADY_EXISTS_FAULT) { std::cout << "Auto Scaling group '" << groupName << "' already exists." << std::endl; } else { std::cerr << "Error with AutoScaling::CreateAutoScalingGroup. " << outcome.GetError().GetMessage() << std::endl; cleanupResources("", templateName, autoScalingClient, ec2Client); return false; } } Aws::Vector<Aws::AutoScaling::Model::AutoScalingGroup> autoScalingGroups; if (AwsDoc::AutoScaling::describeGroup(groupName, autoScalingGroups, autoScalingClient)) { std::cout << "Here is the Auto Scaling group description." << std::endl; if (!autoScalingGroups.empty()) { logAutoScalingGroupInfo(autoScalingGroups); } } else { cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } std::cout << "Waiting for the EC2 instance in the Auto Scaling group to become active..." << std::endl; if (!waitForInstances(groupName, autoScalingGroups, autoScalingClient)) { cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } bool enableMetrics = askYesNoQuestion( "Do you want to collect metrics about the A" "Auto Scaling group during this demo (y/n)? "); // 7. Optionally enable metrics collection for the Auto Scaling group. if (enableMetrics) { Aws::AutoScaling::Model::EnableMetricsCollectionRequest request; request.SetAutoScalingGroupName(groupName); request.AddMetrics("GroupMinSize"); request.AddMetrics("GroupMaxSize"); request.AddMetrics("GroupDesiredCapacity"); request.AddMetrics("GroupInServiceInstances"); request.AddMetrics("GroupTotalInstances"); request.SetGranularity("1Minute"); Aws::AutoScaling::Model::EnableMetricsCollectionOutcome outcome = autoScalingClient.EnableMetricsCollection(request); if (outcome.IsSuccess()) { std::cout << "Auto Scaling metrics have been enabled." << std::endl; } else { std::cerr << "Error with AutoScaling::EnableMetricsCollection. " << outcome.GetError().GetMessage() << std::endl; cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } } std::cout << "Let's update the maximum number of EC2 instances in '" << groupName << "' from 1 to 3." << std::endl; askQuestion("Press enter to continue: ", alwaysTrueTest); // 8. Update the Auto Scaling group, setting a new maximum size. { Aws::AutoScaling::Model::UpdateAutoScalingGroupRequest request; request.SetAutoScalingGroupName(groupName); request.SetMaxSize(3); Aws::AutoScaling::Model::UpdateAutoScalingGroupOutcome outcome = autoScalingClient.UpdateAutoScalingGroup(request); if (!outcome.IsSuccess()) { std::cerr << "Error with AutoScaling::UpdateAutoScalingGroup. " << outcome.GetError().GetMessage() << std::endl; cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } } if (AwsDoc::AutoScaling::describeGroup(groupName, autoScalingGroups, autoScalingClient)) { if (!autoScalingGroups.empty()) { const auto &instances = autoScalingGroups[0].GetInstances(); std::cout << "The group still has one running EC2 instance, but it can have up to 3.\n" << std::endl; logAutoScalingGroupInfo(autoScalingGroups); } else { std::cerr << "No EC2 launch groups were retrieved from DescribeGroup request." << std::endl; cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } } std::cout << "\n" << std::setfill('*') << std::setw(ASTERISK_FILL_WIDTH) << "\n" << std::endl; std::cout << "Let's update the desired capacity in '" << groupName << "' from 1 to 2." << std::endl; askQuestion("Press enter to continue: ", alwaysTrueTest); // 9. Update the Auto Scaling group, setting a new desired capacity. { Aws::AutoScaling::Model::SetDesiredCapacityRequest request; request.SetAutoScalingGroupName(groupName); request.SetDesiredCapacity(2); Aws::AutoScaling::Model::SetDesiredCapacityOutcome outcome = autoScalingClient.SetDesiredCapacity(request); if (!outcome.IsSuccess()) { std::cerr << "Error with AutoScaling::SetDesiredCapacityRequest. " << outcome.GetError().GetMessage() << std::endl; cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } } if (AwsDoc::AutoScaling::describeGroup(groupName, autoScalingGroups, autoScalingClient)) { if (!autoScalingGroups.empty()) { std::cout << "Here is the current state of the group." << std::endl; logAutoScalingGroupInfo(autoScalingGroups); } else { std::cerr << "No EC2 launch groups were retrieved from DescribeGroup request." << std::endl; cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } } std::cout << "Waiting for the new EC2 instance to start..." << std::endl; waitForInstances(groupName, autoScalingGroups, autoScalingClient); std::cout << "\n" << std::setfill('*') << std::setw(ASTERISK_FILL_WIDTH) << "\n" << std::endl; std::cout << "Let's terminate one of the EC2 instances in " << groupName << "." << std::endl; std::cout << "Because the desired capacity is 2, another EC2 instance will start " << "to replace the terminated EC2 instance." << std::endl; std::cout << "The currently running EC2 instances are:" << std::endl; if (autoScalingGroups.empty()) { std::cerr << "Error describing groups. No groups returned." << std::endl; cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } int instanceNumber = 1; Aws::Vector<Aws::String> instanceIDs = instancesToInstanceIDs( autoScalingGroups[0].GetInstances()); for (const Aws::String &instanceID: instanceIDs) { std::cout << " " << instanceNumber << ". " << instanceID << std::endl; ++instanceNumber; } instanceNumber = askQuestionForIntRange("Which EC2 instance do you want to stop? ", 1, static_cast<int>(instanceIDs.size())); // 10. Terminate an EC2 instance in the Auto Scaling group. { Aws::AutoScaling::Model::TerminateInstanceInAutoScalingGroupRequest request; request.SetInstanceId(instanceIDs[instanceNumber - 1]); request.SetShouldDecrementDesiredCapacity(false); Aws::AutoScaling::Model::TerminateInstanceInAutoScalingGroupOutcome outcome = autoScalingClient.TerminateInstanceInAutoScalingGroup(request); if (outcome.IsSuccess()) { std::cout << "Waiting for EC2 instance with ID '" << instanceIDs[instanceNumber - 1] << "' to terminate..." << std::endl; } else { std::cerr << "Error with AutoScaling::TerminateInstanceInAutoScalingGroup. " << outcome.GetError().GetMessage() << std::endl; cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } } waitForInstances(groupName, autoScalingGroups, autoScalingClient); std::cout << "\n" << std::setfill('*') << std::setw(ASTERISK_FILL_WIDTH) << "\n" << std::endl; std::cout << "Let's get a report of scaling activities for EC2 launch group '" << groupName << "'." << std::endl; askQuestion("Press enter to continue: ", alwaysTrueTest); // 11. Get a description of activities for the Auto Scaling group. { Aws::AutoScaling::Model::DescribeScalingActivitiesRequest request; request.SetAutoScalingGroupName(groupName); Aws::Vector<Aws::AutoScaling::Model::Activity> allActivities; Aws::String nextToken; // Used for pagination; do { if (!nextToken.empty()) { request.SetNextToken(nextToken); } Aws::AutoScaling::Model::DescribeScalingActivitiesOutcome outcome = autoScalingClient.DescribeScalingActivities(request); if (outcome.IsSuccess()) { const Aws::Vector<Aws::AutoScaling::Model::Activity> &activities = outcome.GetResult().GetActivities(); allActivities.insert(allActivities.end(), activities.begin(), activities.end()); nextToken = outcome.GetResult().GetNextToken(); } else { std::cerr << "Error with AutoScaling::DescribeScalingActivities. " << outcome.GetError().GetMessage() << std::endl; cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } } while (!nextToken.empty()); std::cout << "Found " << allActivities.size() << " activities." << std::endl; std::cout << "Activities are ordered with the most recent first." << std::endl; for (const Aws::AutoScaling::Model::Activity &activity: allActivities) { std::cout << activity.GetDescription() << std::endl; std::cout << activity.GetDetails() << std::endl; } } if (enableMetrics) { if (!logAutoScalingMetrics(groupName, clientConfig)) { cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } } std::cout << "Let's clean up." << std::endl; askQuestion("Press enter to continue: ", alwaysTrueTest); // 13. Disable metrics collection if enabled. if (enableMetrics) { Aws::AutoScaling::Model::DisableMetricsCollectionRequest request; request.SetAutoScalingGroupName(groupName); Aws::AutoScaling::Model::DisableMetricsCollectionOutcome outcome = autoScalingClient.DisableMetricsCollection(request); if (outcome.IsSuccess()) { std::cout << "Metrics collection has been disabled." << std::endl; } else { std::cerr << "Error with AutoScaling::DisableMetricsCollection. " << outcome.GetError().GetMessage() << std::endl; cleanupResources(groupName, templateName, autoScalingClient, ec2Client); return false; } } return cleanupResources(groupName, templateName, autoScalingClient, ec2Client); } //! Routine which waits for EC2 instances in an Auto Scaling group to //! complete startup or shutdown. /*! \sa waitForInstances() \param groupName: An Auto Scaling group name. \param autoScalingGroups: Vector to receive 'AutoScalingGroup' records. \param client: 'AutoScalingClient' instance. \return bool: Successful completion. */ bool AwsDoc::AutoScaling::waitForInstances(const Aws::String &groupName, Aws::Vector<Aws::AutoScaling::Model::AutoScalingGroup> &autoScalingGroups, const Aws::AutoScaling::AutoScalingClient &client) { bool ready = false; const std::vector<Aws::String> READY_STATES = {"InService", "Terminated"}; int count = 0; int desiredCapacity = 0; std::this_thread::sleep_for(std::chrono::seconds(4)); while (!ready) { if (WAIT_FOR_INSTANCES_TIMEOUT < count) { std::cerr << "Wait for instance timed out." << std::endl; return false; } std::this_thread::sleep_for(std::chrono::seconds(1)); ++count; if (!describeGroup(groupName, autoScalingGroups, client)) { return false; } Aws::Vector<Aws::String> instanceIDs; if (!autoScalingGroups.empty()) { instanceIDs = instancesToInstanceIDs(autoScalingGroups[0].GetInstances()); desiredCapacity = autoScalingGroups[0].GetDesiredCapacity(); } if (instanceIDs.empty()) { if (desiredCapacity == 0) { break; } else { if ((count % 5) == 0) { std::cout << "No instance IDs returned for group." << std::endl; } continue; } } // 6. Check lifecycle state of the instances using DescribeAutoScalingInstances. Aws::AutoScaling::Model::DescribeAutoScalingInstancesRequest request; request.SetInstanceIds(instanceIDs); Aws::AutoScaling::Model::DescribeAutoScalingInstancesOutcome outcome = client.DescribeAutoScalingInstances(request); if (outcome.IsSuccess()) { const Aws::Vector<Aws::AutoScaling::Model::AutoScalingInstanceDetails> &instancesDetails = outcome.GetResult().GetAutoScalingInstances(); ready = instancesDetails.size() >= desiredCapacity; for (const Aws::AutoScaling::Model::AutoScalingInstanceDetails &details: instancesDetails) { if (!stringInVector(details.GetLifecycleState(), READY_STATES)) { ready = false; break; } } // Log the status while waiting. if (((count % 5) == 1) || ready) { logInstancesLifecycleState(instancesDetails); } } else { std::cerr << "Error with AutoScaling::DescribeAutoScalingInstances. " << outcome.GetError().GetMessage() << std::endl; return false; } } if (!describeGroup(groupName, autoScalingGroups, client)) { return false; } return true; } //! Routine to cleanup resources created in 'groupsAndInstancesScenario'. /*! \sa cleanupResources() \param groupName: Optional Auto Scaling group name. \param templateName: Optional EC2 launch template name. \param autoScalingClient: 'AutoScalingClient' instance. \param ec2Client: 'EC2Client' instance. \return bool: Successful completion. */ bool AwsDoc::AutoScaling::cleanupResources(const Aws::String &groupName, const Aws::String &templateName, const Aws::AutoScaling::AutoScalingClient &autoScalingClient, const Aws::EC2::EC2Client &ec2Client) { bool result = true; // 14. Delete the Auto Scaling group. if (!groupName.empty() && (askYesNoQuestion( Aws::String("Delete the Auto Scaling group '") + groupName + "' (y/n)?"))) { { Aws::AutoScaling::Model::UpdateAutoScalingGroupRequest request; request.SetAutoScalingGroupName(groupName); request.SetMinSize(0); request.SetDesiredCapacity(0); Aws::AutoScaling::Model::UpdateAutoScalingGroupOutcome outcome = autoScalingClient.UpdateAutoScalingGroup(request); if (outcome.IsSuccess()) { std::cout << "The minimum size and desired capacity of the Auto Scaling group " << "was set to zero before terminating the instances." << std::endl; } else { std::cerr << "Error with AutoScaling::UpdateAutoScalingGroup. " << outcome.GetError().GetMessage() << std::endl; result = false; } } Aws::Vector<Aws::AutoScaling::Model::AutoScalingGroup> autoScalingGroups; if (AwsDoc::AutoScaling::describeGroup(groupName, autoScalingGroups, autoScalingClient)) { if (!autoScalingGroups.empty()) { Aws::Vector<Aws::String> instanceIDs = instancesToInstanceIDs( autoScalingGroups[0].GetInstances()); for (const Aws::String &instanceID: instanceIDs) { Aws::AutoScaling::Model::TerminateInstanceInAutoScalingGroupRequest request; request.SetInstanceId(instanceID); request.SetShouldDecrementDesiredCapacity(true); Aws::AutoScaling::Model::TerminateInstanceInAutoScalingGroupOutcome outcome = autoScalingClient.TerminateInstanceInAutoScalingGroup( request); if (outcome.IsSuccess()) { std::cout << "Initiating termination of EC2 instance '" << instanceID << "'." << std::endl; } else { std::cerr << "Error with AutoScaling::TerminateInstanceInAutoScalingGroup. " << outcome.GetError().GetMessage() << std::endl; result = false; } } } std::cout << "Waiting for the EC2 instances to terminate before deleting the " << "Auto Scaling group..." << std::endl; waitForInstances(groupName, autoScalingGroups, autoScalingClient); } { Aws::AutoScaling::Model::DeleteAutoScalingGroupRequest request; request.SetAutoScalingGroupName(groupName); Aws::AutoScaling::Model::DeleteAutoScalingGroupOutcome outcome = autoScalingClient.DeleteAutoScalingGroup(request); if (outcome.IsSuccess()) { std::cout << "Auto Scaling group '" << groupName << "' was deleted." << std::endl; } else { std::cerr << "Error with AutoScaling::DeleteAutoScalingGroup. " << outcome.GetError().GetMessage() << std::endl; result = false; } } } // 15. Delete the EC2 launch template. if (!templateName.empty() && (askYesNoQuestion( Aws::String("Delete the EC2 launch template '") + templateName + "' (y/n)?"))) { Aws::EC2::Model::DeleteLaunchTemplateRequest request; request.SetLaunchTemplateName(templateName); Aws::EC2::Model::DeleteLaunchTemplateOutcome outcome = ec2Client.DeleteLaunchTemplate(request); if (outcome.IsSuccess()) { std::cout << "EC2 launch template '" << templateName << "' was deleted." << std::endl; } else { std::cerr << "Error with EC2::DeleteLaunchTemplate. " << outcome.GetError().GetMessage() << std::endl; result = false; } } return result; } //! Routine which retrieves Auto Scaling group descriptions. /*! \sa describeGroup() \param groupName: An Auto Scaling group name. \param autoScalingGroups: Vector to receive 'AutoScalingGroup' records. \param client: 'AutoScalingClient' instance. \return bool: Successful completion. */ bool AwsDoc::AutoScaling::describeGroup(const Aws::String &groupName, Aws::Vector<Aws::AutoScaling::Model::AutoScalingGroup> &autoScalingGroup, const Aws::AutoScaling::AutoScalingClient &client) { // 5. Retrieve a description of the Auto Scaling group. Aws::AutoScaling::Model::DescribeAutoScalingGroupsRequest request; Aws::Vector<Aws::String> groupNames; groupNames.push_back(groupName); request.SetAutoScalingGroupNames(groupNames); Aws::AutoScaling::Model::DescribeAutoScalingGroupsOutcome outcome = client.DescribeAutoScalingGroups(request); if (outcome.IsSuccess()) { autoScalingGroup = outcome.GetResult().GetAutoScalingGroups(); } else { std::cerr << "Error with AutoScaling::DescribeAutoScalingGroups. " << outcome.GetError().GetMessage() << std::endl; } return outcome.IsSuccess(); }
Java
SDK for Java 2.x
注記

については、「」を参照してください GitHub。AWS コード例リポジトリ で全く同じ例を見つけて、設定と実行の方法を確認してください。

/** * Before running this SDK for Java (v2) code example, set up your development * environment, including your credentials. * * For more information, see the following documentation: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html * * In addition, create a launch template. For more information, see the * following topic: * * https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html#create-launch-template * * This code example performs the following operations: * 1. Creates an Auto Scaling group using an AutoScalingWaiter. * 2. Gets a specific Auto Scaling group and returns an instance Id value. * 3. Describes Auto Scaling with the Id value. * 4. Enables metrics collection. * 5. Update an Auto Scaling group. * 6. Describes Account details. * 7. Describe account details" * 8. Updates an Auto Scaling group to use an additional instance. * 9. Gets the specific Auto Scaling group and gets the number of instances. * 10. List the scaling activities that have occurred for the group. * 11. Terminates an instance in the Auto Scaling group. * 12. Stops the metrics collection. * 13. Deletes the Auto Scaling group. */ public class AutoScalingScenario { public static final String DASHES = new String(new char[80]).replace("\0", "-"); public static void main(String[] args) throws InterruptedException { final String usage = """ Usage: <groupName> <launchTemplateName> <vpcZoneId> Where: groupName - The name of the Auto Scaling group. launchTemplateName - The name of the launch template.\s vpcZoneId - A subnet Id for a virtual private cloud (VPC) where instances in the Auto Scaling group can be created. """; if (args.length != 3) { System.out.println(usage); System.exit(1); } String groupName = args[0]; String launchTemplateName = args[1]; String vpcZoneId = args[2]; AutoScalingClient autoScalingClient = AutoScalingClient.builder() .region(Region.US_EAST_1) .build(); System.out.println(DASHES); System.out.println("Welcome to the Amazon EC2 Auto Scaling example scenario."); System.out.println(DASHES); System.out.println(DASHES); System.out.println("1. Create an Auto Scaling group named " + groupName); createAutoScalingGroup(autoScalingClient, groupName, launchTemplateName, vpcZoneId); System.out.println( "Wait 1 min for the resources, including the instance. Otherwise, an empty instance Id is returned"); Thread.sleep(60000); System.out.println(DASHES); System.out.println(DASHES); System.out.println("2. Get Auto Scale group Id value"); String instanceId = getSpecificAutoScalingGroups(autoScalingClient, groupName); if (instanceId.compareTo("") == 0) { System.out.println("Error - no instance Id value"); System.exit(1); } else { System.out.println("The instance Id value is " + instanceId); } System.out.println(DASHES); System.out.println(DASHES); System.out.println("3. Describe Auto Scaling with the Id value " + instanceId); describeAutoScalingInstance(autoScalingClient, instanceId); System.out.println(DASHES); System.out.println(DASHES); System.out.println("4. Enable metrics collection " + instanceId); enableMetricsCollection(autoScalingClient, groupName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("5. Update an Auto Scaling group to update max size to 3"); updateAutoScalingGroup(autoScalingClient, groupName, launchTemplateName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("6. Describe Auto Scaling groups"); describeAutoScalingGroups(autoScalingClient, groupName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("7. Describe account details"); describeAccountLimits(autoScalingClient); System.out.println( "Wait 1 min for the resources, including the instance. Otherwise, an empty instance Id is returned"); Thread.sleep(60000); System.out.println(DASHES); System.out.println(DASHES); System.out.println("8. Set desired capacity to 2"); setDesiredCapacity(autoScalingClient, groupName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("9. Get the two instance Id values and state"); getSpecificAutoScalingGroups(autoScalingClient, groupName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("10. List the scaling activities that have occurred for the group"); describeScalingActivities(autoScalingClient, groupName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("11. Terminate an instance in the Auto Scaling group"); terminateInstanceInAutoScalingGroup(autoScalingClient, instanceId); System.out.println(DASHES); System.out.println(DASHES); System.out.println("12. Stop the metrics collection"); disableMetricsCollection(autoScalingClient, groupName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("13. Delete the Auto Scaling group"); deleteAutoScalingGroup(autoScalingClient, groupName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("The Scenario has successfully completed."); System.out.println(DASHES); autoScalingClient.close(); } public static void describeScalingActivities(AutoScalingClient autoScalingClient, String groupName) { try { DescribeScalingActivitiesRequest scalingActivitiesRequest = DescribeScalingActivitiesRequest.builder() .autoScalingGroupName(groupName) .maxRecords(10) .build(); DescribeScalingActivitiesResponse response = autoScalingClient .describeScalingActivities(scalingActivitiesRequest); List<Activity> activities = response.activities(); for (Activity activity : activities) { System.out.println("The activity Id is " + activity.activityId()); System.out.println("The activity details are " + activity.details()); } } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static void setDesiredCapacity(AutoScalingClient autoScalingClient, String groupName) { try { SetDesiredCapacityRequest capacityRequest = SetDesiredCapacityRequest.builder() .autoScalingGroupName(groupName) .desiredCapacity(2) .build(); autoScalingClient.setDesiredCapacity(capacityRequest); System.out.println("You have set the DesiredCapacity to 2"); } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static void createAutoScalingGroup(AutoScalingClient autoScalingClient, String groupName, String launchTemplateName, String vpcZoneId) { try { AutoScalingWaiter waiter = autoScalingClient.waiter(); LaunchTemplateSpecification templateSpecification = LaunchTemplateSpecification.builder() .launchTemplateName(launchTemplateName) .build(); CreateAutoScalingGroupRequest request = CreateAutoScalingGroupRequest.builder() .autoScalingGroupName(groupName) .availabilityZones("us-east-1a") .launchTemplate(templateSpecification) .maxSize(1) .minSize(1) .vpcZoneIdentifier(vpcZoneId) .build(); autoScalingClient.createAutoScalingGroup(request); DescribeAutoScalingGroupsRequest groupsRequest = DescribeAutoScalingGroupsRequest.builder() .autoScalingGroupNames(groupName) .build(); WaiterResponse<DescribeAutoScalingGroupsResponse> waiterResponse = waiter .waitUntilGroupExists(groupsRequest); waiterResponse.matched().response().ifPresent(System.out::println); System.out.println("Auto Scaling Group created"); } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static void describeAutoScalingInstance(AutoScalingClient autoScalingClient, String id) { try { DescribeAutoScalingInstancesRequest describeAutoScalingInstancesRequest = DescribeAutoScalingInstancesRequest .builder() .instanceIds(id) .build(); DescribeAutoScalingInstancesResponse response = autoScalingClient .describeAutoScalingInstances(describeAutoScalingInstancesRequest); List<AutoScalingInstanceDetails> instances = response.autoScalingInstances(); for (AutoScalingInstanceDetails instance : instances) { System.out.println("The instance lifecycle state is: " + instance.lifecycleState()); } } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static void describeAutoScalingGroups(AutoScalingClient autoScalingClient, String groupName) { try { DescribeAutoScalingGroupsRequest groupsRequest = DescribeAutoScalingGroupsRequest.builder() .autoScalingGroupNames(groupName) .maxRecords(10) .build(); DescribeAutoScalingGroupsResponse response = autoScalingClient.describeAutoScalingGroups(groupsRequest); List<AutoScalingGroup> groups = response.autoScalingGroups(); for (AutoScalingGroup group : groups) { System.out.println("*** The service to use for the health checks: " + group.healthCheckType()); } } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static String getSpecificAutoScalingGroups(AutoScalingClient autoScalingClient, String groupName) { try { String instanceId = ""; DescribeAutoScalingGroupsRequest scalingGroupsRequest = DescribeAutoScalingGroupsRequest.builder() .autoScalingGroupNames(groupName) .build(); DescribeAutoScalingGroupsResponse response = autoScalingClient .describeAutoScalingGroups(scalingGroupsRequest); List<AutoScalingGroup> groups = response.autoScalingGroups(); for (AutoScalingGroup group : groups) { System.out.println("The group name is " + group.autoScalingGroupName()); System.out.println("The group ARN is " + group.autoScalingGroupARN()); List<Instance> instances = group.instances(); for (Instance instance : instances) { instanceId = instance.instanceId(); System.out.println("The instance id is " + instanceId); System.out.println("The lifecycle state is " + instance.lifecycleState()); } } return instanceId; } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return ""; } public static void enableMetricsCollection(AutoScalingClient autoScalingClient, String groupName) { try { EnableMetricsCollectionRequest collectionRequest = EnableMetricsCollectionRequest.builder() .autoScalingGroupName(groupName) .metrics("GroupMaxSize") .granularity("1Minute") .build(); autoScalingClient.enableMetricsCollection(collectionRequest); System.out.println("The enable metrics collection operation was successful"); } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static void disableMetricsCollection(AutoScalingClient autoScalingClient, String groupName) { try { DisableMetricsCollectionRequest disableMetricsCollectionRequest = DisableMetricsCollectionRequest.builder() .autoScalingGroupName(groupName) .metrics("GroupMaxSize") .build(); autoScalingClient.disableMetricsCollection(disableMetricsCollectionRequest); System.out.println("The disable metrics collection operation was successful"); } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static void describeAccountLimits(AutoScalingClient autoScalingClient) { try { DescribeAccountLimitsResponse response = autoScalingClient.describeAccountLimits(); System.out.println("The max number of auto scaling groups is " + response.maxNumberOfAutoScalingGroups()); System.out.println("The current number of auto scaling groups is " + response.numberOfAutoScalingGroups()); } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static void updateAutoScalingGroup(AutoScalingClient autoScalingClient, String groupName, String launchTemplateName) { try { AutoScalingWaiter waiter = autoScalingClient.waiter(); LaunchTemplateSpecification templateSpecification = LaunchTemplateSpecification.builder() .launchTemplateName(launchTemplateName) .build(); UpdateAutoScalingGroupRequest groupRequest = UpdateAutoScalingGroupRequest.builder() .maxSize(3) .autoScalingGroupName(groupName) .launchTemplate(templateSpecification) .build(); autoScalingClient.updateAutoScalingGroup(groupRequest); DescribeAutoScalingGroupsRequest groupsRequest = DescribeAutoScalingGroupsRequest.builder() .autoScalingGroupNames(groupName) .build(); WaiterResponse<DescribeAutoScalingGroupsResponse> waiterResponse = waiter .waitUntilGroupInService(groupsRequest); waiterResponse.matched().response().ifPresent(System.out::println); System.out.println("You successfully updated the auto scaling group " + groupName); } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static void terminateInstanceInAutoScalingGroup(AutoScalingClient autoScalingClient, String instanceId) { try { TerminateInstanceInAutoScalingGroupRequest request = TerminateInstanceInAutoScalingGroupRequest.builder() .instanceId(instanceId) .shouldDecrementDesiredCapacity(false) .build(); autoScalingClient.terminateInstanceInAutoScalingGroup(request); System.out.println("You have terminated instance " + instanceId); } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static void deleteAutoScalingGroup(AutoScalingClient autoScalingClient, String groupName) { try { DeleteAutoScalingGroupRequest deleteAutoScalingGroupRequest = DeleteAutoScalingGroupRequest.builder() .autoScalingGroupName(groupName) .forceDelete(true) .build(); autoScalingClient.deleteAutoScalingGroup(deleteAutoScalingGroupRequest); System.out.println("You successfully deleted " + groupName); } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }
Kotlin
SDK for Kotlin
注記

については、「」を参照してください GitHub。AWS コード例リポジトリ で全く同じ例を見つけて、設定と実行の方法を確認してください。

suspend fun main(args: Array<String>) { val usage = """ Usage: <groupName> <launchTemplateName> <serviceLinkedRoleARN> <vpcZoneId> Where: groupName - The name of the Auto Scaling group. launchTemplateName - The name of the launch template. serviceLinkedRoleARN - The Amazon Resource Name (ARN) of the service-linked role that the Auto Scaling group uses. vpcZoneId - A subnet Id for a virtual private cloud (VPC) where instances in the Auto Scaling group can be created. """ if (args.size != 4) { println(usage) exitProcess(1) } val groupName = args[0] val launchTemplateName = args[1] val serviceLinkedRoleARN = args[2] val vpcZoneId = args[3] println("**** Create an Auto Scaling group named $groupName") createAutoScalingGroup(groupName, launchTemplateName, serviceLinkedRoleARN, vpcZoneId) println("Wait 1 min for the resources, including the instance. Otherwise, an empty instance Id is returned") delay(60000) val instanceId = getSpecificAutoScaling(groupName) if (instanceId.compareTo("") == 0) { println("Error - no instance Id value") exitProcess(1) } else { println("The instance Id value is $instanceId") } println("**** Describe Auto Scaling with the Id value $instanceId") describeAutoScalingInstance(instanceId) println("**** Enable metrics collection $instanceId") enableMetricsCollection(groupName) println("**** Update an Auto Scaling group to maximum size of 3") updateAutoScalingGroup(groupName, launchTemplateName, serviceLinkedRoleARN) println("**** Describe all Auto Scaling groups to show the current state of the groups") describeAutoScalingGroups(groupName) println("**** Describe account details") describeAccountLimits() println("Wait 1 min for the resources, including the instance. Otherwise, an empty instance Id is returned") delay(60000) println("**** Set desired capacity to 2") setDesiredCapacity(groupName) println("**** Get the two instance Id values and state") getAutoScalingGroups(groupName) println("**** List the scaling activities that have occurred for the group") describeScalingActivities(groupName) println("**** Terminate an instance in the Auto Scaling group") terminateInstanceInAutoScalingGroup(instanceId) println("**** Stop the metrics collection") disableMetricsCollection(groupName) println("**** Delete the Auto Scaling group") deleteSpecificAutoScalingGroup(groupName) } suspend fun describeAutoScalingGroups(groupName: String) { val groupsReques = DescribeAutoScalingGroupsRequest { autoScalingGroupNames = listOf(groupName) maxRecords = 10 } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> val response = autoScalingClient.describeAutoScalingGroups(groupsReques) response.autoScalingGroups?.forEach { group -> println("The service to use for the health checks: ${group.healthCheckType}") } } } suspend fun disableMetricsCollection(groupName: String) { val disableMetricsCollectionRequest = DisableMetricsCollectionRequest { autoScalingGroupName = groupName metrics = listOf("GroupMaxSize") } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> autoScalingClient.disableMetricsCollection(disableMetricsCollectionRequest) println("The disable metrics collection operation was successful") } } suspend fun describeScalingActivities(groupName: String?) { val scalingActivitiesRequest = DescribeScalingActivitiesRequest { autoScalingGroupName = groupName maxRecords = 10 } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> val response = autoScalingClient.describeScalingActivities(scalingActivitiesRequest) response.activities?.forEach { activity -> println("The activity Id is ${activity.activityId}") println("The activity details are ${activity.details}") } } } suspend fun getAutoScalingGroups(groupName: String) { val scalingGroupsRequest = DescribeAutoScalingGroupsRequest { autoScalingGroupNames = listOf(groupName) } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> val response = autoScalingClient.describeAutoScalingGroups(scalingGroupsRequest) response.autoScalingGroups?.forEach { group -> println("The group name is ${group.autoScalingGroupName}") println("The group ARN is ${group.autoScalingGroupArn}") group.instances?.forEach { instance -> println("The instance id is ${instance.instanceId}") println("The lifecycle state is " + instance.lifecycleState) } } } } suspend fun setDesiredCapacity(groupName: String) { val capacityRequest = SetDesiredCapacityRequest { autoScalingGroupName = groupName desiredCapacity = 2 } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> autoScalingClient.setDesiredCapacity(capacityRequest) println("You set the DesiredCapacity to 2") } } suspend fun updateAutoScalingGroup( groupName: String, launchTemplateNameVal: String, serviceLinkedRoleARNVal: String, ) { val templateSpecification = LaunchTemplateSpecification { launchTemplateName = launchTemplateNameVal } val groupRequest = UpdateAutoScalingGroupRequest { maxSize = 3 serviceLinkedRoleArn = serviceLinkedRoleARNVal autoScalingGroupName = groupName launchTemplate = templateSpecification } val groupsRequestWaiter = DescribeAutoScalingGroupsRequest { autoScalingGroupNames = listOf(groupName) } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> autoScalingClient.updateAutoScalingGroup(groupRequest) autoScalingClient.waitUntilGroupExists(groupsRequestWaiter) println("You successfully updated the Auto Scaling group $groupName") } } suspend fun createAutoScalingGroup( groupName: String, launchTemplateNameVal: String, serviceLinkedRoleARNVal: String, vpcZoneIdVal: String, ) { val templateSpecification = LaunchTemplateSpecification { launchTemplateName = launchTemplateNameVal } val request = CreateAutoScalingGroupRequest { autoScalingGroupName = groupName availabilityZones = listOf("us-east-1a") launchTemplate = templateSpecification maxSize = 1 minSize = 1 vpcZoneIdentifier = vpcZoneIdVal serviceLinkedRoleArn = serviceLinkedRoleARNVal } // This object is required for the waiter call. val groupsRequestWaiter = DescribeAutoScalingGroupsRequest { autoScalingGroupNames = listOf(groupName) } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> autoScalingClient.createAutoScalingGroup(request) autoScalingClient.waitUntilGroupExists(groupsRequestWaiter) println("$groupName was created!") } } suspend fun describeAutoScalingInstance(id: String) { val describeAutoScalingInstancesRequest = DescribeAutoScalingInstancesRequest { instanceIds = listOf(id) } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> val response = autoScalingClient.describeAutoScalingInstances(describeAutoScalingInstancesRequest) response.autoScalingInstances?.forEach { group -> println("The instance lifecycle state is: ${group.lifecycleState}") } } } suspend fun enableMetricsCollection(groupName: String?) { val collectionRequest = EnableMetricsCollectionRequest { autoScalingGroupName = groupName metrics = listOf("GroupMaxSize") granularity = "1Minute" } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> autoScalingClient.enableMetricsCollection(collectionRequest) println("The enable metrics collection operation was successful") } } suspend fun getSpecificAutoScaling(groupName: String): String { var instanceId = "" val scalingGroupsRequest = DescribeAutoScalingGroupsRequest { autoScalingGroupNames = listOf(groupName) } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> val response = autoScalingClient.describeAutoScalingGroups(scalingGroupsRequest) response.autoScalingGroups?.forEach { group -> println("The group name is ${group.autoScalingGroupName}") println("The group ARN is ${group.autoScalingGroupArn}") group.instances?.forEach { instance -> instanceId = instance.instanceId.toString() } } } return instanceId } suspend fun describeAccountLimits() { AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> val response = autoScalingClient.describeAccountLimits(DescribeAccountLimitsRequest {}) println("The max number of Auto Scaling groups is ${response.maxNumberOfAutoScalingGroups}") println("The current number of Auto Scaling groups is ${response.numberOfAutoScalingGroups}") } } suspend fun terminateInstanceInAutoScalingGroup(instanceIdVal: String) { val request = TerminateInstanceInAutoScalingGroupRequest { instanceId = instanceIdVal shouldDecrementDesiredCapacity = false } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> autoScalingClient.terminateInstanceInAutoScalingGroup(request) println("You have terminated instance $instanceIdVal") } } suspend fun deleteSpecificAutoScalingGroup(groupName: String) { val deleteAutoScalingGroupRequest = DeleteAutoScalingGroupRequest { autoScalingGroupName = groupName forceDelete = true } AutoScalingClient { region = "us-east-1" }.use { autoScalingClient -> autoScalingClient.deleteAutoScalingGroup(deleteAutoScalingGroupRequest) println("You successfully deleted $groupName") } }
PHP
SDK for PHP
注記

については、「」を参照してください GitHub。AWS コード例リポジトリ で全く同じ例を見つけて、設定と実行の方法を確認してください。

namespace AutoScaling; use Aws\AutoScaling\AutoScalingClient; use Aws\CloudWatch\CloudWatchClient; use Aws\Ec2\Ec2Client; use AwsUtilities\AWSServiceClass; use AwsUtilities\RunnableExample; class GettingStartedWithAutoScaling implements RunnableExample { protected Ec2Client $ec2Client; protected AutoScalingClient $autoScalingClient; protected AutoScalingService $autoScalingService; protected CloudWatchClient $cloudWatchClient; protected string $templateName; protected string $autoScalingGroupName; protected array $role; public function runExample() { echo("\n"); echo("--------------------------------------\n"); print("Welcome to the Amazon EC2 Auto Scaling getting started demo using PHP!\n"); echo("--------------------------------------\n"); $clientArgs = [ 'region' => 'us-west-2', 'version' => 'latest', 'profile' => 'default', ]; $uniqid = uniqid(); $this->autoScalingClient = new AutoScalingClient($clientArgs); $this->autoScalingService = new AutoScalingService($this->autoScalingClient); $this->cloudWatchClient = new CloudWatchClient($clientArgs); AWSServiceClass::$waitTime = 5; AWSServiceClass::$maxWaitAttempts = 20; /** * Step 0: Create an EC2 launch template that you'll use to create an Auto Scaling group. */ $this->ec2Client = new EC2Client($clientArgs); $this->templateName = "example_launch_template_$uniqid"; $instanceType = "t1.micro"; $amiId = "ami-0ca285d4c2cda3300"; $launchTemplate = $this->ec2Client->createLaunchTemplate( [ 'LaunchTemplateName' => $this->templateName, 'LaunchTemplateData' => [ 'InstanceType' => $instanceType, 'ImageId' => $amiId, ] ] ); /** * Step 1: CreateAutoScalingGroup: pass it the launch template you created in step 0. */ $availabilityZones[] = $this->ec2Client->describeAvailabilityZones([])['AvailabilityZones'][1]['ZoneName']; $this->autoScalingGroupName = "demoAutoScalingGroupName_$uniqid"; $minSize = 1; $maxSize = 1; $launchTemplateId = $launchTemplate['LaunchTemplate']['LaunchTemplateId']; $this->autoScalingService->createAutoScalingGroup( $this->autoScalingGroupName, $availabilityZones, $minSize, $maxSize, $launchTemplateId ); $this->autoScalingService->waitUntilGroupInService([$this->autoScalingGroupName]); $autoScalingGroup = $this->autoScalingService->describeAutoScalingGroups([$this->autoScalingGroupName]); /** * Step 2: DescribeAutoScalingInstances: show that one instance has launched. */ $instanceIds = [$autoScalingGroup['AutoScalingGroups'][0]['Instances'][0]['InstanceId']]; $instances = $this->autoScalingService->describeAutoScalingInstances($instanceIds); echo "The Auto Scaling group {$this->autoScalingGroupName} was created successfully.\n"; echo count($instances['AutoScalingInstances']) . " instances were created for the group.\n"; echo $autoScalingGroup['AutoScalingGroups'][0]['MaxSize'] . " is the max number of instances for the group.\n"; /** * Step 3: EnableMetricsCollection: enable all metrics or a subset. */ $this->autoScalingService->enableMetricsCollection($this->autoScalingGroupName, "1Minute"); /** * Step 4: UpdateAutoScalingGroup: update max size to 3. */ echo "Updating the max number of instances to 3.\n"; $this->autoScalingService->updateAutoScalingGroup($this->autoScalingGroupName, ['MaxSize' => 3]); /** * Step 5: DescribeAutoScalingGroups: show the current state of the group. */ $autoScalingGroup = $this->autoScalingService->describeAutoScalingGroups([$this->autoScalingGroupName]); echo $autoScalingGroup['AutoScalingGroups'][0]['MaxSize']; echo " is the updated max number of instances for the group.\n"; $limits = $this->autoScalingService->describeAccountLimits(); echo "Here are your account limits:\n"; echo "MaxNumberOfAutoScalingGroups: {$limits['MaxNumberOfAutoScalingGroups']}\n"; echo "MaxNumberOfLaunchConfigurations: {$limits['MaxNumberOfLaunchConfigurations']}\n"; echo "NumberOfAutoScalingGroups: {$limits['NumberOfAutoScalingGroups']}\n"; echo "NumberOfLaunchConfigurations: {$limits['NumberOfLaunchConfigurations']}\n"; /** * Step 6: SetDesiredCapacity: set desired capacity to 2. */ $this->autoScalingService->setDesiredCapacity($this->autoScalingGroupName, 2); sleep(10); // Wait for the group to start processing the request. $this->autoScalingService->waitUntilGroupInService([$this->autoScalingGroupName]); /** * Step 7: DescribeAutoScalingInstances: show that two instances are launched. */ $autoScalingGroups = $this->autoScalingService->describeAutoScalingGroups([$this->autoScalingGroupName]); foreach ($autoScalingGroups['AutoScalingGroups'] as $autoScalingGroup) { echo "There is a group named: {$autoScalingGroup['AutoScalingGroupName']}"; echo "with an ARN of {$autoScalingGroup['AutoScalingGroupARN']}.\n"; foreach ($autoScalingGroup['Instances'] as $instance) { echo "{$autoScalingGroup['AutoScalingGroupName']} has an instance with id of: "; echo "{$instance['InstanceId']} and a lifecycle state of: {$instance['LifecycleState']}.\n"; } } /** * Step 8: TerminateInstanceInAutoScalingGroup: terminate one of the instances in the group. */ $this->autoScalingService->terminateInstanceInAutoScalingGroup($instance['InstanceId'], false); do { sleep(10); $instances = $this->autoScalingService->describeAutoScalingInstances([$instance['InstanceId']]); } while (count($instances['AutoScalingInstances']) > 0); do { sleep(10); $autoScalingGroups = $this->autoScalingService->describeAutoScalingGroups([$this->autoScalingGroupName]); $instances = $autoScalingGroups['AutoScalingGroups'][0]['Instances']; } while (count($instances) < 2); $this->autoScalingService->waitUntilGroupInService([$this->autoScalingGroupName]); foreach ($autoScalingGroups['AutoScalingGroups'] as $autoScalingGroup) { echo "There is a group named: {$autoScalingGroup['AutoScalingGroupName']}"; echo "with an ARN of {$autoScalingGroup['AutoScalingGroupARN']}.\n"; foreach ($autoScalingGroup['Instances'] as $instance) { echo "{$autoScalingGroup['AutoScalingGroupName']} has an instance with id of: "; echo "{$instance['InstanceId']} and a lifecycle state of: {$instance['LifecycleState']}.\n"; } } /** * Step 9: DescribeScalingActivities: list the scaling activities that have occurred for the group so far. */ $activities = $this->autoScalingService->describeScalingActivities($autoScalingGroup['AutoScalingGroupName']); echo "We found " . count($activities['Activities']) . " activities.\n"; foreach ($activities['Activities'] as $activity) { echo "{$activity['ActivityId']} - {$activity['StartTime']} - {$activity['Description']}\n"; } /** * Step 10: Use the Amazon CloudWatch API to get and show some metrics collected for the group. */ $metricsNamespace = 'AWS/AutoScaling'; $metricsDimensions = [ [ 'Name' => 'AutoScalingGroupName', 'Value' => $autoScalingGroup['AutoScalingGroupName'], ], ]; $metrics = $this->cloudWatchClient->listMetrics( [ 'Dimensions' => $metricsDimensions, 'Namespace' => $metricsNamespace, ] ); foreach ($metrics['Metrics'] as $metric) { $timespan = 5; if ($metric['MetricName'] != 'GroupTotalCapacity' && $metric['MetricName'] != 'GroupMaxSize') { continue; } echo "Over the last $timespan minutes, {$metric['MetricName']} recorded:\n"; $stats = $this->cloudWatchClient->getMetricStatistics( [ 'Dimensions' => $metricsDimensions, 'EndTime' => time(), 'StartTime' => time() - (5 * 60), 'MetricName' => $metric['MetricName'], 'Namespace' => $metricsNamespace, 'Period' => 60, 'Statistics' => ['Sum'], ] ); foreach ($stats['Datapoints'] as $stat) { echo "{$stat['Timestamp']}: {$stat['Sum']}\n"; } } return $instances; } public function cleanUp() { /** * Step 11: DisableMetricsCollection: disable all metrics. */ $this->autoScalingService->disableMetricsCollection($this->autoScalingGroupName); /** * Step 12: DeleteAutoScalingGroup: to delete the group you must stop all instances. * - UpdateAutoScalingGroup with MinSize=0 * - TerminateInstanceInAutoScalingGroup for each instance, * specify ShouldDecrementDesiredCapacity=True. Wait for instances to stop. * - Now you can delete the group. */ $this->autoScalingService->updateAutoScalingGroup($this->autoScalingGroupName, ['MinSize' => 0]); $this->autoScalingService->terminateAllInstancesInAutoScalingGroup($this->autoScalingGroupName); $this->autoScalingService->waitUntilGroupInService([$this->autoScalingGroupName]); $this->autoScalingService->deleteAutoScalingGroup($this->autoScalingGroupName); /** * Step 13: Delete launch template. */ $this->ec2Client->deleteLaunchTemplate( [ 'LaunchTemplateName' => $this->templateName, ] ); } public function helloService() { $autoScalingClient = new AutoScalingClient([ 'region' => 'us-west-2', 'version' => 'latest', 'profile' => 'default', ]); $groups = $autoScalingClient->describeAutoScalingGroups([]); var_dump($groups); } }
Python
SDK for Python (Boto3)
注記

については、「」を参照してください GitHub。AWS コード例リポジトリ で全く同じ例を見つけて、設定と実行の方法を確認してください。

コマンドプロンプトからインタラクティブのシナリオを実行します。

def run_scenario(as_wrapper, svc_helper): logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") print("-" * 88) print( "Welcome to the Amazon EC2 Auto Scaling demo for managing groups and instances." ) print("-" * 88) print( "This example requires a launch template that specifies how to create\n" "EC2 instances. You can use an existing template or create a new one." ) template_name = q.ask( "Enter the name of an existing launch template or press Enter to create a new one: " ) template = None if template_name: template = svc_helper.get_template(template_name) if template is None: inst_type = "t1.micro" ami_id = "ami-0ca285d4c2cda3300" print("Let's create a launch template with the following specifications:") print(f"\tInstanceType: {inst_type}") print(f"\tAMI ID: {ami_id}") template_name = q.ask("Enter a name for the template: ", q.non_empty) template = svc_helper.create_template(template_name, inst_type, ami_id) print("-" * 88) print("Let's create an Auto Scaling group.") group_name = q.ask("Enter a name for the group: ", q.non_empty) zones = svc_helper.get_availability_zones() print("EC2 instances can be created in the following Availability Zones:") for index, zone in enumerate(zones): print(f"\t{index+1}. {zone}") print(f"\t{len(zones)+1}. All zones") zone_sel = q.ask( "Which zone do you want to use? ", q.is_int, q.in_range(1, len(zones) + 1) ) group_zones = [zones[zone_sel - 1]] if zone_sel <= len(zones) else zones print(f"Creating group {group_name}...") as_wrapper.create_group(group_name, group_zones, template_name, 1, 1) wait(10) group = as_wrapper.describe_group(group_name) print("Created group:") pp(group) print("Waiting for instance to start...") wait_for_group(group_name, as_wrapper) print("-" * 88) use_metrics = q.ask( "Do you want to collect metrics about Amazon EC2 Auto Scaling during this demo (y/n)? ", q.is_yesno, ) if use_metrics: as_wrapper.enable_metrics( group_name, [ "GroupMinSize", "GroupMaxSize", "GroupDesiredCapacity", "GroupInServiceInstances", "GroupTotalInstances", ], ) print(f"Metrics enabled for {group_name}.") print("-" * 88) print(f"Let's update the maximum number of instances in {group_name} from 1 to 3.") q.ask("Press Enter when you're ready.") as_wrapper.update_group(group_name, MaxSize=3) group = as_wrapper.describe_group(group_name) print("The group still has one running instance, but can have up to three:") print_simplified_group(group) print("-" * 88) print(f"Let's update the desired capacity of {group_name} from 1 to 2.") q.ask("Press Enter when you're ready.") as_wrapper.set_desired_capacity(group_name, 2) wait(10) group = as_wrapper.describe_group(group_name) print("Here's the current state of the group:") print_simplified_group(group) print("-" * 88) print("Waiting for the new instance to start...") instance_ids = wait_for_group(group_name, as_wrapper) print("-" * 88) print(f"Let's terminate one of the instances in {group_name}.") print("Because the desired capacity is 2, another instance will start.") print("The currently running instances are:") for index, inst_id in enumerate(instance_ids): print(f"\t{index+1}. {inst_id}") inst_sel = q.ask( "Which instance do you want to stop? ", q.is_int, q.in_range(1, len(instance_ids) + 1), ) print(f"Stopping {instance_ids[inst_sel-1]}...") as_wrapper.terminate_instance(instance_ids[inst_sel - 1], False) wait(10) group = as_wrapper.describe_group(group_name) print(f"Here's the state of {group_name}:") print_simplified_group(group) print("Waiting for the scaling activities to complete...") wait_for_group(group_name, as_wrapper) print("-" * 88) print(f"Let's get a report of scaling activities for {group_name}.") q.ask("Press Enter when you're ready.") activities = as_wrapper.describe_scaling_activities(group_name) print( f"Found {len(activities)} activities.\n" f"Activities are ordered with the most recent one first:" ) for act in activities: pp(act) print("-" * 88) if use_metrics: print("Let's look at CloudWatch metrics.") metric_namespace = "AWS/AutoScaling" metric_dimensions = [{"Name": "AutoScalingGroupName", "Value": group_name}] print(f"The following metrics are enabled for {group_name}:") done = False while not done: metrics = svc_helper.get_metrics(metric_namespace, metric_dimensions) for index, metric in enumerate(metrics): print(f"\t{index+1}. {metric.name}") print(f"\t{len(metrics)+1}. None") metric_sel = q.ask( "Which metric do you want to see? ", q.is_int, q.in_range(1, len(metrics) + 1), ) if metric_sel < len(metrics) + 1: span = 5 metric = metrics[metric_sel - 1] print(f"Over the last {span} minutes, {metric.name} recorded:") # CloudWatch metric times are in the UTC+0 time zone. now = datetime.now(timezone.utc) metric_data = svc_helper.get_metric_statistics( metric_dimensions, metric, now - timedelta(minutes=span), now ) pp(metric_data) if not q.ask("Do you want to see another metric (y/n)? ", q.is_yesno): done = True else: done = True print(f"Let's clean up.") q.ask("Press Enter when you're ready.") if use_metrics: print(f"Stopping metrics collection for {group_name}.") as_wrapper.disable_metrics(group_name) print( "You must terminate all instances in the group before you can delete the group." ) print("Set minimum size to 0.") as_wrapper.update_group(group_name, MinSize=0) group = as_wrapper.describe_group(group_name) instance_ids = [inst["InstanceId"] for inst in group["Instances"]] for inst_id in instance_ids: print(f"Stopping {inst_id}.") as_wrapper.terminate_instance(inst_id, True) print("Waiting for instances to stop...") wait_for_instances(instance_ids, as_wrapper) print(f"Deleting {group_name}.") as_wrapper.delete_group(group_name) print("-" * 88) if template is not None: if q.ask( f"Do you want to delete launch template {template_name} used in this demo (y/n)? " ): svc_helper.delete_template(template_name) print("Template deleted.") print("\nThanks for watching!") print("-" * 88) if __name__ == "__main__": try: wrapper = AutoScalingWrapper(boto3.client("autoscaling")) helper = ServiceHelper(boto3.client("ec2"), boto3.resource("cloudwatch")) run_scenario(wrapper, helper) except Exception: logging.exception("Something went wrong with the demo!")

起動テンプレートとメトリクスを管理するためにシナリオによって呼び出される関数を定義します。これらの関数はAmazon EC2 および CloudWatch アクションをラップします。

class ServiceHelper: """Encapsulates Amazon EC2 and CloudWatch actions for the example.""" def __init__(self, ec2_client, cloudwatch_resource): """ :param ec2_client: A Boto3 Amazon EC2 client. :param cloudwatch_resource: A Boto3 CloudWatch resource. """ self.ec2_client = ec2_client self.cloudwatch_resource = cloudwatch_resource def get_template(self, template_name): """ Gets a launch template. Launch templates specify configuration for instances that are launched by Amazon EC2 Auto Scaling. :param template_name: The name of the template to look up. :return: The template, if it exists. """ try: response = self.ec2_client.describe_launch_templates( LaunchTemplateNames=[template_name] ) template = response["LaunchTemplates"][0] except ClientError as err: if ( err.response["Error"]["Code"] == "InvalidLaunchTemplateName.NotFoundException" ): logger.warning("Launch template %s does not exist.", template_name) else: logger.error( "Couldn't verify launch template %s. Here's why: %s: %s", template_name, err.response["Error"]["Code"], err.response["Error"]["Message"], ) raise else: return template def create_template(self, template_name, inst_type, ami_id): """ Creates an Amazon EC2 launch template to use with Amazon EC2 Auto Scaling. :param template_name: The name to give to the template. :param inst_type: The type of the instance, such as t1.micro. :param ami_id: The ID of the Amazon Machine Image (AMI) to use when creating an instance. :return: Information about the newly created template. """ try: response = self.ec2_client.create_launch_template( LaunchTemplateName=template_name, LaunchTemplateData={"InstanceType": inst_type, "ImageId": ami_id}, ) template = response["LaunchTemplate"] except ClientError as err: logger.error( "Couldn't create launch template %s. Here's why: %s: %s", template_name, err.response["Error"]["Code"], err.response["Error"]["Message"], ) raise else: return template def delete_template(self, template_name): """ Deletes a launch template. :param template_name: The name of the template to delete. """ try: self.ec2_client.delete_launch_template(LaunchTemplateName=template_name) except ClientError as err: logger.error( "Couldn't delete launch template %s. Here's why: %s: %s", template_name, err.response["Error"]["Code"], err.response["Error"]["Message"], ) raise def get_availability_zones(self): """ Gets a list of Availability Zones in the AWS Region of the Amazon EC2 client. :return: The list of Availability Zones for the client Region. """ try: response = self.ec2_client.describe_availability_zones() zones = [zone["ZoneName"] for zone in response["AvailabilityZones"]] except ClientError as err: logger.error( "Couldn't get availability zones. Here's why: %s: %s", err.response["Error"]["Code"], err.response["Error"]["Message"], ) raise else: return zones def get_metrics(self, namespace, dimensions): """ Gets a list of CloudWatch metrics filtered by namespace and dimensions. :param namespace: The namespace of the metrics to look up. :param dimensions: The dimensions of the metrics to look up. :return: The list of metrics. """ try: metrics = list( self.cloudwatch_resource.metrics.filter( Namespace=namespace, Dimensions=dimensions ) ) except ClientError as err: logger.error( "Couldn't get metrics for %s, %s. Here's why: %s: %s", namespace, dimensions, err.response["Error"]["Code"], err.response["Error"]["Message"], ) raise else: return metrics @staticmethod def get_metric_statistics(dimensions, metric, start, end): """ Gets statistics for a CloudWatch metric within a specified time span. :param dimensions: The dimensions of the metric. :param metric: The metric to look up. :param start: The start of the time span for retrieved metrics. :param end: The end of the time span for retrieved metrics. :return: The list of data points found for the specified metric. """ try: response = metric.get_statistics( Dimensions=dimensions, StartTime=start, EndTime=end, Period=60, Statistics=["Sum"], ) data = response["Datapoints"] except ClientError as err: logger.error( "Couldn't get statistics for metric %s. Here's why: %s: %s", metric.name, err.response["Error"]["Code"], err.response["Error"]["Message"], ) raise else: return data def print_simplified_group(group): """ Prints a subset of data for an Auto Scaling group. """ print(group["AutoScalingGroupName"]) print(f"\tLaunch template: {group['LaunchTemplate']['LaunchTemplateName']}") print( f"\tMin: {group['MinSize']}, Max: {group['MaxSize']}, Desired: {group['DesiredCapacity']}" ) if group["Instances"]: print(f"\tInstances:") for inst in group["Instances"]: print(f"\t\t{inst['InstanceId']}: {inst['LifecycleState']}") def wait_for_group(group_name, as_wrapper): """ Waits for instances to start or stop in an Auto Scaling group. Prints the data for each instance after scaling activities are complete. """ group = as_wrapper.describe_group(group_name) instance_ids = [i["InstanceId"] for i in group["Instances"]] return wait_for_instances(instance_ids, as_wrapper) def wait_for_instances(instance_ids, as_wrapper): """ Waits for instances to start or stop in an Auto Scaling group. Prints the data for each instance after scaling activities are complete. """ ready = False instances = [] while not ready: instances = as_wrapper.describe_instances(instance_ids) if instance_ids else [] if all([x["LifecycleState"] in ["Terminated", "InService"] for x in instances]): ready = True else: wait(10) if instances: print( f"Here are the details of the instance{'s' if len(instances) > 1 else ''}:" ) for instance in instances: pp(instance) return instance_ids
Rust
SDK for Rust
注記

については、「」を参照してください GitHub。用例一覧を検索し、AWS コード例リポジトリでの設定と実行の方法を確認してください。

[package] name = "autoscaling-code-examples" version = "0.1.0" authors = ["Doug Schwartz <dougsch@amazon.com>", "David Souther <dpsouth@amazon.com>"] edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] aws-config = { version = "1.0.1", features = ["behavior-version-latest"] } aws-sdk-autoscaling = { version = "1.3.0" } aws-sdk-ec2 = { version = "1.3.0" } aws-types = { version = "1.0.1" } tokio = { version = "1.20.1", features = ["full"] } clap = { version = "~4.4", features = ["derive"] } tracing-subscriber = { version = "0.3.15", features = ["env-filter"] } anyhow = "1.0.75" tracing = "0.1.37" tokio-stream = "0.1.14" // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 use std::{collections::BTreeSet, fmt::Display}; use anyhow::anyhow; use autoscaling_code_examples::scenario::{AutoScalingScenario, ScenarioError}; use tracing::{info, warn}; async fn show_scenario_description(scenario: &AutoScalingScenario, event: &str) { let description = scenario.describe_scenario().await; info!("DescribeAutoScalingInstances: {event}\n{description}"); } #[derive(Default, Debug)] struct Warnings(Vec<String>); impl Warnings { pub fn push(&mut self, warning: &str, error: ScenarioError) { let formatted = format!("{warning}: {error}"); warn!("{formatted}"); self.0.push(formatted); } pub fn is_empty(&self) -> bool { self.0.is_empty() } } impl Display for Warnings { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { writeln!(f, "Warnings:")?; for warning in &self.0 { writeln!(f, "{: >4}- {warning}", "")?; } Ok(()) } } #[tokio::main] async fn main() -> Result<(), anyhow::Error> { tracing_subscriber::fmt::init(); let shared_config = aws_config::from_env().load().await; let mut warnings = Warnings::default(); // 1. Create an EC2 launch template that you'll use to create an auto scaling group. Bonus: use SDK with EC2.CreateLaunchTemplate to create the launch template. // 2. CreateAutoScalingGroup: pass it the launch template you created in step 0. Give it min/max of 1 instance. // 4. EnableMetricsCollection: enable all metrics or a subset. let scenario = match AutoScalingScenario::prepare_scenario(&shared_config).await { Ok(scenario) => scenario, Err(errs) => { let err_str = errs .into_iter() .map(|e| e.to_string()) .collect::<Vec<String>>() .join(", "); return Err(anyhow!("Failed to initialize scenario: {err_str}")); } }; info!("Prepared autoscaling scenario:\n{scenario}"); let stable = scenario.wait_for_stable(1).await; if let Err(err) = stable { warnings.push( "There was a problem while waiting for group to be stable", err, ); } // 3. DescribeAutoScalingInstances: show that one instance has launched. show_scenario_description( &scenario, "show that the group was created and one instance has launched", ) .await; // 5. UpdateAutoScalingGroup: update max size to 3. let scale_max_size = scenario.scale_max_size(3).await; if let Err(err) = scale_max_size { warnings.push("There was a problem scaling max size", err); } // 6. DescribeAutoScalingGroups: the current state of the group show_scenario_description( &scenario, "show the current state of the group after setting max size", ) .await; // 7. SetDesiredCapacity: set desired capacity to 2. let scale_desired_capacity = scenario.scale_desired_capacity(2).await; if let Err(err) = scale_desired_capacity { warnings.push("There was a problem setting desired capacity", err); } // Wait for a second instance to launch. let stable = scenario.wait_for_stable(2).await; if let Err(err) = stable { warnings.push( "There was a problem while waiting for group to be stable", err, ); } // 8. DescribeAutoScalingInstances: show that two instances are launched. show_scenario_description( &scenario, "show that two instances are launched after setting desired capacity", ) .await; let ids_before = scenario .list_instances() .await .map(|v| v.into_iter().collect::<BTreeSet<_>>()) .unwrap_or_default(); // 9. TerminateInstanceInAutoScalingGroup: terminate one of the instances in the group. let terminate_some_instance = scenario.terminate_some_instance().await; if let Err(err) = terminate_some_instance { warnings.push("There was a problem replacing an instance", err); } let wait_after_terminate = scenario.wait_for_stable(1).await; if let Err(err) = wait_after_terminate { warnings.push( "There was a problem waiting after terminating an instance", err, ); } let wait_scale_up_after_terminate = scenario.wait_for_stable(2).await; if let Err(err) = wait_scale_up_after_terminate { warnings.push( "There was a problem waiting for scale up after terminating an instance", err, ); } let ids_after = scenario .list_instances() .await .map(|v| v.into_iter().collect::<BTreeSet<_>>()) .unwrap_or_default(); let difference = ids_after.intersection(&ids_before).count(); if !(difference == 1 && ids_before.len() == 2 && ids_after.len() == 2) { warnings.push( "Before and after set not different", ScenarioError::with(format!("{difference}")), ); } // 10. DescribeScalingActivities: list the scaling activities that have occurred for the group so far. show_scenario_description( &scenario, "list the scaling activities that have occurred for the group so far", ) .await; // 11. DisableMetricsCollection let scale_group = scenario.scale_group_to_zero().await; if let Err(err) = scale_group { warnings.push("There was a problem scaling the group to 0", err); } show_scenario_description(&scenario, "Scenario scaled to 0").await; // 12. DeleteAutoScalingGroup (to delete the group you must stop all instances): // 13. Delete LaunchTemplate. let clean_scenario = scenario.clean_scenario().await; if let Err(errs) = clean_scenario { for err in errs { warnings.push("There was a problem cleaning the scenario", err); } } else { info!("The scenario has been cleaned up!"); } if warnings.is_empty() { Ok(()) } else { Err(anyhow!( "There were warnings during scenario execution:\n{warnings}" )) } } pub mod scenario; // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 use std::{ error::Error, fmt::{Debug, Display}, time::{Duration, SystemTime}, }; use anyhow::anyhow; use aws_config::SdkConfig; use aws_sdk_autoscaling::{ error::{DisplayErrorContext, ProvideErrorMetadata}, types::{Activity, AutoScalingGroup, LaunchTemplateSpecification}, }; use aws_sdk_ec2::types::RequestLaunchTemplateData; use tracing::trace; const LAUNCH_TEMPLATE_NAME: &str = "SDK_Code_Examples_EC2_Autoscaling_template_from_Rust_SDK"; const AUTOSCALING_GROUP_NAME: &str = "SDK_Code_Examples_EC2_Autoscaling_Group_from_Rust_SDK"; const MAX_WAIT: Duration = Duration::from_secs(5 * 60); // Wait at most 25 seconds. const WAIT_TIME: Duration = Duration::from_millis(500); // Wait half a second at a time. struct Waiter { start: SystemTime, max: Duration, } impl Waiter { fn new() -> Self { Waiter { start: SystemTime::now(), max: MAX_WAIT, } } async fn sleep(&self) -> Result<(), ScenarioError> { if SystemTime::now() .duration_since(self.start) .unwrap_or(Duration::MAX) > self.max { Err(ScenarioError::with( "Exceeded maximum wait duration for stable group", )) } else { tokio::time::sleep(WAIT_TIME).await; Ok(()) } } } pub struct AutoScalingScenario { ec2: aws_sdk_ec2::Client, autoscaling: aws_sdk_autoscaling::Client, launch_template_arn: String, auto_scaling_group_name: String, } impl Display for AutoScalingScenario { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!( "\tLaunch Template ID: {}\n", self.launch_template_arn ))?; f.write_fmt(format_args!( "\tScaling Group Name: {}\n", self.auto_scaling_group_name ))?; Ok(()) } } pub struct AutoScalingScenarioDescription { group: Result<Vec<String>, ScenarioError>, instances: Result<Vec<String>, anyhow::Error>, activities: Result<Vec<Activity>, anyhow::Error>, } impl Display for AutoScalingScenarioDescription { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { writeln!(f, "\t Group status:")?; match &self.group { Ok(groups) => { for status in groups { writeln!(f, "\t\t- {status}")?; } } Err(e) => writeln!(f, "\t\t! - {e}")?, } writeln!(f, "\t Instances:")?; match &self.instances { Ok(instances) => { for instance in instances { writeln!(f, "\t\t- {instance}")?; } } Err(e) => writeln!(f, "\t\t! {e}")?, } writeln!(f, "\t Activities:")?; match &self.activities { Ok(activities) => { for activity in activities { writeln!( f, "\t\t- {} Progress: {}% Status: {:?} End: {:?}", activity.cause().unwrap_or("Unknown"), activity.progress.unwrap_or(-1), activity.status_code(), // activity.status_message().unwrap_or_default() activity.end_time(), )?; } } Err(e) => writeln!(f, "\t\t! {e}")?, } Ok(()) } } #[derive(Debug)] struct MetadataError { message: Option<String>, code: Option<String>, } impl MetadataError { fn from(err: &dyn ProvideErrorMetadata) -> Self { MetadataError { message: err.message().map(|s| s.to_string()), code: err.code().map(|s| s.to_string()), } } } impl Display for MetadataError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let display = match (&self.message, &self.code) { (None, None) => "Unknown".to_string(), (None, Some(code)) => format!("({code})"), (Some(message), None) => message.to_string(), (Some(message), Some(code)) => format!("{message} ({code})"), }; write!(f, "{display}") } } #[derive(Debug)] pub struct ScenarioError { message: String, context: Option<MetadataError>, } impl ScenarioError { pub fn with(message: impl Into<String>) -> Self { ScenarioError { message: message.into(), context: None, } } pub fn new(message: impl Into<String>, err: &dyn ProvideErrorMetadata) -> Self { ScenarioError { message: message.into(), context: Some(MetadataError::from(err)), } } } impl Error for ScenarioError { // While `Error` can capture `source` information about the underlying error, for this example // the ScenarioError captures the underlying information in MetadataError and treats it as a // single Error from this Crate. In other contexts, it may be appropriate to model the error // as including the SdkError as its source. } impl Display for ScenarioError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self.context { Some(c) => write!(f, "{}: {}", self.message, c), None => write!(f, "{}", self.message), } } } impl AutoScalingScenario { pub async fn prepare_scenario(sdk_config: &SdkConfig) -> Result<Self, Vec<ScenarioError>> { let ec2 = aws_sdk_ec2::Client::new(sdk_config); let autoscaling = aws_sdk_autoscaling::Client::new(sdk_config); let auto_scaling_group_name = String::from(AUTOSCALING_GROUP_NAME); // Before creating any resources, prepare the list of AZs let availablity_zones = ec2.describe_availability_zones().send().await; if let Err(err) = availablity_zones { return Err(vec![ScenarioError::new("Failed to find AZs", &err)]); } let availability_zones: Vec<String> = availablity_zones .unwrap() .availability_zones .unwrap_or_default() .iter() .take(3) .map(|z| z.zone_name.clone().unwrap()) .collect(); // 1. Create an EC2 launch template that you'll use to create an auto scaling group. Bonus: use SDK with EC2.CreateLaunchTemplate to create the launch template. // * Recommended: InstanceType='t1.micro', ImageId='ami-0ca285d4c2cda3300' let create_launch_template = ec2 .create_launch_template() .launch_template_name(LAUNCH_TEMPLATE_NAME) .launch_template_data( RequestLaunchTemplateData::builder() .instance_type(aws_sdk_ec2::types::InstanceType::T1Micro) .image_id("ami-0ca285d4c2cda3300") .build(), ) .send() .await .map_err(|err| vec![ScenarioError::new("Failed to create launch template", &err)])?; let launch_template_arn = match create_launch_template.launch_template { Some(launch_template) => launch_template.launch_template_id.unwrap_or_default(), None => { // Try to delete the launch template let _ = ec2 .delete_launch_template() .launch_template_name(LAUNCH_TEMPLATE_NAME) .send() .await; return Err(vec![ScenarioError::with("Failed to load launch template")]); } }; // 2. CreateAutoScalingGroup: pass it the launch template you created in step 0. Give it min/max of 1 instance. // You can use EC2.describe_availability_zones() to get a list of AZs (you have to specify an AZ when you create the group). // Wait for instance to launch. Use a waiter if you have one, otherwise DescribeAutoScalingInstances until LifecycleState='InService' if let Err(err) = autoscaling .create_auto_scaling_group() .auto_scaling_group_name(auto_scaling_group_name.as_str()) .launch_template( LaunchTemplateSpecification::builder() .launch_template_id(launch_template_arn.clone()) .version("$Latest") .build(), ) .max_size(1) .min_size(1) .set_availability_zones(Some(availability_zones)) .send() .await { let mut errs = vec![ScenarioError::new( "Failed to create autoscaling group", &err, )]; if let Err(err) = autoscaling .delete_auto_scaling_group() .auto_scaling_group_name(auto_scaling_group_name.as_str()) .send() .await { errs.push(ScenarioError::new( "Failed to clean up autoscaling group", &err, )); } if let Err(err) = ec2 .delete_launch_template() .launch_template_id(launch_template_arn.clone()) .send() .await { errs.push(ScenarioError::new( "Failed to clean up launch template", &err, )); } return Err(errs); } let scenario = AutoScalingScenario { ec2, autoscaling: autoscaling.clone(), // Clients are cheap so cloning here to prevent a move is ok. auto_scaling_group_name: auto_scaling_group_name.clone(), launch_template_arn, }; // snippet-start:[rust.auto-scaling.scenario.enable_metrics_collection] let enable_metrics_collection = autoscaling .enable_metrics_collection() .auto_scaling_group_name(auto_scaling_group_name.as_str()) .granularity("1Minute") .set_metrics(Some(vec![ String::from("GroupMinSize"), String::from("GroupMaxSize"), String::from("GroupDesiredCapacity"), String::from("GroupInServiceInstances"), String::from("GroupTotalInstances"), ])) .send() .await; // snippet-end:[rust.auto-scaling.scenario.enable_metrics_collection] match enable_metrics_collection { Ok(_) => Ok(scenario), Err(err) => { scenario.clean_scenario().await?; Err(vec![ScenarioError::new( "Failed to enable metrics collections for group", &err, )]) } } } pub async fn clean_scenario(self) -> Result<(), Vec<ScenarioError>> { let _ = self.wait_for_no_scaling().await; let delete_group = self .autoscaling .delete_auto_scaling_group() .auto_scaling_group_name(self.auto_scaling_group_name.clone()) .send() .await; // 14. Delete LaunchTemplate. let delete_launch_template = self .ec2 .delete_launch_template() .launch_template_id(self.launch_template_arn.clone()) .send() .await; let early_exit = match (delete_group, delete_launch_template) { (Ok(_), Ok(_)) => Ok(()), (Ok(_), Err(e)) => Err(vec![ScenarioError::new( "There was an error cleaning the launch template", &e, )]), (Err(e), Ok(_)) => Err(vec![ScenarioError::new( "There was an error cleaning the scale group", &e, )]), (Err(e1), Err(e2)) => Err(vec![ ScenarioError::new("Multiple error cleaning the scenario Scale Group", &e1), ScenarioError::new("Multiple error cleaning the scenario Launch Template", &e2), ]), }; if early_exit.is_err() { early_exit } else { // Wait for delete_group to finish let waiter = Waiter::new(); let mut errors = Vec::<ScenarioError>::new(); while errors.len() < 3 { if let Err(e) = waiter.sleep().await { errors.push(e); continue; } let describe_group = self .autoscaling .describe_auto_scaling_groups() .auto_scaling_group_names(self.auto_scaling_group_name.clone()) .send() .await; match describe_group { Ok(group) => match group.auto_scaling_groups().first() { Some(group) => { if group.status() != Some("Delete in progress") { errors.push(ScenarioError::with(format!( "Group in an unknown state while deleting: {}", group.status().unwrap_or("unknown error") ))); return Err(errors); } } None => return Ok(()), }, Err(err) => { errors.push(ScenarioError::new("Failed to describe autoscaling group during cleanup 3 times, last error", &err)); } } if errors.len() > 3 { return Err(errors); } } Err(vec![ScenarioError::with( "Exited cleanup wait loop without retuning success or failing after three rounds", )]) } } // snippet-start:[rust.auto-scaling.scenario.describe_scenario] pub async fn describe_scenario(&self) -> AutoScalingScenarioDescription { let group = self .autoscaling .describe_auto_scaling_groups() .auto_scaling_group_names(self.auto_scaling_group_name.clone()) .send() .await .map(|s| { s.auto_scaling_groups() .iter() .map(|s| { format!( "{}: {}", s.auto_scaling_group_name().unwrap_or("Unknown"), s.status().unwrap_or("Unknown") ) }) .collect::<Vec<String>>() }) .map_err(|e| { ScenarioError::new("Failed to describe auto scaling groups for scenario", &e) }); let instances = self .list_instances() .await .map_err(|e| anyhow!("There was an error listing instances: {e}",)); // 10. DescribeScalingActivities: list the scaling activities that have occurred for the group so far. // Bonus: use CloudWatch API to get and show some metrics collected for the group. // CW.ListMetrics with Namespace='AWS/AutoScaling' and Dimensions=[{'Name': 'AutoScalingGroupName', 'Value': }] // CW.GetMetricStatistics with Statistics='Sum'. Start and End times must be in UTC! let activities = self .autoscaling .describe_scaling_activities() .auto_scaling_group_name(self.auto_scaling_group_name.clone()) .into_paginator() .items() .send() .collect::<Result<Vec<_>, _>>() .await .map_err(|e| { anyhow!( "There was an error retrieving scaling activities: {}", DisplayErrorContext(&e) ) }); AutoScalingScenarioDescription { group, instances, activities, } } // snippet-end:[rust.auto-scaling.scenario.describe_scenario] // snippet-start:[rust.auto-scaling.scenario.get_group] async fn get_group(&self) -> Result<AutoScalingGroup, ScenarioError> { let describe_auto_scaling_groups = self .autoscaling .describe_auto_scaling_groups() .auto_scaling_group_names(self.auto_scaling_group_name.clone()) .send() .await; if let Err(err) = describe_auto_scaling_groups { return Err(ScenarioError::new( format!( "Failed to get status of autoscaling group {}", self.auto_scaling_group_name.clone() ) .as_str(), &err, )); } let describe_auto_scaling_groups_output = describe_auto_scaling_groups.unwrap(); let auto_scaling_groups = describe_auto_scaling_groups_output.auto_scaling_groups(); let auto_scaling_group = auto_scaling_groups.first(); if auto_scaling_group.is_none() { return Err(ScenarioError::with(format!( "Could not find autoscaling group {}", self.auto_scaling_group_name.clone() ))); } Ok(auto_scaling_group.unwrap().clone()) } // snippet-end:[rust.auto-scaling.scenario.get_group] pub async fn wait_for_no_scaling(&self) -> Result<(), ScenarioError> { let waiter = Waiter::new(); let mut scaling = true; while scaling { waiter.sleep().await?; let describe_activities = self .autoscaling .describe_scaling_activities() .auto_scaling_group_name(self.auto_scaling_group_name.clone()) .send() .await .map_err(|e| { ScenarioError::new("Failed to get autoscaling activities for group", &e) })?; let activities = describe_activities.activities(); trace!( "Waiting for no scaling found {} activities", activities.len() ); scaling = activities.iter().any(|a| a.progress() < Some(100)); } Ok(()) } pub async fn wait_for_stable(&self, size: usize) -> Result<(), ScenarioError> { self.wait_for_no_scaling().await?; let mut group = self.get_group().await?; let mut count = count_group_instances(&group); let waiter = Waiter::new(); while count != size { trace!("Waiting for stable {size} (current: {count})"); waiter.sleep().await?; group = self.get_group().await?; count = count_group_instances(&group); } Ok(()) } // snippet-start:[rust.auto-scaling.scenario.list_instances] pub async fn list_instances(&self) -> Result<Vec<String>, ScenarioError> { // The direct way to list instances is by using DescribeAutoScalingGroup's instances property. However, this returns a Vec<Instance>, as opposed to a Vec<AutoScalingInstanceDetails>. // Ok(self.get_group().await?.instances.unwrap_or_default().map(|i| i.instance_id.clone().unwrap_or_default()).filter(|id| !id.is_empty()).collect()) // Alternatively, and for the sake of example, DescribeAutoScalingInstances returns a list that can be filtered by the client. self.autoscaling .describe_auto_scaling_instances() .into_paginator() .items() .send() .try_collect() .await .map(|items| { items .into_iter() .filter(|i| { i.auto_scaling_group_name.as_deref() == Some(self.auto_scaling_group_name.as_str()) }) .map(|i| i.instance_id.unwrap_or_default()) .filter(|id| !id.is_empty()) .collect::<Vec<String>>() }) .map_err(|err| ScenarioError::new("Failed to get list of auto scaling instances", &err)) } // snippet-end:[rust.auto-scaling.scenario.list_instances] pub async fn scale_min_size(&self, size: i32) -> Result<(), ScenarioError> { let update_group = self .autoscaling .update_auto_scaling_group() .auto_scaling_group_name(self.auto_scaling_group_name.clone()) .min_size(size) .send() .await; if let Err(err) = update_group { return Err(ScenarioError::new( format!("Failer to update group to min size ({size}))").as_str(), &err, )); } Ok(()) } pub async fn scale_max_size(&self, size: i32) -> Result<(), ScenarioError> { // 5. UpdateAutoScalingGroup: update max size to 3. let update_group = self .autoscaling .update_auto_scaling_group() .auto_scaling_group_name(self.auto_scaling_group_name.clone()) .max_size(size) .send() .await; if let Err(err) = update_group { return Err(ScenarioError::new( format!("Failed to update group to max size ({size})").as_str(), &err, )); } Ok(()) } // snippet-start:[rust.auto-scaling.scenario.scale_desired_capacity] pub async fn scale_desired_capacity(&self, capacity: i32) -> Result<(), ScenarioError> { // 7. SetDesiredCapacity: set desired capacity to 2. // Wait for a second instance to launch. let update_group = self .autoscaling .set_desired_capacity() .auto_scaling_group_name(self.auto_scaling_group_name.clone()) .desired_capacity(capacity) .send() .await; if let Err(err) = update_group { return Err(ScenarioError::new( format!("Failed to update group to desired capacity ({capacity}))").as_str(), &err, )); } Ok(()) } // snippet-end:[rust.auto-scaling.scenario.scale_desired_capacity] pub async fn scale_group_to_zero(&self) -> Result<(), ScenarioError> { // snippet-start:[rust.auto-scaling.scenario.disable_metrics_collection] // If this fails it's fine, just means there are extra cloudwatch metrics events for the scale-down. let _ = self .autoscaling .disable_metrics_collection() .auto_scaling_group_name(self.auto_scaling_group_name.clone()) .send() .await; // snippet-end:[rust.auto-scaling.scenario.disable_metrics_collection] // 12. DeleteAutoScalingGroup (to delete the group you must stop all instances): // UpdateAutoScalingGroup with MinSize=0 let update_group = self .autoscaling .update_auto_scaling_group() .auto_scaling_group_name(self.auto_scaling_group_name.clone()) .min_size(0) .desired_capacity(0) .send() .await; if let Err(err) = update_group { return Err(ScenarioError::new( "Failed to update group for scaling down&", &err, )); } let stable = self.wait_for_stable(0).await; if let Err(err) = stable { return Err(ScenarioError::with(format!( "Error while waiting for group to be stable on scale down: {err}" ))); } Ok(()) } // snippet-start:[rust.auto-scaling.scenario.terminate_some_instance] pub async fn terminate_some_instance(&self) -> Result<(), ScenarioError> { // Retrieve a list of instances in the auto scaling group. let auto_scaling_group = self.get_group().await?; let instances = auto_scaling_group.instances(); // Or use other logic to find an instance to terminate. let instance = instances.first(); if let Some(instance) = instance { let instance_id = if let Some(instance_id) = instance.instance_id() { instance_id } else { return Err(ScenarioError::with("Missing instance id")); }; let termination = self .ec2 .terminate_instances() .instance_ids(instance_id) .send() .await; if let Err(err) = termination { Err(ScenarioError::new( "There was a problem terminating an instance", &err, )) } else { Ok(()) } } else { Err(ScenarioError::with("There was no instance to terminate")) } } // snippet-end:[rust.auto-scaling.scenario.terminate_some_instance] } fn count_group_instances(group: &AutoScalingGroup) -> usize { group.instances.as_ref().map(|i| i.len()).unwrap_or(0) }