Skip to content

Commit

Permalink
Merge pull request #1064 from zmrow/sts-region
Browse files Browse the repository at this point in the history
pubsys: use base region for contacting STS
  • Loading branch information
tjkirch authored Aug 23, 2020
2 parents ff88228 + e272d1b commit 10d0e7d
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 9 deletions.
7 changes: 4 additions & 3 deletions tools/pubsys/src/aws/ami/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@ async fn _run(args: &Args, ami_args: &AmiArgs) -> Result<HashMap<String, String>
})?;

// Build EBS client for snapshot management, and EC2 client for registration
let ebs_client = build_client::<EbsClient>(&base_region, &aws).context(error::Client {
let ebs_client = build_client::<EbsClient>(&base_region, &base_region, &aws).context(error::Client {
client_type: "EBS",
region: base_region.name(),
})?;
let ec2_client = build_client::<Ec2Client>(&base_region, &aws).context(error::Client {
let ec2_client = build_client::<Ec2Client>(&base_region, &base_region, &aws).context(error::Client {
client_type: "EC2",
region: base_region.name(),
})?;
Expand Down Expand Up @@ -172,6 +172,7 @@ async fn _run(args: &Args, ami_args: &AmiArgs) -> Result<HashMap<String, String>
wait_for_ami(
&image_id,
&base_region,
&base_region,
"available",
successes_required,
&aws,
Expand All @@ -187,7 +188,7 @@ async fn _run(args: &Args, ami_args: &AmiArgs) -> Result<HashMap<String, String>
// live until the future is resolved.
let mut ec2_clients = HashMap::with_capacity(regions.len());
for region in regions.iter() {
let ec2_client = build_client::<Ec2Client>(&region, &aws).context(error::Client {
let ec2_client = build_client::<Ec2Client>(&region, &base_region, &aws).context(error::Client {
client_type: "EC2",
region: base_region.name(),
})?;
Expand Down
3 changes: 2 additions & 1 deletion tools/pubsys/src/aws/ami/wait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::time::Duration;
pub(crate) async fn wait_for_ami(
id: &str,
region: &Region,
sts_region: &Region,
state: &str,
successes_required: u8,
aws: &AwsConfig,
Expand Down Expand Up @@ -49,7 +50,7 @@ pub(crate) async fn wait_for_ami(
};
// Use a new client each time so we have more confidence that different endpoints can see
// the new AMI.
let ec2_client = build_client::<Ec2Client>(&region, &aws).context(error::Client {
let ec2_client = build_client::<Ec2Client>(&region, &sts_region, &aws).context(error::Client {
client_type: "EC2",
region: region.name(),
})?;
Expand Down
17 changes: 13 additions & 4 deletions tools/pubsys/src/aws/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,14 @@ impl NewWith for Ec2Client {
}

/// Create a rusoto client of the given type using the given region and configuration.
pub(crate) fn build_client<T: NewWith>(region: &Region, aws: &AwsConfig) -> Result<T> {
pub(crate) fn build_client<T: NewWith>(
region: &Region,
sts_region: &Region,
aws: &AwsConfig,
) -> Result<T> {
let maybe_regional_role = aws.region.get(region.name()).and_then(|r| r.role.clone());
let assume_roles = aws.role.iter().chain(maybe_regional_role.iter()).cloned();
let provider = build_provider(&region, assume_roles.clone(), base_provider(&aws.profile)?)?;
let provider = build_provider(&sts_region, assume_roles.clone(), base_provider(&aws.profile)?)?;
Ok(T::new_with(
rusoto_core::HttpClient::new().context(error::HttpClient)?,
provider,
Expand All @@ -61,8 +65,13 @@ impl ProvideAwsCredentials for CredentialsProvider {
}

/// Chains credentials providers to assume the given roles in order.
/// The region given should be the one in which you want to talk to STS to get temporary
/// credentials, not the region in which you want to talk to a service endpoint like EC2. This is
/// needed because you may be assuming a role in an opt-in region from an account that has not
/// opted-in to that region, and you need to get session credentials from an STS endpoint in a
/// region to which you have access in the base account.
fn build_provider<P>(
region: &Region,
sts_region: &Region,
assume_roles: impl Iterator<Item = String>,
base_provider: P,
) -> Result<CredentialsProvider>
Expand All @@ -74,7 +83,7 @@ where
let sts = StsClient::new_with(
HttpClient::new().context(error::HttpClient)?,
provider,
region.clone(),
sts_region.clone(),
);
let expiring_provider = StsAssumeRoleSessionCredentialsProvider::new(
sts,
Expand Down
5 changes: 4 additions & 1 deletion tools/pubsys/src/aws/publish_ami/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ pub(crate) async fn run(args: &Args, publish_args: &PublishArgs) -> Result<()> {
} else {
aws.regions.clone().into()
};
ensure!(!regions.is_empty(), error::MissingConfig { missing: "aws.regions" });
let base_region = region_from_string(&regions[0], &aws).context(error::ParseRegion)?;

// Check that the requested regions are a subset of the regions we *could* publish from the AMI
// input JSON.
let requested_regions = HashSet::from_iter(regions.iter());
Expand Down Expand Up @@ -121,7 +124,7 @@ pub(crate) async fn run(args: &Args, publish_args: &PublishArgs) -> Result<()> {
// live until the future is resolved.
let mut ec2_clients = HashMap::with_capacity(amis.len());
for region in amis.keys() {
let ec2_client = build_client::<Ec2Client>(&region, &aws).context(error::Client {
let ec2_client = build_client::<Ec2Client>(&region, &base_region, &aws).context(error::Client {
client_type: "EC2",
region: region.name(),
})?;
Expand Down

0 comments on commit 10d0e7d

Please sign in to comment.