Skip to content

Commit

Permalink
Add ability to create new canary deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
EricGhildyal committed Nov 20, 2024
1 parent 29c4435 commit 07ca37c
Showing 1 changed file with 67 additions and 3 deletions.
70 changes: 67 additions & 3 deletions src/adapters/ingresses/apig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use async_trait::async_trait;
use miette::{IntoDiagnostic, Result};
use tokio::{fs::File, io::AsyncReadExt};

use aws_sdk_apigateway::client::Client as GatewayClient;
use aws_sdk_lambda::client::Client as LambdaClient;
use aws_sdk_apigateway::{client::Client as GatewayClient, types::DeploymentCanarySettings};
use aws_sdk_lambda::{client::Client as LambdaClient, primitives::Blob, types::FunctionCode};

/// AwsApiGateway is the Ingress implementation for AWS API Gateway + Lambda.
/// It's responsible for creating canary deployments on API Gateway, updating their
Expand Down Expand Up @@ -37,6 +37,61 @@ impl AwsApiGateway {
lambda_client,
})
}

pub async fn upload_lambda(&self, lambda_name: &str) -> Result<String, aws_sdk_lambda::Error> {
// Parse the bytes into the format AWS wants
let code = Blob::from(self.lambda_artifact.clone());

// Turn it into an uploadable zip file
let function_code = FunctionCode::builder().zip_file(code).build();

// Upload it to Lambda
let res = self
.lambda_client
.update_function_code()
.function_name(lambda_name)
.zip_file(function_code.zip_file().unwrap().clone())
.send()
.await?;

Ok(res.version().unwrap().to_string())
}

pub async fn create_apig_deployment(
&self,
api_id: &str,
stage_name: &str,
lambda_name: &str,
lambda_version: &str,
traffic_percentage: f64,
) -> Result<(), aws_sdk_apigateway::Error> {
// Update the APIG with the new lambda version
self.apig_client
.put_integration()
.rest_api_id(api_id)
.uri(format!(
"arn:aws:lambda:us-east-2:471112630982:function:{}:{}",
lambda_name, lambda_version
))
.send()
.await?;

// Create a deployment with canary settings to deploy our new lambda
self.apig_client
.create_deployment()
.rest_api_id(api_id)
.stage_name(stage_name)
.canary_settings(
DeploymentCanarySettings::builder()
.percent_traffic(traffic_percentage)
.use_stage_cache(false)
.build(),
)
.send()
.await?;

Ok(())
}
}

/// given a path to a file, load it as an array of bytes.
Expand All @@ -51,6 +106,15 @@ async fn read_file(artifact_path: PathBuf) -> Result<Vec<u8>> {
#[async_trait]
impl Ingress for AwsApiGateway {
async fn deploy(&mut self) -> Result<()> {
todo!()
// First, we need to deploy the new version of the lambda
let lambda_version = self.upload_lambda("releases").await.unwrap();

// Next, we need to create a new deployment, pointing at our
// new lambda version with canary settings
self.create_apig_deployment("Releases", "prod", "releases", &lambda_version, 10.0)
.await
.unwrap();

Ok(())
}
}

0 comments on commit 07ca37c

Please sign in to comment.