Documentation
¶
Overview ¶
Package aws provides EC2 capacity discovery for the truffle tool. It searches instance type availability, retrieves Spot pricing history, and queries On-Demand Capacity Reservations (ODCRs) and Capacity Blocks for ML workloads across one or more AWS regions concurrently.
Typical usage:
client, err := aws.NewClient(ctx)
results, err := client.SearchInstanceTypes(ctx, []string{"us-east-1"}, pattern, filterOpts)
prices, err := client.GetSpotPricing(ctx, results, aws.SpotOptions{ShowSavings: true})
Index ¶
- type Capabilities
- type CapacityBlockOfferingOptions
- type CapacityBlockOfferingResult
- type CapacityBlockOptions
- type CapacityBlockResult
- type CapacityReservationOptions
- type CapacityReservationResult
- type Client
- func (c *Client) GetAllRegions(ctx context.Context) ([]string, error)
- func (c *Client) GetCapabilities(ctx context.Context, instanceType, region string) (*Capabilities, error)
- func (c *Client) GetCapacityBlockOfferings(ctx context.Context, regions []string, opts CapacityBlockOfferingOptions) ([]CapacityBlockOfferingResult, error)
- func (c *Client) GetCapacityBlocks(ctx context.Context, regions []string, opts CapacityBlockOptions) ([]CapacityBlockResult, error)
- func (c *Client) GetCapacityReservations(ctx context.Context, regions []string, opts CapacityReservationOptions) ([]CapacityReservationResult, error)
- func (c *Client) GetEnabledRegions(ctx context.Context) ([]string, error)
- func (c *Client) GetInstanceTypes(ctx context.Context, region string) ([]string, error)
- func (c *Client) GetSpotPricing(ctx context.Context, instances []InstanceTypeResult, opts SpotOptions) ([]SpotPriceResult, error)
- func (c *Client) HourlyRate(ctx context.Context, instanceType, region, model string) (float64, error)
- func (c *Client) OnDemandPrice(ctx context.Context, instanceType, region string) (float64, error)
- func (c *Client) SageMakerPrice(ctx context.Context, instanceType, region string) (float64, error)
- func (c *Client) SearchInstanceTypes(ctx context.Context, regions []string, matcher *regexp.Regexp, ...) ([]InstanceTypeResult, error)
- func (c *Client) SearchSageMakerInstanceTypes(ctx context.Context, regions []string, matcher *regexp.Regexp, ...) ([]InstanceTypeResult, error)
- func (c *Client) SetOnDemandPricer(p OnDemandPricer)
- func (c *Client) SetSageMakerPricer(p SageMakerPricer)
- func (c *Client) SetSageMakerTypeLister(l SageMakerTypeLister)
- type FilterOptions
- type Finder
- type InstanceTypeResult
- type OnDemandPricer
- type SageMakerPricer
- type SageMakerTypeLister
- type SpotOptions
- type SpotPriceResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Capabilities ¶ added in v0.38.0
type Capabilities struct {
InstanceType string `json:"instance_type"`
Found bool `json:"found"`
Architectures []string `json:"architectures,omitempty"` // e.g. ["x86_64"], ["arm64"]
ClusterPlacement bool `json:"cluster_placement"` // supports the "cluster" placement strategy (MPI)
EFA bool `json:"efa"` // supports Elastic Fabric Adapter
Hibernation bool `json:"hibernation"` // supports On-Demand hibernation
NestedVirtualization bool `json:"nested_virtualization"` // can run KVM/Hyper-V in-instance
GPUs int32 `json:"gpus,omitempty"`
BareMetal bool `json:"bare_metal"`
}
Capabilities is a feature-support snapshot for a single instance type, from one DescribeInstanceTypes call. truffle is the instance-type capability authority for the spore.host tools; other tools (e.g. spawn's pre-flight launch validation) consume this instead of re-querying EC2 themselves.
type CapacityBlockOfferingOptions ¶ added in v0.40.0
type CapacityBlockOfferingOptions struct {
InstanceType string // required
InstanceCount int32 // required by us; defaults to 1
CapacityDurationHours int32 // required by AWS
StartAfter string // ISO-8601; earliest block start → StartDateRange
EndBy string // ISO-8601; latest block end → EndDateRange
Verbose bool
}
CapacityBlockOfferingOptions are the query parameters for discovering purchasable Capacity Block offerings. CapacityDurationHours and InstanceType are required by the AWS DescribeCapacityBlockOfferings API; InstanceCount defaults to 1.
type CapacityBlockOfferingResult ¶ added in v0.40.0
type CapacityBlockOfferingResult struct {
OfferingID string `json:"offering_id" yaml:"offering_id"`
InstanceType string `json:"instance_type" yaml:"instance_type"`
InstanceCount int32 `json:"instance_count" yaml:"instance_count"`
AvailabilityZone string `json:"availability_zone" yaml:"availability_zone"`
Region string `json:"region" yaml:"region"`
StartDate string `json:"start_date" yaml:"start_date"`
EndDate string `json:"end_date" yaml:"end_date"`
DurationHours int32 `json:"duration_hours" yaml:"duration_hours"`
UpfrontFee string `json:"upfront_fee" yaml:"upfront_fee"` // total up-front price (string per AWS)
CurrencyCode string `json:"currency_code" yaml:"currency_code"`
Tenancy string `json:"tenancy,omitempty" yaml:"tenancy,omitempty"`
}
CapacityBlockOfferingResult represents a PURCHASABLE Capacity Block offering (the answer to "what can I reserve?"), as returned by DescribeCapacityBlock Offerings — distinct from CapacityBlockResult, which represents an EXISTING reservation you already own. The OfferingID is what spawn purchases (spawn#217).
type CapacityBlockOptions ¶
type CapacityBlockOptions struct {
InstanceTypes []string
MinDuration int32 // Minimum duration in hours
MaxDuration int32 // Maximum duration in hours
StartAfter string // ISO format datetime
StartBefore string // ISO format datetime
OnlyActive bool
Verbose bool
}
CapacityBlockOptions contains Capacity Block search options
type CapacityBlockResult ¶
type CapacityBlockResult struct {
CapacityBlockID string `json:"capacity_block_id" yaml:"capacity_block_id"`
InstanceType string `json:"instance_type" yaml:"instance_type"`
InstanceCount int32 `json:"instance_count" yaml:"instance_count"`
AvailabilityZone string `json:"availability_zone" yaml:"availability_zone"`
StartDate string `json:"start_date" yaml:"start_date"`
EndDate string `json:"end_date" yaml:"end_date"`
DurationHours int32 `json:"duration_hours" yaml:"duration_hours"`
State string `json:"state" yaml:"state"` // scheduled, active, completed, cancelled
ReservationFee float64 `json:"reservation_fee" yaml:"reservation_fee"`
UltraClusterPlacement bool `json:"ultra_cluster_placement" yaml:"ultra_cluster_placement"`
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
}
CapacityBlockResult represents a Capacity Block for ML
type CapacityReservationOptions ¶
type CapacityReservationOptions struct {
InstanceTypes []string
OnlyAvailable bool // Only show reservations with available capacity
OnlyActive bool // Only show active reservations
IncludeExpired bool // Include expired reservations
MinCapacity int32 // Minimum available capacity
Verbose bool
}
CapacityReservationOptions contains ODCR search options
type CapacityReservationResult ¶
type CapacityReservationResult struct {
ReservationID string `json:"reservation_id" yaml:"reservation_id"`
InstanceType string `json:"instance_type" yaml:"instance_type"`
Region string `json:"region" yaml:"region"`
AvailabilityZone string `json:"availability_zone" yaml:"availability_zone"`
TotalCapacity int32 `json:"total_capacity" yaml:"total_capacity"`
AvailableCapacity int32 `json:"available_capacity" yaml:"available_capacity"`
UsedCapacity int32 `json:"used_capacity" yaml:"used_capacity"`
State string `json:"state" yaml:"state"`
Tenancy string `json:"tenancy" yaml:"tenancy"`
EBSOptimized bool `json:"ebs_optimized" yaml:"ebs_optimized"`
EndDate string `json:"end_date,omitempty" yaml:"end_date,omitempty"`
Platform string `json:"platform" yaml:"platform"`
Tags []string `json:"tags,omitempty" yaml:"tags,omitempty"`
}
CapacityReservationResult represents an ODCR (On-Demand Capacity Reservation)
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client wraps AWS SDK clients
func NewClientFromConfig ¶
NewClientFromConfig creates a new AWS client with an injected aws.Config. Use this in tests to point the client at a Substrate emulator.
func (*Client) GetAllRegions ¶
GetAllRegions is deprecated. Use GetEnabledRegions instead. This method is kept for backward compatibility.
func (*Client) GetCapabilities ¶ added in v0.38.0
func (c *Client) GetCapabilities(ctx context.Context, instanceType, region string) (*Capabilities, error)
GetCapabilities returns feature support for a single instance type in the given region (region may be empty for the client default). Backed by one DescribeInstanceTypes call; the API is the source of truth (no hardcoded family lists).
func (*Client) GetCapacityBlockOfferings ¶ added in v0.40.0
func (c *Client) GetCapacityBlockOfferings(ctx context.Context, regions []string, opts CapacityBlockOfferingOptions) ([]CapacityBlockOfferingResult, error)
GetCapacityBlockOfferings discovers PURCHASABLE Capacity Block offerings across regions via DescribeCapacityBlockOfferings (the "what can I reserve?" query) — distinct from GetCapacityBlocks, which lists blocks you already own. Read-only. The returned OfferingID feeds spawn's purchase command (spawn#217). Price (UpfrontFee + CurrencyCode) comes directly from each offering — no separate pricing lookup needed.
func (*Client) GetCapacityBlocks ¶
func (c *Client) GetCapacityBlocks(ctx context.Context, regions []string, opts CapacityBlockOptions) ([]CapacityBlockResult, error)
GetCapacityBlocks retrieves Capacity Blocks for ML
func (*Client) GetCapacityReservations ¶
func (c *Client) GetCapacityReservations(ctx context.Context, regions []string, opts CapacityReservationOptions) ([]CapacityReservationResult, error)
GetCapacityReservations retrieves On-Demand Capacity Reservations (ODCRs)
func (*Client) GetEnabledRegions ¶
GetEnabledRegions returns AWS regions enabled for this account. This respects Service Control Policies (SCPs) that may restrict regions. Regions blocked by organizational SCPs will not appear in the returned list.
func (*Client) GetInstanceTypes ¶
GetInstanceTypes returns all instance types in a region
func (*Client) GetSpotPricing ¶
func (c *Client) GetSpotPricing(ctx context.Context, instances []InstanceTypeResult, opts SpotOptions) ([]SpotPriceResult, error)
GetSpotPricing retrieves current Spot pricing for instance types
func (*Client) HourlyRate ¶ added in v0.36.2
func (c *Client) HourlyRate(ctx context.Context, instanceType, region, model string) (float64, error)
HourlyRate returns the current $/hr for one instance type in one region under the given purchase model. It is a library-friendly convenience for embedders that want a single number rather than reducing a []SpotPriceResult by hand.
model is case-insensitive:
- "on-demand" / "ondemand" / "" → the On-Demand rate.
- "spot" → the minimum current Spot price across AZs in the region (Spot varies by AZ; the minimum is the best obtainable rate). Returns an error if no Spot price is currently published for the type.
"reserved" is not a point-in-time rate (it depends on term, payment option, and offering class) and is rejected; use the On-Demand rate as the baseline and apply your own reserved discount.
func (*Client) OnDemandPrice ¶ added in v0.36.2
OnDemandPrice returns the current On-Demand $/hr for one instance type in one region (Linux, shared tenancy). It is a thin accessor over the client's OnDemandPricer; see Client.HourlyRate for a purchase-model-aware helper.
func (*Client) SageMakerPrice ¶ added in v0.42.0
SageMakerPrice returns the current On-Demand $/hr for one ml.* instance type in one region. It is a thin accessor over the client's SageMakerPricer.
func (*Client) SearchInstanceTypes ¶
func (c *Client) SearchInstanceTypes(ctx context.Context, regions []string, matcher *regexp.Regexp, opts FilterOptions) ([]InstanceTypeResult, error)
SearchInstanceTypes searches for instance types matching the pattern across regions
func (*Client) SearchSageMakerInstanceTypes ¶ added in v0.42.0
func (c *Client) SearchSageMakerInstanceTypes(ctx context.Context, regions []string, matcher *regexp.Regexp, opts FilterOptions) ([]InstanceTypeResult, error)
SearchSageMakerInstanceTypes searches for SageMaker ml.* instance types matching the pattern across regions. It mirrors Client.SearchInstanceTypes: per-region concurrency and the #63 error-aggregation contract (a total failure must not masquerade as an empty result).
Unlike EC2, SageMaker has no DescribeInstanceTypes API, so the offered set comes from Service Quotas. Specs (vCPU/memory/GPU/arch) are derived from the underlying EC2 instance type (ml.g5.2xlarge → g5.2xlarge), which runs on the same hardware. Results carry Service="sagemaker" and SpawnSupported=false (spawn launches EC2, not SageMaker); OnDemandPrice is left 0 — SageMaker pricing is a separate concern (issue #80).
func (*Client) SetOnDemandPricer ¶ added in v0.36.2
func (c *Client) SetOnDemandPricer(p OnDemandPricer)
SetOnDemandPricer overrides the On-Demand price source used by this client. Pass nil to reset to the default AWS Price List pricer. This is primarily for embedders and tests that want deterministic prices or an offline source.
func (*Client) SetSageMakerPricer ¶ added in v0.42.0
func (c *Client) SetSageMakerPricer(p SageMakerPricer)
SetSageMakerPricer overrides the SageMaker price source used by this client. Pass nil to reset to the default AWS Price List pricer. Primarily for embedders and tests that want deterministic prices or an offline source.
func (*Client) SetSageMakerTypeLister ¶ added in v0.42.0
func (c *Client) SetSageMakerTypeLister(l SageMakerTypeLister)
SetSageMakerTypeLister overrides the source of offered ml.* types used by this client. Pass nil to reset to the default Service Quotas lister. This is primarily for embedders and tests that want a deterministic offering set.
type FilterOptions ¶
type FilterOptions struct {
IncludeAZs bool // If true, populate InstanceTypeResult.AvailableAZs (one extra API call per type)
Architecture string // Filter to "x86_64" or "arm64"; empty matches both
MinVCPUs int // Minimum vCPU count; 0 disables this filter
MinMemory float64 // Minimum memory in GiB; 0 disables this filter
MinPhysicalCores int // Minimum physical core count; 0 disables this filter
ExactVCPUs bool // If true, match exact vCPU count instead of minimum
ExactMemory bool // If true, match exact memory instead of minimum
ExactCores bool // If true, match exact physical core count instead of minimum
InstanceFamily string // Restrict to a family prefix, e.g. "m6i"; empty matches all
NestedVirt bool // If true, only types supporting nested virtualization (KVM/Hyper-V in-instance)
Verbose bool // If true, log per-region progress to stderr
}
FilterOptions controls which instance types are returned by Client.SearchInstanceTypes.
type Finder ¶ added in v0.36.8
type Finder interface {
// GetEnabledRegions returns regions enabled for the caller's account.
GetEnabledRegions(ctx context.Context) ([]string, error)
// GetAllRegions returns all AWS regions (enabled or not).
GetAllRegions(ctx context.Context) ([]string, error)
// GetInstanceTypes returns all instance type names available in a region.
GetInstanceTypes(ctx context.Context, region string) ([]string, error)
// SearchInstanceTypes finds instance types matching a pattern across regions.
SearchInstanceTypes(ctx context.Context, regions []string, matcher *regexp.Regexp, opts FilterOptions) ([]InstanceTypeResult, error)
// GetSpotPricing retrieves current Spot pricing for instance types.
GetSpotPricing(ctx context.Context, instances []InstanceTypeResult, opts SpotOptions) ([]SpotPriceResult, error)
// GetCapacityReservations retrieves ODCRs across regions.
GetCapacityReservations(ctx context.Context, regions []string, opts CapacityReservationOptions) ([]CapacityReservationResult, error)
// GetCapacityBlocks retrieves Capacity Blocks for ML across regions.
GetCapacityBlocks(ctx context.Context, regions []string, opts CapacityBlockOptions) ([]CapacityBlockResult, error)
// GetCapacityBlockOfferings discovers purchasable Capacity Block offerings across regions.
GetCapacityBlockOfferings(ctx context.Context, regions []string, opts CapacityBlockOfferingOptions) ([]CapacityBlockOfferingResult, error)
// OnDemandPrice returns the on-demand $/hr for an instance type in a region.
OnDemandPrice(ctx context.Context, instanceType, region string) (float64, error)
// HourlyRate returns $/hr under a given purchase model ("on-demand" or "spot").
HourlyRate(ctx context.Context, instanceType, region, model string) (float64, error)
}
Finder is the read-only query interface for EC2 instance discovery. The concrete Client satisfies this interface. Downstream consumers should accept Finder in their function signatures to enable unit testing with [awsmock.Finder] or any custom implementation.
type InstanceTypeResult ¶
type InstanceTypeResult struct {
InstanceType string `json:"instance_type" yaml:"instance_type"` // EC2 instance type, e.g. "m6i.2xlarge"
Region string `json:"region" yaml:"region"` // AWS region where this type is available
AvailableAZs []string `json:"availability_zones,omitempty" yaml:"availability_zones,omitempty"` // AZs with capacity; populated when FilterOptions.IncludeAZs is true
VCPUs int32 `json:"vcpus,omitempty" yaml:"vcpus,omitempty"` // Default vCPU count
PhysicalCores int32 `json:"physical_cores,omitempty" yaml:"physical_cores,omitempty"` // Physical CPU cores (vCPUs / threads-per-core)
ThreadsPerCore int32 `json:"threads_per_core,omitempty" yaml:"threads_per_core,omitempty"` // Threads per physical core (1 for Graviton, 2 for most x86)
MemoryMiB int64 `json:"memory_mib,omitempty" yaml:"memory_mib,omitempty"` // Memory in MiB
Architecture string `json:"architecture,omitempty" yaml:"architecture,omitempty"` // CPU architecture: "x86_64" or "arm64"
InstanceFamily string `json:"instance_family,omitempty" yaml:"instance_family,omitempty"` // Family prefix, e.g. "m6i"
GPUs int32 `json:"gpus,omitempty" yaml:"gpus,omitempty"` // Number of GPUs; 0 for non-GPU instances
GPUMemoryMiB int64 `json:"gpu_memory_mib,omitempty" yaml:"gpu_memory_mib,omitempty"` // Total GPU memory in MiB across all GPUs
GPUModel string `json:"gpu_model,omitempty" yaml:"gpu_model,omitempty"` // GPU model name, e.g. "A100"
GPUManufacturer string `json:"gpu_manufacturer,omitempty" yaml:"gpu_manufacturer,omitempty"` // GPU vendor, e.g. "nvidia"
OnDemandPrice float64 `json:"on_demand_price,omitempty" yaml:"on_demand_price,omitempty"` // On-demand $/hr; 0 if not yet fetched
SpawnSupported bool `json:"spawn_supported,omitempty" yaml:"spawn_supported,omitempty"` // True if spawn can launch instances in this region
NestedVirt bool `json:"nested_virtualization,omitempty" yaml:"nested_virtualization,omitempty"` // True if the type supports nested virtualization (KVM/Hyper-V in-instance)
Service string `json:"service,omitempty" yaml:"service,omitempty"` // Offering namespace: "" / "ec2" (default) or "sagemaker" for ml.* types
// SageMaker-only fields (populated when Service == "sagemaker"):
ManagedSpotEligible bool `json:"managed_spot_eligible,omitempty" yaml:"managed_spot_eligible,omitempty"` // Type can be used with managed spot training (has a "spot training job usage" quota). Managed spot is a billed-time discount (up to 90%), not a spot market — there is no per-type spot price.
TrainingJobQuota *float64 `json:"training_job_quota,omitempty" yaml:"training_job_quota,omitempty"` // Account limit for "training job usage" of this type; nil when the region exposes no such quota. 0 means an increase must be requested before launching.
}
InstanceTypeResult represents an instance type's availability and specifications in a given region, as returned by Client.SearchInstanceTypes.
type OnDemandPricer ¶ added in v0.36.2
type OnDemandPricer interface {
// OnDemandPrice returns the On-Demand $/hr for instanceType in region.
// It returns (0, error) when no price could be determined.
OnDemandPrice(ctx context.Context, instanceType, region string) (float64, error)
}
OnDemandPricer resolves the On-Demand hourly rate ($/hr) for a Linux instance type in a region. Implementations should be safe for concurrent use.
truffle uses this to populate SpotPriceResult.OnDemandPrice and SpotPriceResult.SavingsPercent (when SpotOptions.ShowSavings is set) and to back the Client.HourlyRate convenience. The default implementation (NewAWSOnDemandPricer) queries the AWS Price List API and caches results; callers embedding truffle as a library can inject their own via Client.SetOnDemandPricer (e.g. a fixture in tests).
func NewAWSOnDemandPricer ¶ added in v0.36.2
func NewAWSOnDemandPricer(cfg aws.Config) OnDemandPricer
NewAWSOnDemandPricer returns an OnDemandPricer backed solely by the AWS Price List API (no static fallback). Most callers want the client default; this is exported for embedders that want to control fallback behavior.
type SageMakerPricer ¶ added in v0.42.0
type SageMakerPricer interface {
// SageMakerPrice returns the On-Demand $/hr for an ml.* instanceType in
// region. It returns (0, error) when no price could be determined.
SageMakerPrice(ctx context.Context, instanceType, region string) (float64, error)
}
SageMakerPricer resolves the On-Demand hourly rate ($/hr) for a SageMaker ml.* instance type in a region. SageMaker is priced under a distinct offer (AmazonSageMaker) with a management premium over the equivalent EC2 rate, so it cannot reuse the EC2 pricer. Implementations should be safe for concurrent use.
The default implementation queries the AWS Price List API and caches results; embedders and tests can inject their own via Client.SetSageMakerPricer.
func NewAWSSageMakerPricer ¶ added in v0.42.0
func NewAWSSageMakerPricer(cfg aws.Config) SageMakerPricer
NewAWSSageMakerPricer returns a SageMakerPricer backed by the AWS Price List API. Exported for embedders that want to control pricing directly.
type SageMakerTypeLister ¶ added in v0.42.0
type SageMakerTypeLister interface {
// OfferedTypes returns the ml.*-prefixed types offered in region, with quota detail.
OfferedTypes(ctx context.Context, region string) ([]quotas.SageMakerTypeQuota, error)
}
SageMakerTypeLister returns the SageMaker ml.* instance types offered in a region, with their per-type quota detail (training-job limit, managed-spot eligibility). There is no SageMaker equivalent of EC2 DescribeInstanceTypes, so the authoritative source is Service Quotas (which lists a quota per ml.* type). Implementations should be safe for concurrent use.
The default implementation queries Service Quotas via pkg/quotas; embedders and tests can inject their own with Client.SetSageMakerTypeLister.
type SpotOptions ¶
type SpotOptions struct {
MaxPrice float64 // Exclude results above this $/hr threshold; 0 disables
ShowSavings bool // Populate SpotPriceResult.SavingsPercent by comparing with on-demand price
LookbackHours int // Hours of price history to query; 0 uses the AWS default (typically 1 hour)
OnlyActive bool // Exclude price history entries with no current offering
Verbose bool // If true, log per-region progress to stderr
}
SpotOptions controls the behavior of Client.GetSpotPricing.
type SpotPriceResult ¶
type SpotPriceResult struct {
InstanceType string `json:"instance_type" yaml:"instance_type"` // EC2 instance type
Region string `json:"region" yaml:"region"` // AWS region
AvailabilityZone string `json:"availability_zone" yaml:"availability_zone"` // AZ where this price applies
SpotPrice float64 `json:"spot_price" yaml:"spot_price"` // Current Spot price in $/hr
OnDemandPrice float64 `json:"on_demand_price,omitempty" yaml:"on_demand_price,omitempty"` // On-demand $/hr for savings calculation; 0 if unavailable
SavingsPercent float64 `json:"savings_percent,omitempty" yaml:"savings_percent,omitempty"` // Discount vs on-demand: 100*(1-spot/ondemand); set when SpotOptions.ShowSavings is true
Timestamp string `json:"timestamp" yaml:"timestamp"` // RFC3339 timestamp of the price observation
ProductType string `json:"product_type,omitempty" yaml:"product_type,omitempty"` // OS description, e.g. "Linux/UNIX"
}
SpotPriceResult represents a Spot instance price observation for one AZ, as returned by Client.GetSpotPricing.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package awsmock provides a configurable mock implementation of aws.Finder for unit testing downstream consumers of truffle's instance discovery API.
|
Package awsmock provides a configurable mock implementation of aws.Finder for unit testing downstream consumers of truffle's instance discovery API. |