Skip to content

Commit

Permalink
Add find_ami_id logic instead of pass argument --instance-id
Browse files Browse the repository at this point in the history
currently integration test needs human manually find bottlerocket ami id
and pass it to integration test via `--instance-id`, which isn't efficient
and convenient; therefore, we add a new logic about finding ami id
via aws-sdk-ssm according to arch, bottlerocket-version, and eks-version
provided by the users.
  • Loading branch information
gthao313 committed Mar 10, 2022
1 parent bb5fd23 commit d36bdd4
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 8 deletions.
32 changes: 31 additions & 1 deletion integ/src/ec2_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,24 @@ impl Ec2Creator {}

pub async fn create_ec2_instance(
cluster: ClusterInfo,
node_ami: &str,
ami_arch: &str,
bottlerocket_version: &str,
eks_version: &str,
) -> ProviderResult<CreatedEc2Instances> {
// Setup aws_sdk_config and clients.
let region_provider = RegionProviderChain::first_try(Some(Region::new(cluster.region.clone())));
let shared_config = aws_config::from_env().region(region_provider).load().await;
let ec2_client = aws_sdk_ec2::Client::new(&shared_config);
let ssm_client = aws_sdk_ssm::Client::new(&shared_config);

// Prepare security groups
let mut security_groups = vec![];
security_groups.append(&mut cluster.nodegroup_sg.clone());
security_groups.append(&mut cluster.clustershared_sg.clone());

// Prepare ami id
let node_ami = find_ami_id(&ssm_client, ami_arch, bottlerocket_version, eks_version).await?;

// Prepare instance type
let instance_type = instance_type(&ec2_client, &node_ami).await?;

Expand Down Expand Up @@ -138,6 +144,30 @@ pub async fn terminate_ec2_instance(cluster: ClusterInfo) -> ProviderResult<()>
Ok(())
}

// Find the node ami id to use.
async fn find_ami_id(
ssm_client: &aws_sdk_ssm::Client,
arch: &str,
br_version: &str,
eks_version: &str,
) -> ProviderResult<String> {
let parameter_name = format!(
"/aws/service/bottlerocket/aws-k8s-{}/{}/{}/image_id",
eks_version, arch, br_version
);
let ami_id = ssm_client
.get_parameter()
.name(parameter_name)
.send()
.await
.context("Unable to get ami id")?
.parameter
.context("Unable to get ami id")?
.value
.context("ami id is missing")?;
Ok(ami_id)
}

/// Determine the instance type to use. If provided use that one. Otherwise, for `x86_64` use `m5.large`
/// and for `aarch64` use `m6g.large`
async fn instance_type(ec2_client: &aws_sdk_ec2::Client, node_ami: &str) -> ProviderResult<String> {
Expand Down
29 changes: 22 additions & 7 deletions integ/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ const DEFAULT_KUBECONFIG_FILE_NAME: &str = "kubeconfig.yaml";
const DEFAULT_REGION: &str = "us-west-2";
const CLUSTER_NAME: &str = "brupop-integration-test";

//The default values for AMI ID
const AMI_ARCH: &str = "x86_64";
const BOTTLEROCKET_VERSION: &str = "1.6.1";
const EKS_VERSION: &str = "1.21";

/// This value configure how long it sleeps between create instance and label instance.
const INTEGRATION_TEST_DELAY: Duration = Duration::from_secs(60);

Expand Down Expand Up @@ -60,9 +65,15 @@ enum SubCommand {

// Stores user-supplied arguments for the 'integration-test' subcommand.
#[derive(StructOpt, Debug)]
struct IntegrationTestArgs {
#[structopt(long = "--instance-ami-id")]
instance_ami_id: String,
pub struct IntegrationTestArgs {
#[structopt(long = "--bottlerocket-version", default_value = BOTTLEROCKET_VERSION)]
bottlerocket_version: String,

#[structopt(long = "--arch", default_value = AMI_ARCH)]
ami_arch: String,

#[structopt(long = "--eks-version", default_value = EKS_VERSION)]
eks_version: String,
}

async fn generate_kubeconfig(arguments: &Arguments) -> Result<String> {
Expand Down Expand Up @@ -122,10 +133,14 @@ async fn run() -> Result<()> {
SubCommand::IntegrationTest(integ_test_args) => {
// create instances and add nodes to eks cluster
info!("Creating EC2 instances ...");
let created_instances =
create_ec2_instance(cluster_info, &integ_test_args.instance_ami_id)
.await
.context(error::CreateEc2Instances)?;
let created_instances = create_ec2_instance(
cluster_info,
&integ_test_args.ami_arch,
&integ_test_args.bottlerocket_version,
&integ_test_args.eks_version,
)
.await
.context(error::CreateEc2Instances)?;
info!("EC2 instances have been created");

// generate kubeconfig if no input value for argument `kube_config_path`
Expand Down

0 comments on commit d36bdd4

Please sign in to comment.