I have various AWS regions configured, and they each have a default region specified. Thus with AWS CLI I can do this to list CloudFormation exports for the default profile:
aws cloudformation list-exports
To list CloudFormation exports for the foobar
, I would do this:
aws cloudformation list-exports --profile foobar
So I want to do the same thing with the AWS SDK for Rust. My CLI has an Option<String>
indicating the AWS profile (if any) specified on the command line, to override the default.
let aws_credentials_provider_builder = aws_config::profile::ProfileFileCredentialsProvider::builder();
let aws_credentials_provider_builder = match aws_profile_option {
Some(aws_profile) => aws_credentials_provider_builder.profile_name(aws_profile),
None => aws_credentials_provider_builder,
};
let config = aws_config::from_env().credentials_provider(aws_credentials_provider_builder.build()).load().await;
let cf_client = aws_sdk_cloudformation::Client::new(&config);
let list_exports_output = cf_client.list_exports().send().await.unwrap();
if let Some(exports) = list_exports_output.exports {
for export in exports {
dbg!(export);
}
};
That works if I don't specify a profile. But if I specify a profile, e.g. foobar
, it panics with:
thread 'main' panicked at src\main.rs:139:69:
called `Result::unwrap()` on an `Err` value: DispatchFailure(DispatchFailure { source: ConnectorError { kind: Other(None), source: ProviderError(ProviderError { source: ProviderError(ProviderError { source: DispatchFailure(DispatchFailure { source: ConnectorError { kind: Other(None), source: ResolveEndpointError { message: "Invalid Configuration: Missing Region", source: None }, connection: Unknown } }) }) }), connection: Unknown } })
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Why is it missing a region, if the foobar
profile I indicated has a default region specified? (In other words, I expected it to work like the aws cloudformation list-exports --profile foobar
CLI command listed above.)
It appears I should be setting the profile of the ConfigLoader
, not the ProfileFileCredentialsProvider
. The following code works:
let config_loader = aws_config::from_env();
let config_loader = match aws_profile_option {
Some(aws_profile) => config_loader.profile_name(aws_profile),
None => config_loader,
};
let config = config_loader.load().await;
let cf_client = aws_sdk_cloudformation::Client::new(&config);
let list_exports_output = cf_client.list_exports().send().await.unwrap();handling
if let Some(exports) = list_exports_output.exports {
for export in exports {
dbg!(export);
}
};
I was thrown off by an answer to another question, which indicated to set the profile of a ProfileFileCredentialsProvider
, not the ConfigLoader
. I'm not immediately sure of the distinction between the two, other than this way works and the other does not. I'll have to study more to find out what the other approach does, but for the meantime, this approach is what reflects my intention.