Skip to content

Commit

Permalink
proxy: Create Elasticache credentials provider lazily (#9967)
Browse files Browse the repository at this point in the history
## Problem

The credentials providers tries to connect to AWS STS even when we use
plain Redis connections.

## Summary of changes

* Construct the CredentialsProvider only when needed ("irsa").
  • Loading branch information
cloneable authored Dec 2, 2024
1 parent c18716b commit 1b60571
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 47 deletions.
49 changes: 7 additions & 42 deletions proxy/src/bin/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@ use std::pin::pin;
use std::sync::Arc;

use anyhow::bail;
use aws_config::environment::EnvironmentVariableCredentialsProvider;
use aws_config::imds::credentials::ImdsCredentialsProvider;
use aws_config::meta::credentials::CredentialsProviderChain;
use aws_config::meta::region::RegionProviderChain;
use aws_config::profile::ProfileFileCredentialsProvider;
use aws_config::provider_config::ProviderConfig;
use aws_config::web_identity_token::WebIdentityTokenCredentialsProvider;
use aws_config::Region;
use futures::future::Either;
use proxy::auth::backend::jwt::JwkCache;
use proxy::auth::backend::{AuthRateLimiter, ConsoleRedirectBackend, MaybeOwned};
Expand Down Expand Up @@ -314,39 +306,7 @@ async fn main() -> anyhow::Result<()> {
};
info!("Using region: {}", args.aws_region);

let region_provider =
RegionProviderChain::default_provider().or_else(Region::new(args.aws_region.clone()));
let provider_conf =
ProviderConfig::without_region().with_region(region_provider.region().await);
let aws_credentials_provider = {
// uses "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"
CredentialsProviderChain::first_try("env", EnvironmentVariableCredentialsProvider::new())
// uses "AWS_PROFILE" / `aws sso login --profile <profile>`
.or_else(
"profile-sso",
ProfileFileCredentialsProvider::builder()
.configure(&provider_conf)
.build(),
)
// uses "AWS_WEB_IDENTITY_TOKEN_FILE", "AWS_ROLE_ARN", "AWS_ROLE_SESSION_NAME"
// needed to access remote extensions bucket
.or_else(
"token",
WebIdentityTokenCredentialsProvider::builder()
.configure(&provider_conf)
.build(),
)
// uses imds v2
.or_else("imds", ImdsCredentialsProvider::builder().build())
};
let elasticache_credentials_provider = Arc::new(elasticache::CredentialsProvider::new(
elasticache::AWSIRSAConfig::new(
args.aws_region.clone(),
args.redis_cluster_name,
args.redis_user_id,
),
aws_credentials_provider,
));
// TODO: untangle the config args
let regional_redis_client = match (args.redis_auth_type.as_str(), &args.redis_notifications) {
("plain", redis_url) => match redis_url {
None => {
Expand All @@ -361,7 +321,12 @@ async fn main() -> anyhow::Result<()> {
ConnectionWithCredentialsProvider::new_with_credentials_provider(
host.to_string(),
port,
elasticache_credentials_provider.clone(),
elasticache::CredentialsProvider::new(
args.aws_region,
args.redis_cluster_name,
args.redis_user_id,
)
.await,
),
),
(None, None) => {
Expand Down
51 changes: 46 additions & 5 deletions proxy/src/redis/elasticache.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
use std::sync::Arc;
use std::time::{Duration, SystemTime};

use aws_config::environment::EnvironmentVariableCredentialsProvider;
use aws_config::imds::credentials::ImdsCredentialsProvider;
use aws_config::meta::credentials::CredentialsProviderChain;
use aws_config::meta::region::RegionProviderChain;
use aws_config::profile::ProfileFileCredentialsProvider;
use aws_config::provider_config::ProviderConfig;
use aws_config::web_identity_token::WebIdentityTokenCredentialsProvider;
use aws_config::Region;
use aws_sdk_iam::config::ProvideCredentials;
use aws_sigv4::http_request::{
self, SignableBody, SignableRequest, SignatureLocation, SigningSettings,
Expand Down Expand Up @@ -45,12 +53,45 @@ pub struct CredentialsProvider {
}

impl CredentialsProvider {
pub fn new(config: AWSIRSAConfig, credentials_provider: CredentialsProviderChain) -> Self {
CredentialsProvider {
config,
credentials_provider,
}
pub async fn new(
aws_region: String,
redis_cluster_name: Option<String>,
redis_user_id: Option<String>,
) -> Arc<CredentialsProvider> {
let region_provider =
RegionProviderChain::default_provider().or_else(Region::new(aws_region.clone()));
let provider_conf =
ProviderConfig::without_region().with_region(region_provider.region().await);
let aws_credentials_provider = {
// uses "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"
CredentialsProviderChain::first_try(
"env",
EnvironmentVariableCredentialsProvider::new(),
)
// uses "AWS_PROFILE" / `aws sso login --profile <profile>`
.or_else(
"profile-sso",
ProfileFileCredentialsProvider::builder()
.configure(&provider_conf)
.build(),
)
// uses "AWS_WEB_IDENTITY_TOKEN_FILE", "AWS_ROLE_ARN", "AWS_ROLE_SESSION_NAME"
// needed to access remote extensions bucket
.or_else(
"token",
WebIdentityTokenCredentialsProvider::builder()
.configure(&provider_conf)
.build(),
)
// uses imds v2
.or_else("imds", ImdsCredentialsProvider::builder().build())
};
Arc::new(CredentialsProvider {
config: AWSIRSAConfig::new(aws_region, redis_cluster_name, redis_user_id),
credentials_provider: aws_credentials_provider,
})
}

pub(crate) async fn provide_credentials(&self) -> anyhow::Result<(String, String)> {
let aws_credentials = self
.credentials_provider
Expand Down

1 comment on commit 1b60571

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7144 tests run: 6825 passed, 1 failed, 318 skipped (full report)


Failures on Postgres 16

  • test_ingest_logical_message[github-actions-selfhosted-fsync-131072]: release-x86-64
# Run all failed tests locally:
scripts/pytest -vv -n $(nproc) -k "test_ingest_logical_message[release-pg16-github-actions-selfhosted-fsync-131072]"
Flaky tests (5)

Postgres 17

Postgres 15

Postgres 14

Code coverage* (full report)

  • functions: 30.4% (8272 of 27228 functions)
  • lines: 47.7% (65209 of 136588 lines)

* collected from Rust tests only


The comment gets automatically updated with the latest test results
1b60571 at 2024-12-02T17:39:20.886Z :recycle:

Please sign in to comment.