Merge pull request #9777 from hashicorp/fix_9756

Add aws_polling config option to override env variables
This commit is contained in:
Megan Marsh 2020-08-17 10:49:38 -07:00 committed by GitHub
commit d74b47b734
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 263 additions and 57 deletions

View File

@ -398,12 +398,15 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
GeneratedData: generatedData,
},
&StepCreateVolume{
PollingConfig: b.config.PollingConfig,
RootVolumeType: b.config.RootVolumeType,
RootVolumeSize: b.config.RootVolumeSize,
RootVolumeTags: b.config.RootVolumeTags,
Ctx: b.config.ctx,
},
&StepAttachVolume{},
&StepAttachVolume{
PollingConfig: b.config.PollingConfig,
},
&StepEarlyUnflock{},
&chroot.StepPreMountCommands{
Commands: b.config.PreMountCommands,
@ -427,7 +430,9 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&chroot.StepChrootProvision{},
&chroot.StepEarlyCleanup{},
&StepSnapshot{},
&StepSnapshot{
PollingConfig: b.config.PollingConfig,
},
&awscommon.StepDeregisterAMI{
AccessConfig: &b.config.AccessConfig,
ForceDeregister: b.config.AMIForceDeregister,
@ -440,6 +445,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
EnableAMISriovNetSupport: b.config.AMISriovNetSupport,
EnableAMIENASupport: b.config.AMIENASupport,
AMISkipBuildRegion: b.config.AMISkipBuildRegion,
PollingConfig: b.config.PollingConfig,
},
&awscommon.StepAMIRegionCopy{
AccessConfig: &b.config.AccessConfig,

View File

@ -52,6 +52,7 @@ type FlatConfig struct {
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check" hcl:"skip_metadata_api_check"`
Token *string `mapstructure:"token" required:"false" cty:"token" hcl:"token"`
VaultAWSEngine *common.FlatVaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false" cty:"vault_aws_engine" hcl:"vault_aws_engine"`
PollingConfig *common.FlatAWSPollingConfig `mapstructure:"aws_polling" required:"false" cty:"aws_polling" hcl:"aws_polling"`
AMIMappings []common.FlatBlockDevice `mapstructure:"ami_block_device_mappings" hcl2-schema-generator:"ami_block_device_mappings,direct" required:"false" cty:"ami_block_device_mappings" hcl:"ami_block_device_mappings"`
ChrootMounts [][]string `mapstructure:"chroot_mounts" required:"false" cty:"chroot_mounts" hcl:"chroot_mounts"`
CommandWrapper *string `mapstructure:"command_wrapper" required:"false" cty:"command_wrapper" hcl:"command_wrapper"`
@ -127,6 +128,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
"aws_polling": &hcldec.BlockSpec{TypeName: "aws_polling", Nested: hcldec.ObjectSpec((*common.FlatAWSPollingConfig)(nil).HCL2Spec())},
"ami_block_device_mappings": &hcldec.BlockListSpec{TypeName: "ami_block_device_mappings", Nested: hcldec.ObjectSpec((*common.FlatBlockDevice)(nil).HCL2Spec())},
"chroot_mounts": &hcldec.AttrSpec{Name: "chroot_mounts", Type: cty.List(cty.List(cty.String)), Required: false},
"command_wrapper": &hcldec.AttrSpec{Name: "command_wrapper", Type: cty.String, Required: false},

View File

@ -19,8 +19,9 @@ import (
// device string - The location where the volume was attached.
// attach_cleanup CleanupFunc
type StepAttachVolume struct {
attached bool
volumeId string
PollingConfig *awscommon.AWSPollingConfig
attached bool
volumeId string
}
func (s *StepAttachVolume) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
@ -51,7 +52,7 @@ func (s *StepAttachVolume) Run(ctx context.Context, state multistep.StateBag) mu
s.volumeId = volumeId
// Wait for the volume to become attached
err = awscommon.WaitUntilVolumeAttached(ctx, ec2conn, s.volumeId)
err = s.PollingConfig.WaitUntilVolumeAttached(ctx, ec2conn, s.volumeId)
if err != nil {
err := fmt.Errorf("Error waiting for volume: %s", err)
state.Put("error", err)
@ -87,7 +88,7 @@ func (s *StepAttachVolume) CleanupFunc(state multistep.StateBag) error {
s.attached = false
// Wait for the volume to detach
err = awscommon.WaitUntilVolumeDetached(aws.BackgroundContext(), ec2conn, s.volumeId)
err = s.PollingConfig.WaitUntilVolumeDetached(aws.BackgroundContext(), ec2conn, s.volumeId)
if err != nil {
return fmt.Errorf("Error waiting for volume: %s", err)
}

View File

@ -20,6 +20,7 @@ import (
// Produces:
// volume_id string - The ID of the created volume
type StepCreateVolume struct {
PollingConfig *awscommon.AWSPollingConfig
volumeId string
RootVolumeSize int64
RootVolumeType string
@ -110,7 +111,7 @@ func (s *StepCreateVolume) Run(ctx context.Context, state multistep.StateBag) mu
log.Printf("Volume ID: %s", s.volumeId)
// Wait for the volume to become ready
err = awscommon.WaitUntilVolumeAvailable(ctx, ec2conn, s.volumeId)
err = s.PollingConfig.WaitUntilVolumeAvailable(ctx, ec2conn, s.volumeId)
if err != nil {
err := fmt.Errorf("Error waiting for volume: %s", err)
state.Put("error", err)

View File

@ -15,6 +15,7 @@ import (
// StepRegisterAMI creates the AMI.
type StepRegisterAMI struct {
PollingConfig *awscommon.AWSPollingConfig
RootVolumeSize int64
EnableAMIENASupport confighelper.Trilean
EnableAMISriovNetSupport bool
@ -81,7 +82,7 @@ func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) mul
state.Put("amis", amis)
ui.Say("Waiting for AMI to become ready...")
if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil {
if err := s.PollingConfig.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil {
err := fmt.Errorf("Error waiting for AMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())

View File

@ -16,7 +16,8 @@ import (
// Produces:
// snapshot_id string - ID of the created snapshot
type StepSnapshot struct {
snapshotId string
PollingConfig *awscommon.AWSPollingConfig
snapshotId string
}
func (s *StepSnapshot) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
@ -43,7 +44,7 @@ func (s *StepSnapshot) Run(ctx context.Context, state multistep.StateBag) multis
ui.Message(fmt.Sprintf("Snapshot ID: %s", s.snapshotId))
// Wait for the snapshot to be ready
err = awscommon.WaitUntilSnapshotDone(ctx, ec2conn, s.snapshotId)
err = s.PollingConfig.WaitUntilSnapshotDone(ctx, ec2conn, s.snapshotId)
if err != nil {
err := fmt.Errorf("Error waiting for snapshot: %s", err)
state.Put("error", err)

View File

@ -138,6 +138,9 @@ type AccessConfig struct {
// }
// ```
VaultAWSEngine VaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false"`
// [Polling configuration](#polling-configuration) for the AWS waiter. Configures the waiter that checks
// resource state.
PollingConfig *AWSPollingConfig `mapstructure:"aws_polling" required:"false"`
getEC2Connection func() ec2iface.EC2API
}
@ -215,7 +218,6 @@ func (c *AccessConfig) Session() (*session.Session, error) {
if c.DecodeAuthZMessages {
DecodeAuthZMessages(c.session)
}
LogEnvOverrideWarnings()
return c.session, nil
}
@ -296,6 +298,11 @@ func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error {
fmt.Errorf("`access_key` and `secret_key` must both be either set or not set."))
}
if c.PollingConfig == nil {
c.PollingConfig = new(AWSPollingConfig)
}
c.PollingConfig.LogEnvOverrideWarnings()
return errs
}

View File

@ -13,6 +13,7 @@ func testAccessConfig() *AccessConfig {
getEC2Connection: func() ec2iface.EC2API {
return &mockEC2Client{}
},
PollingConfig: new(AWSPollingConfig),
}
}

View File

@ -1,3 +1,5 @@
//go:generate struct-markdown
//go:generate mapstructure-to-hcl2 -type AWSPollingConfig
package common
import (
@ -38,12 +40,45 @@ type StateChangeConf struct {
// Following are wrapper functions that use Packer's environment-variables to
// determine retry logic, then call the AWS SDK's built-in waiters.
func WaitUntilAMIAvailable(ctx aws.Context, conn ec2iface.EC2API, imageId string) error {
// Polling configuration for the AWS waiter. Configures the waiter for resources creation or actions like attaching
// volumes or importing image.
// Usage example:
//
// In JSON:
// ```json
// "aws_polling" : {
// "delay_seconds": 30,
// "max_attempts": 50
// }
// ```
//
// In HCL2:
// ```hcl
// aws_polling {
// delay_seconds = 30
// max_attempts = 50
// }
// ```
//
type AWSPollingConfig struct {
// Specifies the maximum number of attempts the waiter will check for resource state.
// This value can also be set via the AWS_MAX_ATTEMPTS.
// If both option and environment variable are set, the max_attempts will be considered over the AWS_MAX_ATTEMPTS.
// If none is set, defaults to AWS waiter default which is 40 max_attempts.
MaxAttempts int `mapstructure:"max_attempts" required:"false"`
// Specifies the delay in seconds between attempts to check the resource state.
// This value can also be set via the AWS_POLL_DELAY_SECONDS.
// If both option and environment variable are set, the delay_seconds will be considered over the AWS_POLL_DELAY_SECONDS.
// If none is set, defaults to AWS waiter default which is 15 seconds.
DelaySeconds int `mapstructure:"delay_seconds" required:"false"`
}
func (w *AWSPollingConfig) WaitUntilAMIAvailable(ctx aws.Context, conn ec2iface.EC2API, imageId string) error {
imageInput := ec2.DescribeImagesInput{
ImageIds: []*string{&imageId},
}
waitOpts := getWaiterOptions()
waitOpts := w.getWaiterOptions()
if len(waitOpts) == 0 {
// Bump this default to 30 minutes because the aws default
// of ten minutes doesn't work for some of our long-running copies.
@ -66,7 +101,7 @@ func WaitUntilAMIAvailable(ctx aws.Context, conn ec2iface.EC2API, imageId string
return err
}
func WaitUntilInstanceRunning(ctx aws.Context, conn *ec2.EC2, instanceId string) error {
func (w *AWSPollingConfig) WaitUntilInstanceRunning(ctx aws.Context, conn *ec2.EC2, instanceId string) error {
instanceInput := ec2.DescribeInstancesInput{
InstanceIds: []*string{&instanceId},
@ -75,12 +110,11 @@ func WaitUntilInstanceRunning(ctx aws.Context, conn *ec2.EC2, instanceId string)
err := conn.WaitUntilInstanceRunningWithContext(
ctx,
&instanceInput,
getWaiterOptions()...)
w.getWaiterOptions()...)
return err
}
func WaitUntilInstanceTerminated(ctx aws.Context, conn *ec2.EC2, instanceId string) error {
func (w *AWSPollingConfig) WaitUntilInstanceTerminated(ctx aws.Context, conn *ec2.EC2, instanceId string) error {
instanceInput := ec2.DescribeInstancesInput{
InstanceIds: []*string{&instanceId},
}
@ -88,12 +122,12 @@ func WaitUntilInstanceTerminated(ctx aws.Context, conn *ec2.EC2, instanceId stri
err := conn.WaitUntilInstanceTerminatedWithContext(
ctx,
&instanceInput,
getWaiterOptions()...)
w.getWaiterOptions()...)
return err
}
// This function works for both requesting and cancelling spot instances.
func WaitUntilSpotRequestFulfilled(ctx aws.Context, conn *ec2.EC2, spotRequestId string) error {
func (w *AWSPollingConfig) WaitUntilSpotRequestFulfilled(ctx aws.Context, conn *ec2.EC2, spotRequestId string) error {
spotRequestInput := ec2.DescribeSpotInstanceRequestsInput{
SpotInstanceRequestIds: []*string{&spotRequestId},
}
@ -101,11 +135,11 @@ func WaitUntilSpotRequestFulfilled(ctx aws.Context, conn *ec2.EC2, spotRequestId
err := conn.WaitUntilSpotInstanceRequestFulfilledWithContext(
ctx,
&spotRequestInput,
getWaiterOptions()...)
w.getWaiterOptions()...)
return err
}
func WaitUntilVolumeAvailable(ctx aws.Context, conn *ec2.EC2, volumeId string) error {
func (w *AWSPollingConfig) WaitUntilVolumeAvailable(ctx aws.Context, conn *ec2.EC2, volumeId string) error {
volumeInput := ec2.DescribeVolumesInput{
VolumeIds: []*string{&volumeId},
}
@ -113,11 +147,11 @@ func WaitUntilVolumeAvailable(ctx aws.Context, conn *ec2.EC2, volumeId string) e
err := conn.WaitUntilVolumeAvailableWithContext(
ctx,
&volumeInput,
getWaiterOptions()...)
w.getWaiterOptions()...)
return err
}
func WaitUntilSnapshotDone(ctx aws.Context, conn *ec2.EC2, snapshotID string) error {
func (w *AWSPollingConfig) WaitUntilSnapshotDone(ctx aws.Context, conn *ec2.EC2, snapshotID string) error {
snapInput := ec2.DescribeSnapshotsInput{
SnapshotIds: []*string{&snapshotID},
}
@ -125,13 +159,13 @@ func WaitUntilSnapshotDone(ctx aws.Context, conn *ec2.EC2, snapshotID string) er
err := conn.WaitUntilSnapshotCompletedWithContext(
ctx,
&snapInput,
getWaiterOptions()...)
w.getWaiterOptions()...)
return err
}
// Wrappers for our custom AWS waiters
func WaitUntilVolumeAttached(ctx aws.Context, conn *ec2.EC2, volumeId string) error {
func (w *AWSPollingConfig) WaitUntilVolumeAttached(ctx aws.Context, conn *ec2.EC2, volumeId string) error {
volumeInput := ec2.DescribeVolumesInput{
VolumeIds: []*string{&volumeId},
}
@ -139,11 +173,11 @@ func WaitUntilVolumeAttached(ctx aws.Context, conn *ec2.EC2, volumeId string) er
err := WaitForVolumeToBeAttached(conn,
ctx,
&volumeInput,
getWaiterOptions()...)
w.getWaiterOptions()...)
return err
}
func WaitUntilVolumeDetached(ctx aws.Context, conn *ec2.EC2, volumeId string) error {
func (w *AWSPollingConfig) WaitUntilVolumeDetached(ctx aws.Context, conn *ec2.EC2, volumeId string) error {
volumeInput := ec2.DescribeVolumesInput{
VolumeIds: []*string{&volumeId},
}
@ -151,11 +185,11 @@ func WaitUntilVolumeDetached(ctx aws.Context, conn *ec2.EC2, volumeId string) er
err := WaitForVolumeToBeDetached(conn,
ctx,
&volumeInput,
getWaiterOptions()...)
w.getWaiterOptions()...)
return err
}
func WaitUntilImageImported(ctx aws.Context, conn *ec2.EC2, taskID string) error {
func (w *AWSPollingConfig) WaitUntilImageImported(ctx aws.Context, conn *ec2.EC2, taskID string) error {
importInput := ec2.DescribeImportImageTasksInput{
ImportTaskIds: []*string{&taskID},
}
@ -163,7 +197,7 @@ func WaitUntilImageImported(ctx aws.Context, conn *ec2.EC2, taskID string) error
err := WaitForImageToBeImported(conn,
ctx,
&importInput,
getWaiterOptions()...)
w.getWaiterOptions()...)
return err
}
@ -298,8 +332,18 @@ type overridableWaitVars struct {
awsTimeoutSeconds envInfo
}
func getWaiterOptions() []request.WaiterOption {
func (w *AWSPollingConfig) getWaiterOptions() []request.WaiterOption {
envOverrides := getEnvOverrides()
if w.MaxAttempts != 0 {
envOverrides.awsMaxAttempts.Val = w.MaxAttempts
envOverrides.awsMaxAttempts.overridden = true
}
if w.DelaySeconds != 0 {
envOverrides.awsPollDelaySeconds.Val = w.DelaySeconds
envOverrides.awsPollDelaySeconds.overridden = true
}
waitOpts := applyEnvOverrides(envOverrides)
return waitOpts
}
@ -333,33 +377,38 @@ func getEnvOverrides() overridableWaitVars {
return envValues
}
func LogEnvOverrideWarnings() {
pollDelay := os.Getenv("AWS_POLL_DELAY_SECONDS")
timeoutSeconds := os.Getenv("AWS_TIMEOUT_SECONDS")
maxAttempts := os.Getenv("AWS_MAX_ATTEMPTS")
func (w *AWSPollingConfig) LogEnvOverrideWarnings() {
pollDelayEnv := os.Getenv("AWS_POLL_DELAY_SECONDS")
timeoutSecondsEnv := os.Getenv("AWS_TIMEOUT_SECONDS")
maxAttemptsEnv := os.Getenv("AWS_MAX_ATTEMPTS")
if maxAttempts != "" && timeoutSeconds != "" {
maxAttemptsIsSet := maxAttemptsEnv != "" || w.MaxAttempts != 0
timeoutSecondsIsSet := timeoutSecondsEnv != ""
pollDelayIsSet := pollDelayEnv != "" || w.DelaySeconds != 0
if maxAttemptsIsSet && timeoutSecondsIsSet {
warning := fmt.Sprintf("[WARNING] (aws): AWS_MAX_ATTEMPTS and " +
"AWS_TIMEOUT_SECONDS are both set. Packer will use " +
"AWS_MAX_ATTEMPTS and discard AWS_TIMEOUT_SECONDS.")
if pollDelay == "" {
if !pollDelayIsSet {
warning = fmt.Sprintf("%s Since you have not set the poll delay, "+
"Packer will default to a 2-second delay.", warning)
}
log.Printf(warning)
} else if timeoutSeconds != "" {
} else if timeoutSecondsIsSet {
log.Printf("[WARNING] (aws): env var AWS_TIMEOUT_SECONDS is " +
"deprecated in favor of AWS_MAX_ATTEMPTS. If you have not " +
"explicitly set AWS_POLL_DELAY_SECONDS, we are defaulting to a " +
"poll delay of 2 seconds, regardless of the AWS waiter's default.")
"deprecated in favor of AWS_MAX_ATTEMPTS env or aws_polling_max_attempts config option. " +
"If you have not explicitly set AWS_POLL_DELAY_SECONDS env or aws_polling_delay_seconds config option, " +
"we are defaulting to a poll delay of 2 seconds, regardless of the AWS waiter's default.")
}
if maxAttempts == "" && timeoutSeconds == "" && pollDelay == "" {
if !maxAttemptsIsSet && !timeoutSecondsIsSet && !pollDelayIsSet {
log.Printf("[INFO] (aws): No AWS timeout and polling overrides have been set. " +
"Packer will default to waiter-specific delays and timeouts. If you would " +
"like to customize the length of time between retries and max " +
"number of retries you may do so by setting the environment " +
"variables AWS_POLL_DELAY_SECONDS and AWS_MAX_ATTEMPTS to your " +
"desired values.")
"variables AWS_POLL_DELAY_SECONDS and AWS_MAX_ATTEMPTS or the " +
"configuration options aws_polling_delay_seconds and aws_polling_max_attempts " +
"to your desired values.")
}
}

View File

@ -0,0 +1,32 @@
// Code generated by "mapstructure-to-hcl2 -type AWSPollingConfig"; DO NOT EDIT.
package common
import (
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
)
// FlatAWSPollingConfig is an auto-generated flat version of AWSPollingConfig.
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
type FlatAWSPollingConfig struct {
MaxAttempts *int `mapstructure:"max_attempts" required:"false" cty:"max_attempts" hcl:"max_attempts"`
DelaySeconds *int `mapstructure:"delay_seconds" required:"false" cty:"delay_seconds" hcl:"delay_seconds"`
}
// FlatMapstructure returns a new FlatAWSPollingConfig.
// FlatAWSPollingConfig is an auto-generated flat version of AWSPollingConfig.
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
func (*AWSPollingConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
return new(FlatAWSPollingConfig)
}
// HCL2Spec returns the hcl spec of a AWSPollingConfig.
// This spec is used by HCL to read the fields of AWSPollingConfig.
// The decoded values from this spec will then be applied to a FlatAWSPollingConfig.
func (*FlatAWSPollingConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"max_attempts": &hcldec.AttrSpec{Name: "max_attempts", Type: cty.Number, Required: false},
"delay_seconds": &hcldec.AttrSpec{Name: "delay_seconds", Type: cty.Number, Required: false},
}
return s
}

View File

@ -209,7 +209,7 @@ func (s *StepAMIRegionCopy) amiRegionCopy(ctx context.Context, state multistep.S
}
// Wait for the image to become ready
if err := WaitUntilAMIAvailable(ctx, regionconn, *resp.ImageId); err != nil {
if err := s.AccessConfig.PollingConfig.WaitUntilAMIAvailable(ctx, regionconn, *resp.ImageId); err != nil {
return "", snapshotIds, fmt.Errorf("Error waiting for AMI (%s) in region (%s): %s",
*resp.ImageId, target, err)
}

View File

@ -19,6 +19,7 @@ import (
)
type StepRunSourceInstance struct {
PollingConfig *AWSPollingConfig
AssociatePublicIpAddress bool
LaunchMappings EC2BlockDeviceMappingsBuilder
Comm *communicator.Config
@ -234,7 +235,7 @@ func (s *StepRunSourceInstance) Run(ctx context.Context, state multistep.StateBa
InstanceIds: []*string{aws.String(instanceId)},
}
if err := WaitUntilInstanceRunning(ctx, ec2conn, instanceId); err != nil {
if err := s.PollingConfig.WaitUntilInstanceRunning(ctx, ec2conn, instanceId); err != nil {
err := fmt.Errorf("Error waiting for instance (%s) to become ready: %s", instanceId, err)
state.Put("error", err)
ui.Error(err.Error())
@ -364,7 +365,7 @@ func (s *StepRunSourceInstance) Cleanup(state multistep.StateBag) {
return
}
if err := WaitUntilInstanceTerminated(aws.BackgroundContext(), ec2conn, s.instanceId); err != nil {
if err := s.PollingConfig.WaitUntilInstanceTerminated(aws.BackgroundContext(), ec2conn, s.instanceId); err != nil {
ui.Error(err.Error())
}
}

View File

@ -23,6 +23,7 @@ type EC2BlockDeviceMappingsBuilder interface {
}
type StepRunSpotInstance struct {
PollingConfig *AWSPollingConfig
AssociatePublicIpAddress bool
LaunchMappings EC2BlockDeviceMappingsBuilder
BlockDurationMinutes int64
@ -466,7 +467,7 @@ func (s *StepRunSpotInstance) Cleanup(state multistep.StateBag) {
return
}
if err := WaitUntilInstanceTerminated(aws.BackgroundContext(), ec2conn, s.instanceId); err != nil {
if err := s.PollingConfig.WaitUntilInstanceTerminated(aws.BackgroundContext(), ec2conn, s.instanceId); err != nil {
ui.Error(err.Error())
}
}

View File

@ -29,6 +29,7 @@ func tStateSpot() multistep.StateBag {
func getBasicStep() *StepRunSpotInstance {
stepRunSpotInstance := StepRunSpotInstance{
PollingConfig: new(AWSPollingConfig),
AssociatePublicIpAddress: false,
LaunchMappings: BlockDevices{},
BlockDurationMinutes: 0,

View File

@ -12,6 +12,7 @@ import (
)
type StepStopEBSBackedInstance struct {
PollingConfig *AWSPollingConfig
Skip bool
DisableStopInstance bool
}
@ -74,7 +75,7 @@ func (s *StepStopEBSBackedInstance) Run(ctx context.Context, state multistep.Sta
&ec2.DescribeInstancesInput{
InstanceIds: []*string{instance.InstanceId},
},
getWaiterOptions()...)
s.PollingConfig.getWaiterOptions()...)
if err != nil {
err := fmt.Errorf("Error waiting for instance to stop: %s", err)

View File

@ -169,6 +169,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
if b.config.IsSpotInstance() {
instanceStep = &awscommon.StepRunSpotInstance{
PollingConfig: b.config.PollingConfig,
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
LaunchMappings: b.config.LaunchMappings,
BlockDurationMinutes: b.config.BlockDurationMinutes,
@ -191,6 +192,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
}
} else {
instanceStep = &awscommon.StepRunSourceInstance{
PollingConfig: b.config.PollingConfig,
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
LaunchMappings: b.config.LaunchMappings,
Comm: &b.config.RunConfig.Comm,
@ -292,6 +294,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Comm: &b.config.RunConfig.Comm,
},
&awscommon.StepStopEBSBackedInstance{
PollingConfig: b.config.PollingConfig,
Skip: b.config.IsSpotInstance(),
DisableStopInstance: b.config.DisableStopInstance,
},
@ -308,6 +311,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&stepCreateAMI{
AMISkipBuildRegion: b.config.AMISkipBuildRegion,
PollingConfig: b.config.PollingConfig,
},
&awscommon.StepAMIRegionCopy{
AccessConfig: &b.config.AccessConfig,

View File

@ -31,6 +31,7 @@ type FlatConfig struct {
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check" hcl:"skip_metadata_api_check"`
Token *string `mapstructure:"token" required:"false" cty:"token" hcl:"token"`
VaultAWSEngine *common.FlatVaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false" cty:"vault_aws_engine" hcl:"vault_aws_engine"`
PollingConfig *common.FlatAWSPollingConfig `mapstructure:"aws_polling" required:"false" cty:"aws_polling" hcl:"aws_polling"`
AMIName *string `mapstructure:"ami_name" required:"true" cty:"ami_name" hcl:"ami_name"`
AMIDescription *string `mapstructure:"ami_description" required:"false" cty:"ami_description" hcl:"ami_description"`
AMIVirtType *string `mapstructure:"ami_virtualization_type" required:"false" cty:"ami_virtualization_type" hcl:"ami_virtualization_type"`
@ -171,6 +172,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
"aws_polling": &hcldec.BlockSpec{TypeName: "aws_polling", Nested: hcldec.ObjectSpec((*common.FlatAWSPollingConfig)(nil).HCL2Spec())},
"ami_name": &hcldec.AttrSpec{Name: "ami_name", Type: cty.String, Required: false},
"ami_description": &hcldec.AttrSpec{Name: "ami_description", Type: cty.String, Required: false},
"ami_virtualization_type": &hcldec.AttrSpec{Name: "ami_virtualization_type", Type: cty.String, Required: false},

View File

@ -16,6 +16,7 @@ import (
)
type stepCreateAMI struct {
PollingConfig *awscommon.AWSPollingConfig
image *ec2.Image
AMISkipBuildRegion bool
}
@ -85,8 +86,7 @@ func (s *stepCreateAMI) Run(ctx context.Context, state multistep.StateBag) multi
// Wait for the image to become ready
ui.Say("Waiting for AMI to become ready...")
if waitErr := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *createResp.ImageId); waitErr != nil {
if waitErr := s.PollingConfig.WaitUntilAMIAvailable(ctx, ec2conn, *createResp.ImageId); waitErr != nil {
// waitErr should get bubbled up if the issue is a wait timeout
err := fmt.Errorf("Error waiting for AMI: %s", waitErr)
imResp, imerr := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ImageIds: []*string{createResp.ImageId}})

View File

@ -192,6 +192,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
if b.config.IsSpotInstance() {
instanceStep = &awscommon.StepRunSpotInstance{
PollingConfig: b.config.PollingConfig,
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
LaunchMappings: b.config.LaunchMappings,
BlockDurationMinutes: b.config.BlockDurationMinutes,
@ -213,6 +214,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
}
} else {
instanceStep = &awscommon.StepRunSourceInstance{
PollingConfig: b.config.PollingConfig,
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
LaunchMappings: b.config.LaunchMappings,
Comm: &b.config.RunConfig.Comm,
@ -316,6 +318,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Comm: &b.config.RunConfig.Comm,
},
&awscommon.StepStopEBSBackedInstance{
PollingConfig: b.config.PollingConfig,
Skip: b.config.IsSpotInstance(),
DisableStopInstance: b.config.DisableStopInstance,
},
@ -325,6 +328,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
EnableAMIENASupport: b.config.AMIENASupport,
},
&StepSnapshotVolumes{
PollingConfig: b.config.PollingConfig,
LaunchDevices: launchDevices,
SnapshotOmitMap: b.config.LaunchMappings.GetOmissions(),
},
@ -344,6 +348,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Architecture: b.config.Architecture,
LaunchOmitMap: b.config.LaunchMappings.GetOmissions(),
AMISkipBuildRegion: b.config.AMISkipBuildRegion,
PollingConfig: b.config.PollingConfig,
},
&awscommon.StepAMIRegionCopy{
AccessConfig: &b.config.AccessConfig,

View File

@ -74,6 +74,7 @@ type FlatConfig struct {
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check" hcl:"skip_metadata_api_check"`
Token *string `mapstructure:"token" required:"false" cty:"token" hcl:"token"`
VaultAWSEngine *common.FlatVaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false" cty:"vault_aws_engine" hcl:"vault_aws_engine"`
PollingConfig *common.FlatAWSPollingConfig `mapstructure:"aws_polling" required:"false" cty:"aws_polling" hcl:"aws_polling"`
AssociatePublicIpAddress *bool `mapstructure:"associate_public_ip_address" required:"false" cty:"associate_public_ip_address" hcl:"associate_public_ip_address"`
AvailabilityZone *string `mapstructure:"availability_zone" required:"false" cty:"availability_zone" hcl:"availability_zone"`
BlockDurationMinutes *int64 `mapstructure:"block_duration_minutes" required:"false" cty:"block_duration_minutes" hcl:"block_duration_minutes"`
@ -215,6 +216,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
"aws_polling": &hcldec.BlockSpec{TypeName: "aws_polling", Nested: hcldec.ObjectSpec((*common.FlatAWSPollingConfig)(nil).HCL2Spec())},
"associate_public_ip_address": &hcldec.AttrSpec{Name: "associate_public_ip_address", Type: cty.Bool, Required: false},
"availability_zone": &hcldec.AttrSpec{Name: "availability_zone", Type: cty.String, Required: false},
"block_duration_minutes": &hcldec.AttrSpec{Name: "block_duration_minutes", Type: cty.Number, Required: false},

View File

@ -15,6 +15,7 @@ import (
// StepRegisterAMI creates the AMI.
type StepRegisterAMI struct {
PollingConfig *awscommon.AWSPollingConfig
RootDevice RootBlockDevice
AMIDevices []*ec2.BlockDeviceMapping
LaunchDevices []*ec2.BlockDeviceMapping
@ -86,7 +87,7 @@ func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) mul
// Wait for the image to become ready
ui.Say("Waiting for AMI to become ready...")
if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil {
if err := s.PollingConfig.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil {
err := fmt.Errorf("Error waiting for AMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())

View File

@ -7,6 +7,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/builder/amazon/common"
)
const sourceDeviceName = "/dev/xvdf"
@ -23,6 +24,7 @@ func newStepRegisterAMI(amiDevices, launchDevices []*ec2.BlockDeviceMapping) *St
},
AMIDevices: amiDevices,
LaunchDevices: launchDevices,
PollingConfig: new(common.AWSPollingConfig),
}
}

View File

@ -18,6 +18,7 @@ import (
// Produces:
// snapshot_ids map[string]string - IDs of the created snapshots
type StepSnapshotVolumes struct {
PollingConfig *awscommon.AWSPollingConfig
LaunchDevices []*ec2.BlockDeviceMapping
snapshotIds map[string]string
snapshotMutex sync.Mutex
@ -56,7 +57,7 @@ func (s *StepSnapshotVolumes) snapshotVolume(ctx context.Context, deviceName str
s.snapshotMutex.Unlock()
// Wait for snapshot to be created
err = awscommon.WaitUntilSnapshotDone(ctx, ec2conn, *createSnapResp.SnapshotId)
err = s.PollingConfig.WaitUntilSnapshotDone(ctx, ec2conn, *createSnapResp.SnapshotId)
return err
}

View File

@ -173,6 +173,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
if b.config.IsSpotInstance() {
instanceStep = &awscommon.StepRunSpotInstance{
PollingConfig: b.config.PollingConfig,
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
LaunchMappings: b.config.launchBlockDevices,
BlockDurationMinutes: b.config.BlockDurationMinutes,
@ -194,6 +195,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
}
} else {
instanceStep = &awscommon.StepRunSourceInstance{
PollingConfig: b.config.PollingConfig,
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
LaunchMappings: b.config.launchBlockDevices,
Comm: &b.config.RunConfig.Comm,
@ -286,6 +288,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
Comm: &b.config.RunConfig.Comm,
},
&awscommon.StepStopEBSBackedInstance{
PollingConfig: b.config.PollingConfig,
Skip: b.config.IsSpotInstance(),
DisableStopInstance: b.config.DisableStopInstance,
},

View File

@ -76,6 +76,7 @@ type FlatConfig struct {
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check" hcl:"skip_metadata_api_check"`
Token *string `mapstructure:"token" required:"false" cty:"token" hcl:"token"`
VaultAWSEngine *common.FlatVaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false" cty:"vault_aws_engine" hcl:"vault_aws_engine"`
PollingConfig *common.FlatAWSPollingConfig `mapstructure:"aws_polling" required:"false" cty:"aws_polling" hcl:"aws_polling"`
AssociatePublicIpAddress *bool `mapstructure:"associate_public_ip_address" required:"false" cty:"associate_public_ip_address" hcl:"associate_public_ip_address"`
AvailabilityZone *string `mapstructure:"availability_zone" required:"false" cty:"availability_zone" hcl:"availability_zone"`
BlockDurationMinutes *int64 `mapstructure:"block_duration_minutes" required:"false" cty:"block_duration_minutes" hcl:"block_duration_minutes"`
@ -195,6 +196,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
"aws_polling": &hcldec.BlockSpec{TypeName: "aws_polling", Nested: hcldec.ObjectSpec((*common.FlatAWSPollingConfig)(nil).HCL2Spec())},
"associate_public_ip_address": &hcldec.AttrSpec{Name: "associate_public_ip_address", Type: cty.Bool, Required: false},
"availability_zone": &hcldec.AttrSpec{Name: "availability_zone", Type: cty.String, Required: false},
"block_duration_minutes": &hcldec.AttrSpec{Name: "block_duration_minutes", Type: cty.Number, Required: false},

View File

@ -255,6 +255,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
if b.config.IsSpotInstance() {
instanceStep = &awscommon.StepRunSpotInstance{
PollingConfig: b.config.PollingConfig,
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
LaunchMappings: b.config.LaunchMappings,
BlockDurationMinutes: b.config.BlockDurationMinutes,
@ -273,6 +274,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
}
} else {
instanceStep = &awscommon.StepRunSourceInstance{
PollingConfig: b.config.PollingConfig,
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
LaunchMappings: b.config.LaunchMappings,
Comm: &b.config.RunConfig.Comm,
@ -385,6 +387,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
EnableAMISriovNetSupport: b.config.AMISriovNetSupport,
EnableAMIENASupport: b.config.AMIENASupport,
AMISkipBuildRegion: b.config.AMISkipBuildRegion,
PollingConfig: b.config.PollingConfig,
},
&awscommon.StepAMIRegionCopy{
AccessConfig: &b.config.AccessConfig,

View File

@ -31,6 +31,7 @@ type FlatConfig struct {
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check" hcl:"skip_metadata_api_check"`
Token *string `mapstructure:"token" required:"false" cty:"token" hcl:"token"`
VaultAWSEngine *common.FlatVaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false" cty:"vault_aws_engine" hcl:"vault_aws_engine"`
PollingConfig *common.FlatAWSPollingConfig `mapstructure:"aws_polling" required:"false" cty:"aws_polling" hcl:"aws_polling"`
AMIName *string `mapstructure:"ami_name" required:"true" cty:"ami_name" hcl:"ami_name"`
AMIDescription *string `mapstructure:"ami_description" required:"false" cty:"ami_description" hcl:"ami_description"`
AMIVirtType *string `mapstructure:"ami_virtualization_type" required:"false" cty:"ami_virtualization_type" hcl:"ami_virtualization_type"`
@ -177,6 +178,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
"aws_polling": &hcldec.BlockSpec{TypeName: "aws_polling", Nested: hcldec.ObjectSpec((*common.FlatAWSPollingConfig)(nil).HCL2Spec())},
"ami_name": &hcldec.AttrSpec{Name: "ami_name", Type: cty.String, Required: false},
"ami_description": &hcldec.AttrSpec{Name: "ami_description", Type: cty.String, Required: false},
"ami_virtualization_type": &hcldec.AttrSpec{Name: "ami_virtualization_type", Type: cty.String, Required: false},

View File

@ -14,6 +14,7 @@ import (
)
type StepRegisterAMI struct {
PollingConfig *awscommon.AWSPollingConfig
EnableAMIENASupport confighelper.Trilean
EnableAMISriovNetSupport bool
AMISkipBuildRegion bool
@ -80,7 +81,7 @@ func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) mul
// Wait for the image to become ready
ui.Say("Waiting for AMI to become ready...")
if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil {
if err := s.PollingConfig.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil {
err := fmt.Errorf("Error waiting for AMI: %s", err)
state.Put("error", err)
ui.Error(err.Error())

View File

@ -119,7 +119,10 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
if len(errs.Errors) > 0 {
return errs
}
awscommon.LogEnvOverrideWarnings()
if p.config.PollingConfig == nil {
p.config.PollingConfig = new(awscommon.AWSPollingConfig)
}
p.config.PollingConfig.LogEnvOverrideWarnings()
packer.LogSecretFilter.Set(p.config.AccessKey, p.config.SecretKey, p.config.Token)
log.Println(p.config)
@ -250,7 +253,7 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
// Wait for import process to complete, this takes a while
ui.Message(fmt.Sprintf("Waiting for task %s to complete (may take a while)", *import_start.ImportTaskId))
err = awscommon.WaitUntilImageImported(aws.BackgroundContext(), ec2conn, *import_start.ImportTaskId)
err = p.config.PollingConfig.WaitUntilImageImported(aws.BackgroundContext(), ec2conn, *import_start.ImportTaskId)
if err != nil {
// Retrieve the status message
@ -313,7 +316,7 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
ui.Message(fmt.Sprintf("Waiting for AMI rename to complete (may take a while)"))
if err := awscommon.WaitUntilAMIAvailable(aws.BackgroundContext(), ec2conn, *resp.ImageId); err != nil {
if err := p.config.PollingConfig.WaitUntilAMIAvailable(aws.BackgroundContext(), ec2conn, *resp.ImageId); err != nil {
return nil, false, false, fmt.Errorf("Error waiting for AMI (%s): %s", *resp.ImageId, err)
}

View File

@ -30,6 +30,7 @@ type FlatConfig struct {
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check" hcl:"skip_metadata_api_check"`
Token *string `mapstructure:"token" required:"false" cty:"token" hcl:"token"`
VaultAWSEngine *common.FlatVaultAWSEngineOptions `mapstructure:"vault_aws_engine" required:"false" cty:"vault_aws_engine" hcl:"vault_aws_engine"`
PollingConfig *common.FlatAWSPollingConfig `mapstructure:"aws_polling" required:"false" cty:"aws_polling" hcl:"aws_polling"`
S3Bucket *string `mapstructure:"s3_bucket_name" cty:"s3_bucket_name" hcl:"s3_bucket_name"`
S3Key *string `mapstructure:"s3_key_name" cty:"s3_key_name" hcl:"s3_key_name"`
S3Encryption *string `mapstructure:"s3_encryption" cty:"s3_encryption" hcl:"s3_encryption"`
@ -79,6 +80,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
"token": &hcldec.AttrSpec{Name: "token", Type: cty.String, Required: false},
"vault_aws_engine": &hcldec.BlockSpec{TypeName: "vault_aws_engine", Nested: hcldec.ObjectSpec((*common.FlatVaultAWSEngineOptions)(nil).HCL2Spec())},
"aws_polling": &hcldec.BlockSpec{TypeName: "aws_polling", Nested: hcldec.ObjectSpec((*common.FlatAWSPollingConfig)(nil).HCL2Spec())},
"s3_bucket_name": &hcldec.AttrSpec{Name: "s3_bucket_name", Type: cty.String, Required: false},
"s3_key_name": &hcldec.AttrSpec{Name: "s3_key_name", Type: cty.String, Required: false},
"s3_encryption": &hcldec.AttrSpec{Name: "s3_encryption", Type: cty.String, Required: false},

View File

@ -106,6 +106,12 @@ Block devices can be nested in the
@include 'builder/amazon/common/AccessConfig-not-required.mdx'
### Polling Configuration
@include 'builder/amazon/common/AWSPollingConfig.mdx'
@include 'builder/amazon/common/AWSPollingConfig-not-required.mdx'
## Basic Example
Here is a basic example. It is completely valid except for the access keys:

View File

@ -69,6 +69,12 @@ necessary for this build to succeed and can be found further down the page.
@include 'builder/amazon/common/AccessConfig-not-required.mdx'
### Polling Configuration
@include 'builder/amazon/common/AWSPollingConfig.mdx'
@include 'builder/amazon/common/AWSPollingConfig-not-required.mdx'
### Run Configuration
#### Required:

View File

@ -65,6 +65,12 @@ necessary for this build to succeed and can be found further down the page.
@include 'builder/amazon/common/AccessConfig-not-required.mdx'
### Polling Configuration
@include 'builder/amazon/common/AWSPollingConfig.mdx'
@include 'builder/amazon/common/AWSPollingConfig-not-required.mdx'
### Run Configuration
#### Required:

View File

@ -57,6 +57,12 @@ necessary for this build to succeed and can be found further down the page.
@include 'builder/amazon/common/AccessConfig-not-required.mdx'
### Polling Configuration
@include 'builder/amazon/common/AWSPollingConfig.mdx'
@include 'builder/amazon/common/AWSPollingConfig-not-required.mdx'
### AMI Configuration
#### Optional:

View File

@ -85,6 +85,12 @@ necessary for this build to succeed and can be found further down the page.
@include 'builder/amazon/common/AccessConfig-not-required.mdx'
### Polling Configuration
@include 'builder/amazon/common/AWSPollingConfig.mdx'
@include 'builder/amazon/common/AWSPollingConfig-not-required.mdx'
### Run Configuration
#### Required:

View File

@ -0,0 +1,11 @@
<!-- Code generated from the comments of the AWSPollingConfig struct in builder/amazon/common/state.go; DO NOT EDIT MANUALLY -->
- `max_attempts` (int) - Specifies the maximum number of attempts the waiter will check for resource state.
This value can also be set via the AWS_MAX_ATTEMPTS.
If both option and environment variable are set, the max_attempts will be considered over the AWS_MAX_ATTEMPTS.
If none is set, defaults to AWS waiter default which is 40 max_attempts.
- `delay_seconds` (int) - Specifies the delay in seconds between attempts to check the resource state.
This value can also be set via the AWS_POLL_DELAY_SECONDS.
If both option and environment variable are set, the delay_seconds will be considered over the AWS_POLL_DELAY_SECONDS.
If none is set, defaults to AWS waiter default which is 15 seconds.

View File

@ -0,0 +1,21 @@
<!-- Code generated from the comments of the AWSPollingConfig struct in builder/amazon/common/state.go; DO NOT EDIT MANUALLY -->
Polling configuration for the AWS waiter. Configures the waiter for resources creation or actions like attaching
volumes or importing image.
Usage example:
In JSON:
```json
"aws_polling" : {
"delay_seconds": 30,
"max_attempts": 50
}
```
In HCL2:
```hcl
aws_polling {
delay_seconds = 30
max_attempts = 50
}
```

View File

@ -81,3 +81,6 @@
ttl = "3600s"
}
```
- `aws_polling` (\*AWSPollingConfig) - [Polling configuration](#polling-configuration) for the AWS waiter. Configures the waiter that checks
resource state.

View File

@ -0,0 +1,3 @@
<!-- Code generated from the comments of the StateChangeConf struct in builder/amazon/common/state.go; DO NOT EDIT MANUALLY -->
StateChangeConf is the configuration struct used for `WaitForState`.