1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
mod backend;
mod ec2_instance;
mod ec2_instance_definition;
mod ssh;
pub use backend::{Aws, InstanceType, PlacementStrategy};
pub use ec2_instance::{Ec2Instance, NetworkInterface};
pub use ec2_instance_definition::{Ec2InstanceDefinition, InstanceOs};
// include a magic number in the keyname to avoid collisions
// This can never change or we may fail to cleanup resources.
const USER_TAG_NAME: &str = "aws-throwaway-23c2d22c-d929-43fc-b2a4-c1c72f0b733f:user";
const APP_TAG_NAME: &str = "aws-throwaway-23c2d22c-d929-43fc-b2a4-c1c72f0b733f:app";
pub struct AwsBuilder {
cleanup: CleanupResources,
use_public_addresses: bool,
vpc_id: Option<String>,
subnet_id: Option<String>,
placement_strategy: PlacementStrategy,
security_group_id: Option<String>,
}
/// The default configuration will succeed for an AMI user with sufficient access and unmodified default vpcs/subnets
/// Consider altering the configuration if:
/// * you want to reduce the amount of access required by the user
/// * you want to connect directly from within the VPC
/// * you have already created a specific VPC, subnet or security group that you want aws-throwaway to make use of.
///
/// All resources will be created in us-east-1c.
/// This is hardcoded so that aws-throawaway only has to look into one region when cleaning up.
/// All instances are created in a single spread placement group in a single AZ to ensure consistent latency between instances.
// TODO: document minimum required access for default configuration.
impl AwsBuilder {
fn new(cleanup: CleanupResources) -> Self {
AwsBuilder {
cleanup,
use_public_addresses: true,
vpc_id: None,
subnet_id: None,
// refer to: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html
// I believe Spread is the best default since it is the easiest for amazon to fulfill and gives the most realistic results in benchmarks.
placement_strategy: PlacementStrategy::Spread,
security_group_id: None,
}
}
/// When set to:
/// * true => aws-throwaway will connect to the public ip of the instances that it creates.
/// + The subnet must have the property MapPublicIpOnLaunch set to true (the unmodified default subnet meets this requirement)
/// + Elastic IPs will be created for instances with multiple network interfaces because AWS does not assign a public IP in that scenario
/// * false => aws-throwaway will connect to the private ip of the instances that it creates.
/// + aws-throwaway must be running on a machine within the VPC used by aws-throwaaway or a VPN must be used to connect to the VPC or another similar setup.
///
/// If the subnet used has MapPublicIpOnLaunch=true then all instances will be publically accessible regardless of this use_public_addresses field.
///
/// The default is `true`.
pub fn use_public_addresses(mut self, use_public_addresses: bool) -> Self {
self.use_public_addresses = use_public_addresses;
self
}
/// * Some(_) => All resources will go into the specified vpc
/// * None => All resources will go into the default vpc
///
/// The default is `None`
pub fn use_vpc_id(mut self, vpc_id: Option<String>) -> Self {
self.vpc_id = vpc_id;
self
}
/// * Some(_) => All instances will go into the specified subnet
/// * None => All instances will go into the default subnet for the specified or default vpc
///
/// The default is `None`
pub fn use_subnet_id(mut self, subnet_id: Option<String>) -> Self {
self.subnet_id = subnet_id;
self
}
/// All EC2 instances are created within a single placement group with the specified strategy.
///
/// The default is `PlacementStrategy::Spread`
pub fn use_placement_strategy(mut self, placement_strategy: PlacementStrategy) -> Self {
self.placement_strategy = placement_strategy;
self
}
/// * Some(_) => All instances will use the specified security group
/// * None => A single security group will be created for all instances to use. It will allow:
/// + ssh traffic in from the internet
/// + all traffic out to the internet
/// + all traffic in+out between instances in the security group, i.e. all ec2 instances created by this [`Aws`] instance
///
/// The default is `None`
pub fn use_security_group_id(mut self, security_group_id: Option<String>) -> Self {
self.security_group_id = security_group_id;
self
}
pub async fn build(self) -> Aws {
Aws::new(self).await
}
}
/// Specify the cleanup process to use.
pub enum CleanupResources {
/// Cleanup resources created by all [`Aws`] instances that use [`CleanupResources::WithAppTag`] of the same tag.
/// It is highly reccomended that this tag is hardcoded, generating this tag could easily lead to forgotten resources.
WithAppTag(String),
/// Cleanup resources created by all [`Aws`] instances regardless of whether it was created via [`CleanupResources::AllResources`] or [`CleanupResources::ResourcesMatchingTag`]
AllResources,
}