Há mais exemplos de AWS SDK disponíveis no repositório AWS Doc SDK Examples
As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Exemplos do Auto Scaling usando o SDK para Rust
Os exemplos de código a seguir mostram como realizar ações e implementar cenários comuns usando o AWS SDK para Rust com Auto Scaling.
As noções básicas são exemplos de código que mostram como realizar as operações essenciais em um serviço.
Ações são trechos de código de programas maiores e devem ser executadas em contexto. Embora as ações mostrem como chamar perfis de serviço individuais, você pode ver as ações no contexto em seus cenários relacionados.
Cada exemplo inclui um link para o código-fonte completo, em que você pode encontrar instruções sobre como configurar e executar o código.
Conceitos básicos
Os exemplos de código a seguir mostram como começar a usar o Auto Scaling.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da AWS
. async fn list_groups(client: &Client) -> Result<(), Error> { let resp = client.describe_auto_scaling_groups().send().await?; println!("Groups:"); let groups = resp.auto_scaling_groups(); for group in groups { println!( "Name: {}", group.auto_scaling_group_name().unwrap_or("Unknown") ); println!( "Arn: {}", group.auto_scaling_group_arn().unwrap_or("unknown"), ); println!("Zones: {:?}", group.availability_zones(),); println!(); } println!("Found {} group(s)", groups.len()); Ok(()) }
-
Para obter detalhes da API, consulte a DescribeAutoScalingGroups
referência da API AWS SDK for Rust.
-
Tópicos
Conceitos básicos
O exemplo de código a seguir mostra como:
Crie um grupo do Amazon EC2 Auto Scaling com um modelo de lançamento e zonas de disponibilidade e obtenha informações sobre instâncias em execução.
Ative a coleta de CloudWatch métricas da Amazon.
Atualizar a capacidade desejada do grupo e aguardar a inicialização de uma instância.
Encerrar uma instância no grupo.
Listar as atividades de ajuste de escala que ocorrem em resposta às solicitações do usuário e às mudanças de capacidade.
Obtenha estatísticas de CloudWatch métricas e, em seguida, limpe os recursos.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da 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" 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; 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, }; 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; 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", )]) } } 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, } } 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()) } 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(()) } 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)) } 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(()) } 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(()) } pub async fn scale_group_to_zero(&self) -> Result<(), ScenarioError> { // 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; // 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(()) } 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")) } } } fn count_group_instances(group: &AutoScalingGroup) -> usize { group.instances.as_ref().map(|i| i.len()).unwrap_or(0) }
-
Para obter detalhes da API, consulte os tópicos a seguir na Referência da API AWS SDK para Rust.
-
Ações
O código de exemplo a seguir mostra como usar CreateAutoScalingGroup
.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da AWS
. async fn create_group(client: &Client, name: &str, id: &str) -> Result<(), Error> { client .create_auto_scaling_group() .auto_scaling_group_name(name) .instance_id(id) .min_size(1) .max_size(5) .send() .await?; println!("Created AutoScaling group"); Ok(()) }
-
Para obter detalhes da API, consulte a CreateAutoScalingGroup
referência da API AWS SDK for Rust.
-
O código de exemplo a seguir mostra como usar DeleteAutoScalingGroup
.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da AWS
. async fn delete_group(client: &Client, name: &str, force: bool) -> Result<(), Error> { client .delete_auto_scaling_group() .auto_scaling_group_name(name) .set_force_delete(if force { Some(true) } else { None }) .send() .await?; println!("Deleted Auto Scaling group"); Ok(()) }
-
Para obter detalhes da API, consulte a DeleteAutoScalingGroup
referência da API AWS SDK for Rust.
-
O código de exemplo a seguir mostra como usar DescribeAutoScalingGroups
.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da AWS
. async fn list_groups(client: &Client) -> Result<(), Error> { let resp = client.describe_auto_scaling_groups().send().await?; println!("Groups:"); let groups = resp.auto_scaling_groups(); for group in groups { println!( "Name: {}", group.auto_scaling_group_name().unwrap_or("Unknown") ); println!( "Arn: {}", group.auto_scaling_group_arn().unwrap_or("unknown"), ); println!("Zones: {:?}", group.availability_zones(),); println!(); } println!("Found {} group(s)", groups.len()); Ok(()) }
-
Para obter detalhes da API, consulte a DescribeAutoScalingGroups
referência da API AWS SDK for Rust.
-
O código de exemplo a seguir mostra como usar DescribeAutoScalingInstances
.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da AWS
. 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)) }
-
Para obter detalhes da API, consulte a DescribeAutoScalingInstances
referência da API AWS SDK for Rust.
-
O código de exemplo a seguir mostra como usar DescribeScalingActivities
.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da AWS
. 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, } }
-
Para obter detalhes da API, consulte a DescribeScalingActivities
referência da API AWS SDK for Rust.
-
O código de exemplo a seguir mostra como usar DisableMetricsCollection
.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da AWS
. // 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;
-
Para obter detalhes da API, consulte a DisableMetricsCollection
referência da API AWS SDK for Rust.
-
O código de exemplo a seguir mostra como usar EnableMetricsCollection
.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da AWS
. 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;
-
Para obter detalhes da API, consulte a EnableMetricsCollection
referência da API AWS SDK for Rust.
-
O código de exemplo a seguir mostra como usar SetDesiredCapacity
.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da AWS
. 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(()) }
-
Para obter detalhes da API, consulte a SetDesiredCapacity
referência da API AWS SDK for Rust.
-
O código de exemplo a seguir mostra como usar TerminateInstanceInAutoScalingGroup
.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da AWS
. 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")) } } 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()) }
-
Para obter detalhes da API, consulte a TerminateInstanceInAutoScalingGroup
referência da API AWS SDK for Rust.
-
O código de exemplo a seguir mostra como usar UpdateAutoScalingGroup
.
- SDK para Rust
-
nota
Tem mais sobre GitHub. Encontre o exemplo completo e saiba como configurar e executar no Repositório de exemplos de código da AWS
. async fn update_group(client: &Client, name: &str, size: i32) -> Result<(), Error> { client .update_auto_scaling_group() .auto_scaling_group_name(name) .max_size(size) .send() .await?; println!("Updated AutoScaling group"); Ok(()) }
-
Para obter detalhes da API, consulte a UpdateAutoScalingGroup
referência da API AWS SDK for Rust.
-