Compare commits

..

1 Commits

Author SHA1 Message Date
Wilken Rivera bd0ba33ce1 builder/amazon: Update logic for session credentials
When failing back to Session credentials the build should not error if
creds were returned successfully.

* Switching to %v verb of %w in cases where error is nil.

Closes #10000
2020-09-28 12:23:52 -04:00
3006 changed files with 168129 additions and 262498 deletions
+7 -7
View File
@@ -7,11 +7,11 @@ version: 2.1
executors:
golang:
docker:
- image: docker.mirror.hashicorp.services/circleci/golang:1.15
- image: circleci/golang:1.13
resource_class: medium+
darwin:
macos:
xcode: "12.0.0"
xcode: "9.0"
commands:
install-go-run-tests-unix:
@@ -67,7 +67,7 @@ jobs:
steps:
- install-go-run-tests-unix:
GOOS: darwin
GOVERSION: "1.15"
GOVERSION: "1.13"
- codecov/upload:
file: coverage.txt
test-windows:
@@ -76,7 +76,7 @@ jobs:
shell: bash.exe
steps:
- install-go-run-tests-windows:
GOVERSION: "1.15"
GOVERSION: "1.13"
- codecov/upload:
file: coverage.txt
check-lint:
@@ -153,7 +153,7 @@ jobs:
destination: /
build-website-docker-image:
docker:
- image: docker.mirror.hashicorp.services/circleci/buildpack-deps
- image: circleci/buildpack-deps
shell: /usr/bin/env bash -euo pipefail -c
steps:
- checkout
@@ -167,14 +167,14 @@ jobs:
echo "Dependencies have not changed, not building a new website docker image."
else
cd website/
docker login -u $WEBSITE_DOCKER_USER -p $WEBSITE_DOCKER_PASS
docker build -t hashicorp/packer-website:$IMAGE_TAG .
docker tag hashicorp/packer-website:$IMAGE_TAG hashicorp/packer-website:latest
docker login -u $WEBSITE_DOCKER_USER -p $WEBSITE_DOCKER_PASS
docker push hashicorp/packer-website
fi
algolia-index:
docker:
- image: docker.mirror.hashicorp.services/node:12
- image: node:12
steps:
- checkout
- run:
-1
View File
@@ -6,7 +6,6 @@
*.mdx text eol=lf
*.ps1 text eol=lf
*.hcl text eol=lf
*.txt text eol=lf
go.mod text eol=lf
go.sum text eol=lf
common/test-fixtures/root/* eol=lf
+1 -1
View File
@@ -259,7 +259,7 @@ does not attempt to track the latest version for each dependency.
#### Code generation
Packer relies on `go generate` to generate a [peg parser for boot
commands](https://github.com/hashicorp/packer/blob/master/packer-plugin-sdk/bootcommand/boot_command.go),
commands](https://github.com/hashicorp/packer/blob/master/common/bootcommand/boot_command.go),
[docs](https://github.com/hashicorp/packer/blob/master/website/pages/partials/builder/amazon/chroot/_Config-not-required.mdx)
and HCL2's bridging code. Packer's testing suite will run `make check-generate`
to check that all the generated files Packer needs are what they should be.
-1
View File
@@ -27,4 +27,3 @@ Thumbs.db
/packer.exe
.project
cache
/.vscode/
+2 -116
View File
@@ -1,118 +1,4 @@
## 1.6.6 (Upcoming)
### FEATURES:
* **New command** `fmt` allows users to format existing HCL2 configuration
files into a canonical style. Please see [fmt command
docs](https://packer.io/docs/commands/fmt) for more details. [GH-10225]
* **New function** `env` allows users to set the default value of a variable to
the value of an environment variable. Please see [env function
docs](https://www.packer.io/docs/from-1.5/functions/contextual/env") for
more details. [GH-10240]
* builder/azure-arm: Create keyvaults with SoftDelete enabled [GH-10210]
* builder/outscale: Add x509 certificate support [GH-10161]
* post-processor/yandex-export: Verify the access to a specific bucket
[GH-10188]
### IMPROVEMENTS
* builder/amazon-ebs: Add tags to launch templates. [GH-10203]
* builder/azure-arm: Add Azure CLI authentication support to builder.
[GH-10157]
* core/hcl: Update to `hcl2_upgrade` command to support complex variable
values and packer version blocks. [GH-10221]
* post-processor/vagrant-cloud: Add support for uploading directly to storage
on Vagrant Cloud. [GH-10193]
### BUG FIXES
* builder/amazon: Fix single `tag` interpolation to allow for templating engine
usage. [GH-10224]
## 1.6.5 (October 30, 2020)
### FEATURES:
* New Builder(s): Proxmox builder has been split into two new builders
`proxmox-iso` and `promox-clone`. See [Proxmox
Builder](https://packer.io/docs/builders/proxmox) for more information on
the builder. For users of the previous `proxmox` builder please use `packer
fix` to migrate your templates to the new `promox-iso` builder. [GH-9262]
### BUG FIXES:
* builder/amazon: SSM connection now recovers from reboots. [GH-10003]
* builder/azure-arm: Fix build failures due to the deletion of additional
managed disks defined in "disk_additional_size". [GH-10163]
* builder/azure-chroot: Fix typo in option `exlude_from_latest` to
`exclude_from_latest`. Old name will still be respected. [GH-10034]
* builder/googlecompute: Fix HCL image_encryption_key fields and use the same
casing in JSON and HCL2 [GH-10173]
* builder/openstack: Fix source image validation regression when using filters.
[GH-10065]
* builder/proxmox: Fix unhandled buildvar type for HCL2 enabled build
templates. [GH-10154]
* builder/qemu: Fix a regression where Packer would not wait properly in
step_shutdown when a null communicator was used. [GH-10178]
* builder/qemu: Fix crash in step_run of qemu when loading commhostport form
the statebag in a situation where the communicator is none. [GH-10145]
* builder/vsphere-clone: Packer was not respecting the "destroy" flag set in
the content library config, and always keeping the source vm. This has been
fixed. [GH-10165]
* builder/vsphere: Ensure builds are able to continue when no communicator has
been specified `"communicator": "none"`. [GH-9964]
* builder/vsphere: Fix CD uploads so that Packer does not try to delete a CD
that was not successfully uploaded. [GH-10155]
* core/hcl: Hide sensitive variables from output. [GH-10031]
* core/hcl: Packer HCL's "Coalesce" function now behaves same way as
Terraform's. [GH-10016]
* core: Fix artifact handling so that input artifacts are properly preserved in
postprocessors that don't modify artifacts. [GH-9996]
* core: Fix pathing in cd_files to copy proper directory tree when user
provided absolute paths. [GH-10022]
* provisioner/ansible: Ansible galaxy no longer forces use of collections in v1
files. [GH-10010]
### IMPROVEMENTS:
* builder/amazon-ebssurrogate: Apply snapshot tags at snapshot creation time.
[GH-10150]
* builder/amazon: Add `io2` as a supported volume type. [GH-10102]
* builder/amazon: Add support for source instance tenancy [GH-10085]
* builder/google: Add service account impersonation. [GH-9968] [GH-10054]
* builder/googlecompute: Add `skip_create_image` option. [GH-10115]
* builder/googlecompute: Allow users to select the algorithm to use when
generating temporary SSH keypair [GH-10111]
* builder/linode: Add `state_timeout` attribute to Linode builder. [GH-10128]
* builder/oracle-oci: New option to specify image compartment separate from
build compartment. [GH-10040]
* builder/oracle-oci: New option to specify boot volume size. [GH-10017]
* builder/oracle: Add `base_image_filter` option as alternative to
`base_image_ocid` [GH-10116]
* builder/outscale: Migrate to new Outscale SDK. [GH-10056]
* builder/proxmox: split Proxmox into proxmox-iso and proxmox-clone. [GH-9626]
[GH-10166]
* builder/scaleway: Allow the user to use an image label (eg ubuntu_focal)
instead of a hardcoded UUID on the Scaleway builder. [GH-10061]
* builder/vsphere: Skip iso download if hashed file is already present on
remote datastore. [GH-10143]
* builder/yandex: Add support for IAM credentials in the token field and
YC_TOKEN environment variable. [GH-10158]
* core/hcl: Add ability to set version restrictions [GH-10149]
* core/hcl: Add build.name variable so users can access build name in addition
to source name. [GH-10114]
* core/hcl: Add consul_key function to HCL templates. [GH-10119]
* core/hcl: Add HCL2 aws_secretsmanager function [GH-10124]
* core/hcl: Add packer.version variable to hcl configs so users can access the
Packer release version. [GH-10117]
* core: Let user provide type of generated ssh key instead of always doing ssh-
rsa [GH-10101]
## 1.6.4 (September 30, 2020)
### BUG FIXES:
* builder/amazon: Fix authentication issue when using instance profiles or
assumed roles for loading session-derived credentials. [GH-10007]
* builder/azure: Fix crash when using `azure_tag` or `azure_tags` configuration
options. [GH-10014]
* builder/qemu: Ensure `qemu_img_args` are honored during the disk convert
step. [GH-10001]
## 1.6.4 (Upcoming)
## 1.6.3 (September 25, 2020)
@@ -135,7 +21,7 @@
* builder/proxmox: Add `io_thread` option for supporting io threads when using
a `virtio-scsi-single` controller with a `scsi` or `virtio` disk type.
[GH-9969]
* builder/proxmox: Add ability to specify interfaces for http_directory and VM.
* builder/proxmox: Add ability to specify interfaces for http_directroy and VM.
[GH-9874]
* builder/proxmox: Allow the mounting of multiple ISOs via the `cd_drive`
option. [GH-9653]
+1 -1
View File
@@ -1,4 +1,4 @@
FROM docker.mirror.hashicorp.services/ubuntu:16.04
FROM ubuntu:16.04
ENV DEBIAN_FRONTEND noninteractive
+6 -7
View File
@@ -1,5 +1,4 @@
TEST?=$(shell go list ./...)
COUNT?=1
VET?=$(shell go list ./...)
ACC_TEST_BUILDERS?=all
ACC_TEST_PROVISIONERS?=all
@@ -123,9 +122,9 @@ generate: install-gen-deps ## Generate dynamically generated code
@echo "==> removing autogenerated markdown..."
@find website/pages/ -type f | xargs grep -l '^<!-- Code generated' | xargs rm -f
@echo "==> removing autogenerated code..."
@find post-processor packer-plugin-sdk helper template builder provisioner -type f | xargs grep -l '^// Code generated' | xargs rm -f
@find post-processor common helper template builder provisioner -type f | xargs grep -l '^// Code generated' | xargs rm -f
go generate ./...
go fmt packer-plugin-sdk/bootcommand/boot_command.go
go fmt common/bootcommand/boot_command.go
go run ./cmd/generate-fixer-deprecations
generate-check: generate ## Check go code generation is on par
@@ -137,7 +136,7 @@ generate-check: generate ## Check go code generation is on par
fi
test: mode-check vet ## Run unit tests
@go test -count $(COUNT) $(TEST) $(TESTARGS) -timeout=3m
@go test $(TEST) $(TESTARGS) -timeout=3m
# acctest runs provisioners acceptance tests
provisioners-acctest: install-build-deps generate
@@ -146,14 +145,14 @@ provisioners-acctest: install-build-deps generate
# testacc runs acceptance tests
testacc: install-build-deps generate ## Run acceptance tests
@echo "WARN: Acceptance tests will take a long time to run and may cost money. Ctrl-C if you want to cancel."
PACKER_ACC=1 go test -count $(COUNT) -v $(TEST) $(TESTARGS) -timeout=120m
PACKER_ACC=1 go test -v $(TEST) $(TESTARGS) -timeout=45m
testrace: mode-check vet ## Test with race detection enabled
@GO111MODULE=off go test -count $(COUNT) -race $(TEST) $(TESTARGS) -timeout=3m -p=8
@GO111MODULE=off go test -race $(TEST) $(TESTARGS) -timeout=3m -p=8
# Runs code coverage and open a html page with report
cover:
go test -count $(COUNT) $(TEST) $(TESTARGS) -timeout=3m -coverprofile=coverage.out
go test $(TEST) $(TESTARGS) -timeout=3m -coverprofile=coverage.out
go tool cover -html=coverage.out
rm coverage.out
+1 -1
View File
@@ -25,7 +25,7 @@ from a single source configuration.
Packer is lightweight, runs on every major operating system, and is highly
performant, creating machine images for multiple platforms in parallel. Packer
comes out of the box with support for many platforms, the full list of which can
be found at https://www.packer.io/docs/builders.
be found at https://www.packer.io/docs/builders/index.html.
Support for other platforms can be added via plugins.
+3 -3
View File
@@ -11,8 +11,8 @@ import (
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/builder/alicloud/version"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
"github.com/hashicorp/packer/version"
"github.com/mitchellh/go-homedir"
)
@@ -78,7 +78,7 @@ func (c *AlicloudAccessConfig) Client() (*ClientWrapper, error) {
return nil, err
}
client.AppendUserAgent(Packer, version.AlicloudPluginVersion.FormattedVersion())
client.AppendUserAgent(Packer, version.FormattedVersion())
client.SetReadTimeout(DefaultRequestReadTimeout)
c.client = &ClientWrapper{client}
+7 -9
View File
@@ -9,13 +9,12 @@ import (
"fmt"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/common"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep/commonsteps"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
// The unique ID for this builder
@@ -47,7 +46,6 @@ func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstruct
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
err := config.Decode(&b.config, &config.DecodeOpts{
PluginType: BuilderId,
Interpolate: true,
InterpolateContext: &b.config.ctx,
InterpolateFilter: &interpolate.RenderFilter{
@@ -165,8 +163,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
b.config.SSHPrivateIp),
SSHConfig: b.config.RunConfig.Comm.SSHConfigFunc(),
},
&commonsteps.StepProvision{},
&commonsteps.StepCleanupTempKeys{
&common.StepProvision{},
&common.StepCleanupTempKeys{
Comm: &b.config.RunConfig.Comm,
},
&stepStopAlicloudInstance{
@@ -207,7 +205,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
})
// Run!
b.runner = commonsteps.NewRunner(steps, b.config.PackerConfig, ui)
b.runner = common.NewRunner(steps, b.config.PackerConfig, ui)
b.runner.Run(ctx, state)
// If there was an error, return that
-6
View File
@@ -49,7 +49,6 @@ func (*FlatAlicloudDiskDevice) HCL2Spec() map[string]hcldec.Spec {
type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
@@ -108,8 +107,6 @@ type FlatConfig struct {
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password" hcl:"ssh_password"`
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" undocumented:"true" cty:"ssh_keypair_name" hcl:"ssh_keypair_name"`
SSHTemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" undocumented:"true" cty:"temporary_key_pair_name" hcl:"temporary_key_pair_name"`
SSHTemporaryKeyPairType *string `mapstructure:"temporary_key_pair_type" cty:"temporary_key_pair_type" hcl:"temporary_key_pair_type"`
SSHTemporaryKeyPairBits *int `mapstructure:"temporary_key_pair_bits" cty:"temporary_key_pair_bits" hcl:"temporary_key_pair_bits"`
SSHCiphers []string `mapstructure:"ssh_ciphers" cty:"ssh_ciphers" hcl:"ssh_ciphers"`
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys" hcl:"ssh_clear_authorized_keys"`
SSHKEXAlgos []string `mapstructure:"ssh_key_exchange_algorithms" cty:"ssh_key_exchange_algorithms" hcl:"ssh_key_exchange_algorithms"`
@@ -166,7 +163,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
"packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false},
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
@@ -225,8 +221,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"ssh_password": &hcldec.AttrSpec{Name: "ssh_password", Type: cty.String, Required: false},
"ssh_keypair_name": &hcldec.AttrSpec{Name: "ssh_keypair_name", Type: cty.String, Required: false},
"temporary_key_pair_name": &hcldec.AttrSpec{Name: "temporary_key_pair_name", Type: cty.String, Required: false},
"temporary_key_pair_type": &hcldec.AttrSpec{Name: "temporary_key_pair_type", Type: cty.String, Required: false},
"temporary_key_pair_bits": &hcldec.AttrSpec{Name: "temporary_key_pair_bits", Type: cty.Number, Required: false},
"ssh_ciphers": &hcldec.AttrSpec{Name: "ssh_ciphers", Type: cty.List(cty.String), Required: false},
"ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false},
"ssh_key_exchange_algorithms": &hcldec.AttrSpec{Name: "ssh_key_exchange_algorithms", Type: cty.List(cty.String), Required: false},
+1 -1
View File
@@ -4,8 +4,8 @@ import (
"reflect"
"testing"
helperconfig "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer"
helperconfig "github.com/hashicorp/packer/packer-plugin-sdk/template/config"
)
func testBuilderConfig() map[string]interface{} {
+83 -43
View File
@@ -8,12 +8,10 @@ import (
"strings"
"github.com/hashicorp/packer/hcl2template"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
// The "AlicloudDiskDevice" object us used for the `ECSSystemDiskMapping` and
// `ECSImagesDiskMappings` options, and contains the following fields:
type AlicloudDiskDevice struct {
// The value of disk name is blank by default. [2,
// 128] English or Chinese characters, must begin with an
@@ -21,7 +19,8 @@ type AlicloudDiskDevice struct {
// ., _ and -. The disk name will appear on the console. It cannot
// begin with `http://` or `https://`.
DiskName string `mapstructure:"disk_name" required:"false"`
// Category of the system disk. Optional values are:
// Category of the system disk. Optional values
// are:
// - cloud - general cloud disk
// - cloud_efficiency - efficiency cloud disk
// - cloud_ssd - cloud SSD
@@ -33,8 +32,6 @@ type AlicloudDiskDevice struct {
// Snapshots are used to create the data
// disk After this parameter is specified, Size is ignored. The actual
// size of the created disk is the size of the specified snapshot.
// This field is only used in the ECSImagesDiskMappings option, not
// the ECSSystemDiskMapping option.
SnapshotId string `mapstructure:"disk_snapshot_id" required:"false"`
// The value of disk description is blank by
// default. [2, 256] characters. The disk description will appear on the
@@ -47,51 +44,94 @@ type AlicloudDiskDevice struct {
// such as /dev/xvdb It is null unless the Status is In_use.
Device string `mapstructure:"disk_device" required:"false"`
// Whether or not to encrypt the data disk.
// If this option is set to true, the data disk will be encryped and
// corresponding snapshot in the target image will also be encrypted. By
// If this option is set to true, the data disk will be encryped and corresponding snapshot in the target image will also be encrypted. By
// default, if this is an extra data disk, Packer will not encrypt the
// data disk. Otherwise, Packer will keep the encryption setting to what
// it was in the source image. Please refer to Introduction of ECS disk
// encryption for more details.
// it was in the source image. Please refer to Introduction of ECS disk encryption
// for more details.
Encrypted config.Trilean `mapstructure:"disk_encrypted" required:"false"`
}
// The "AlicloudDiskDevices" object is used to define disk mappings for your
// instance.
type AlicloudDiskDevices struct {
// Image disk mapping for the system disk.
// See the [disk device configuration](#disk-devices-configuration) section
// for more information on options.
// Usage example:
// Image disk mapping for system
// disk.
// - `disk_category` (string) - Category of the system disk. Optional values
// are:
// - `cloud` - general cloud disk
// - `cloud_efficiency` - efficiency cloud disk
// - `cloud_ssd` - cloud SSD
//
// For phased-out instance types and non-I/O optimized instances, the
// default value is cloud. Otherwise, the default value is
// cloud\_efficiency.
//
// - `disk_description` (string) - The value of disk description is blank by
// default. \[2, 256\] characters. The disk description will appear on the
// console. It cannot begin with `http://` or `https://`.
//
// - `disk_name` (string) - The value of disk name is blank by default. \[2,
// 128\] English or Chinese characters, must begin with an
// uppercase/lowercase letter or Chinese character. Can contain numbers,
// `.`, `_` and `-`. The disk name will appear on the console. It cannot
// begin with `http://` or `https://`.
//
// - `disk_size` (number) - Size of the system disk, measured in GiB. Value
// range: \[20, 500\]. The specified value must be equal to or greater
// than max{20, ImageSize}. Default value: max{40, ImageSize}.
//
// ```json
// "builders": [{
// "type":"alicloud-ecs",
// "system_disk_mapping": {
// "disk_size": 50,
// "disk_name": "mydisk"
// },
// ...
// }
// ```
ECSSystemDiskMapping AlicloudDiskDevice `mapstructure:"system_disk_mapping" required:"false"`
// Add one or more data disks to the image.
// See the [disk device configuration](#disk-devices-configuration) section
// for more information on options.
// Usage example:
// Add one or more data
// disks to the image.
//
// - `disk_category` (string) - Category of the data disk. Optional values
// are:
// - `cloud` - general cloud disk
// - `cloud_efficiency` - efficiency cloud disk
// - `cloud_ssd` - cloud SSD
//
// Default value: cloud.
//
// - `disk_delete_with_instance` (boolean) - Whether or not the disk is
// released along with the instance:
// - True indicates that when the instance is released, this disk will
// be released with it
// - False indicates that when the instance is released, this disk will
// be retained.
// - `disk_description` (string) - The value of disk description is blank by
// default. \[2, 256\] characters. The disk description will appear on the
// console. It cannot begin with `http://` or `https://`.
//
// - `disk_device` (string) - Device information of the related instance:
// such as `/dev/xvdb` It is null unless the Status is In\_use.
//
// - `disk_name` (string) - The value of disk name is blank by default. \[2,
// 128\] English or Chinese characters, must begin with an
// uppercase/lowercase letter or Chinese character. Can contain numbers,
// `.`, `_` and `-`. The disk name will appear on the console. It cannot
// begin with `http://` or `https://`.
//
// - `disk_size` (number) - Size of the data disk, in GB, values range:
// - `cloud` - 5 \~ 2000
// - `cloud_efficiency` - 20 \~ 2048
// - `cloud_ssd` - 20 \~ 2048
//
// The value should be equal to or greater than the size of the specific
// SnapshotId.
//
// - `disk_snapshot_id` (string) - Snapshots are used to create the data
// disk After this parameter is specified, Size is ignored. The actual
// size of the created disk is the size of the specified snapshot.
//
// Snapshots from on or before July 15, 2013 cannot be used to create a
// disk.
//
// - `disk_encrypted` (boolean) - Whether or not to encrypt the data disk.
// If this option is set to true, the data disk will be encryped and corresponding snapshot in the target image will also be encrypted. By
// default, if this is an extra data disk, Packer will not encrypt the
// data disk. Otherwise, Packer will keep the encryption setting to what
// it was in the source image. Please refer to Introduction of [ECS disk encryption](https://www.alibabacloud.com/help/doc-detail/59643.htm)
// for more details.
//
// ```json
// "builders": [{
// "type":"alicloud-ecs",
// "image_disk_mappings": [
// {
// "disk_snapshot_id": "someid",
// "disk_device": "dev/xvdb"
// }
// ],
// ...
// }
// ```
ECSImagesDiskMappings []AlicloudDiskDevice `mapstructure:"image_disk_mappings" required:"false"`
}
+1 -1
View File
@@ -4,8 +4,8 @@ import (
"fmt"
"strconv"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
func cleanUpMessage(state multistep.StateBag, module string) {
+3 -3
View File
@@ -8,10 +8,10 @@ import (
"os"
"strings"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/packer-plugin-sdk/uuid"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
type RunConfig struct {
+1 -1
View File
@@ -3,7 +3,7 @@ package ecs
import (
"time"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/helper/multistep"
)
var (
+1 -1
View File
@@ -6,8 +6,8 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepAttachKeyPair struct {
@@ -5,8 +5,8 @@ import (
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepCheckAlicloudSourceImage struct {
+2 -2
View File
@@ -5,12 +5,12 @@ import (
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
"github.com/hashicorp/packer/packer-plugin-sdk/uuid"
"github.com/hashicorp/packer/common/uuid"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepConfigAlicloudEIP struct {
+1 -1
View File
@@ -8,8 +8,8 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepConfigAlicloudKeyPair struct {
@@ -5,8 +5,8 @@ import (
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepConfigAlicloudPublicIP struct {
@@ -6,9 +6,9 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/uuid"
)
type stepConfigAlicloudSecurityGroup struct {
+2 -2
View File
@@ -7,9 +7,9 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/uuid"
)
type stepConfigAlicloudVPC struct {
+2 -2
View File
@@ -6,9 +6,9 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/uuid"
)
type stepConfigAlicloudVSwitch struct {
+3 -3
View File
@@ -5,13 +5,13 @@ import (
"fmt"
"time"
"github.com/hashicorp/packer/packer-plugin-sdk/random"
"github.com/hashicorp/packer/common/random"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/uuid"
)
type stepCreateAlicloudImage struct {
+3 -3
View File
@@ -7,14 +7,14 @@ import (
"io/ioutil"
"strconv"
"github.com/hashicorp/packer/packer-plugin-sdk/uuid"
"github.com/hashicorp/packer/common/uuid"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
confighelper "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
confighelper "github.com/hashicorp/packer/packer-plugin-sdk/template/config"
)
type stepCreateAlicloudInstance struct {
+1 -1
View File
@@ -7,8 +7,8 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepCreateAlicloudSnapshot struct {
+1 -1
View File
@@ -5,8 +5,8 @@ import (
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepCreateTags struct {
@@ -6,8 +6,8 @@ import (
"log"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepDeleteAlicloudImageSnapshots struct {
+1 -1
View File
@@ -5,8 +5,8 @@ import (
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepPreValidate struct {
@@ -7,9 +7,9 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
confighelper "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
confighelper "github.com/hashicorp/packer/packer-plugin-sdk/template/config"
)
type stepRegionCopyAlicloudImage struct {
+1 -1
View File
@@ -6,8 +6,8 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepRunAlicloudInstance struct {
+1 -1
View File
@@ -5,8 +5,8 @@ import (
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepShareAlicloudImage struct {
+1 -1
View File
@@ -8,8 +8,8 @@ import (
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/services/ecs"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type stepStopAlicloudInstance struct {
-13
View File
@@ -1,13 +0,0 @@
package version
import (
"github.com/hashicorp/packer/helper/version"
packerVersion "github.com/hashicorp/packer/version"
)
var AlicloudPluginVersion *version.PluginVersion
func init() {
AlicloudPluginVersion = version.InitializePluginVersion(
packerVersion.Version, packerVersion.VersionPrerelease)
}
+8 -13
View File
@@ -14,16 +14,15 @@ import (
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer/builder"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/chroot"
"github.com/hashicorp/packer/hcl2template"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/chroot"
"github.com/hashicorp/packer/packer-plugin-sdk/common"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep/commonsteps"
"github.com/hashicorp/packer/packer-plugin-sdk/packerbuilderdata"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
// The unique ID for this builder
@@ -195,18 +194,14 @@ func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstruct
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
b.config.ctx.Funcs = awscommon.TemplateFuncs
err := config.Decode(&b.config, &config.DecodeOpts{
PluginType: BuilderId,
Interpolate: true,
InterpolateContext: &b.config.ctx,
InterpolateFilter: &interpolate.RenderFilter{
Exclude: []string{
"ami_description",
"snapshot_tags",
"snapshot_tag",
"tags",
"tag",
"root_volume_tags",
"root_volume_tag",
"command_wrapper",
"post_mount_commands",
"pre_mount_commands",
@@ -373,7 +368,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
state.Put("hook", hook)
state.Put("ui", ui)
state.Put("wrappedCommand", common.CommandWrapper(wrappedCommand))
generatedData := &packerbuilderdata.GeneratedData{State: state}
generatedData := &builder.GeneratedData{State: state}
// Build the steps
steps := []multistep.Step{
@@ -479,7 +474,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
)
// Run!
b.runner = commonsteps.NewRunner(steps, b.config.PackerConfig, ui)
b.runner = common.NewRunner(steps, b.config.PackerConfig, ui)
b.runner.Run(ctx, state)
// If there was an error, return that
@@ -13,7 +13,6 @@ import (
type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
@@ -53,7 +52,6 @@ type FlatConfig struct {
RawRegion *string `mapstructure:"region" required:"true" cty:"region" hcl:"region"`
SecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key" hcl:"secret_key"`
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check" hcl:"skip_metadata_api_check"`
SkipCredsValidation *bool `mapstructure:"skip_credential_validation" cty:"skip_credential_validation" hcl:"skip_credential_validation"`
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"`
@@ -93,7 +91,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
"packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false},
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
@@ -133,7 +130,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"region": &hcldec.AttrSpec{Name: "region", Type: cty.String, Required: false},
"secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false},
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
"skip_credential_validation": &hcldec.AttrSpec{Name: "skip_credential_validation", 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())},
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"runtime"
"testing"
"github.com/hashicorp/packer/packer-plugin-sdk/common"
"github.com/hashicorp/packer/common"
)
func TestCopyFile(t *testing.T) {
+1 -1
View File
@@ -8,8 +8,8 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
// StepAttachVolume attaches the previously created volume to an
@@ -3,7 +3,7 @@ package chroot
import (
"testing"
"github.com/hashicorp/packer/packer-plugin-sdk/chroot"
"github.com/hashicorp/packer/common/chroot"
)
func TestAttachVolumeCleanupFunc_ImplementsCleanupFunc(t *testing.T) {
@@ -5,8 +5,8 @@ import (
"fmt"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
// StepCheckRootDevice makes sure the root device on the AMI is EBS-backed.
+2 -2
View File
@@ -9,9 +9,9 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
// StepCreateVolume creates a new volume from the snapshot of the root
+2 -2
View File
@@ -5,9 +5,9 @@ import (
"fmt"
"log"
"github.com/hashicorp/packer/common/chroot"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/chroot"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
// StepEarlyUnflock unlocks the flock.
+1 -1
View File
@@ -7,8 +7,8 @@ import (
"os"
"path/filepath"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
// StepFlock provisions the instance within a chroot.
+1 -1
View File
@@ -3,7 +3,7 @@ package chroot
import (
"testing"
"github.com/hashicorp/packer/packer-plugin-sdk/chroot"
"github.com/hashicorp/packer/common/chroot"
)
func TestFlockCleanupFunc_ImplementsCleanupFunc(t *testing.T) {
+1 -1
View File
@@ -8,8 +8,8 @@ import (
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
// StepInstanceInfo verifies that this builder is running on an EC2 instance.
+5 -5
View File
@@ -10,11 +10,11 @@ import (
"strings"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/builder"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/common"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/packerbuilderdata"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
type mountPathData struct {
@@ -31,7 +31,7 @@ type StepMountDevice struct {
MountPartition string
mountPath string
GeneratedData *packerbuilderdata.GeneratedData
GeneratedData *builder.GeneratedData
}
func (s *StepMountDevice) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
@@ -3,7 +3,7 @@ package chroot
import (
"testing"
"github.com/hashicorp/packer/packer-plugin-sdk/chroot"
"github.com/hashicorp/packer/common/chroot"
)
func TestMountDeviceCleanupFunc_ImplementsCleanupFunc(t *testing.T) {
+3 -3
View File
@@ -6,14 +6,14 @@ import (
"log"
"os"
"github.com/hashicorp/packer/builder"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/packerbuilderdata"
)
// StepPrepareDevice finds an available device and sets it.
type StepPrepareDevice struct {
GeneratedData *packerbuilderdata.GeneratedData
GeneratedData *builder.GeneratedData
}
func (s *StepPrepareDevice) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
+3 -3
View File
@@ -7,10 +7,10 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/common/random"
confighelper "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/random"
confighelper "github.com/hashicorp/packer/packer-plugin-sdk/template/config"
)
// StepRegisterAMI creates the AMI.
@@ -4,7 +4,7 @@ import (
"testing"
amazon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/packer-plugin-sdk/common"
"github.com/hashicorp/packer/common"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
+1 -1
View File
@@ -7,8 +7,8 @@ import (
"github.com/aws/aws-sdk-go/service/ec2"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
// StepSnapshot creates a snapshot of the created volume.
+170 -34
View File
@@ -9,17 +9,19 @@ import (
"log"
"net/http"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
awsCredentials "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
awsbase "github.com/hashicorp/aws-sdk-go-base"
"github.com/aws/aws-sdk-go/service/sts"
cleanhttp "github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/packer/builder/amazon/common/awserrors"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
vaultapi "github.com/hashicorp/vault/api"
homedir "github.com/mitchellh/go-homedir"
)
// AssumeRoleConfig lets users set configuration options for assuming a special
@@ -146,8 +148,6 @@ type AccessConfig struct {
// validation of the ami_regions configuration option. Default false.
SkipValidation bool `mapstructure:"skip_region_validation" required:"false"`
SkipMetadataApiCheck bool `mapstructure:"skip_metadata_api_check"`
// Set to true if you want to skip validating AWS credentials before runtime.
SkipCredsValidation bool `mapstructure:"skip_credential_validation"`
// The access token to use. This is different from the
// access key and secret key. If you're not sure what this is, then you
// probably don't need it. This will also be read from the AWS_SESSION_TOKEN
@@ -272,7 +272,7 @@ func (c *AccessConfig) Session() (*session.Session, error) {
cp, err := c.session.Config.Credentials.Get()
if awserrors.Matches(err, "NoCredentialProviders", "") {
if IsAWSErr(err, "NoCredentialProviders", "") {
return nil, c.NewNoValidCredentialSourcesError(err)
}
@@ -309,35 +309,171 @@ func (c *AccessConfig) IsChinaCloud() bool {
// endpoints. GetCredentials also validates the credentials and the ability to
// assume a role or will return an error if unsuccessful.
func (c *AccessConfig) GetCredentials(config *aws.Config) (*awsCredentials.Credentials, error) {
// Reload values into the config used by the Packer-Terraform shared SDK
awsbaseConfig := &awsbase.Config{
AccessKey: c.AccessKey,
AssumeRoleARN: c.AssumeRole.AssumeRoleARN,
AssumeRoleDurationSeconds: c.AssumeRole.AssumeRoleDurationSeconds,
AssumeRoleExternalID: c.AssumeRole.AssumeRoleExternalID,
AssumeRolePolicy: c.AssumeRole.AssumeRolePolicy,
AssumeRolePolicyARNs: c.AssumeRole.AssumeRolePolicyARNs,
AssumeRoleSessionName: c.AssumeRole.AssumeRoleSessionName,
AssumeRoleTags: c.AssumeRole.AssumeRoleTags,
AssumeRoleTransitiveTagKeys: c.AssumeRole.AssumeRoleTransitiveTagKeys,
CredsFilename: c.CredsFilename,
DebugLogging: false,
// TODO: implement for Packer
// IamEndpoint: c.Endpoints["iam"],
Insecure: c.InsecureSkipTLSVerify,
MaxRetries: c.MaxRetries,
Profile: c.ProfileName,
Region: c.RawRegion,
SecretKey: c.SecretKey,
SkipCredsValidation: c.SkipCredsValidation,
SkipMetadataApiCheck: c.SkipMetadataApiCheck,
// TODO: implement for Packer
// SkipRequestingAccountId: c.SkipRequestingAccountId,
// StsEndpoint: c.Endpoints["sts"],
Token: c.Token,
sharedCredentialsFilename, err := homedir.Expand(c.CredsFilename)
if err != nil {
return nil, fmt.Errorf("error expanding shared credentials filename: %v", err)
}
return awsbase.GetCredentials(awsbaseConfig)
// Create a credentials chain that tries to load credentials from various
// common sources: config vars, then local profiles.
// Rather than using the default credentials chain, build a chain provider,
// lazy-evaluated by aws-sdk
providers := []awsCredentials.Provider{
// Tries to set new credentials object using the given
// access_key/secret_key/token. If they are not set, this will fail
// over to the other credentials providers
&awsCredentials.StaticProvider{Value: awsCredentials.Value{
AccessKeyID: c.AccessKey,
SecretAccessKey: c.SecretKey,
SessionToken: c.Token,
}},
// Tries to load credentials from environment.
&awsCredentials.EnvProvider{},
// Tries to load credentials from local file.
// If sharedCredentialsFilename is empty, the AWS sdk will use the
// environment var AWS_SHARED_CREDENTIALS_FILE to determine the file
// location, and if that's not set, AWS will use the default locations
// of:
// - Linux/Unix: $HOME/.aws/credentials
// - Windows: %USERPROFILE%\.aws\credentials
&awsCredentials.SharedCredentialsProvider{
Filename: sharedCredentialsFilename,
Profile: c.ProfileName,
},
}
// Validate the credentials before returning them
creds := awsCredentials.NewChainCredentials(providers)
cp, err := creds.Get()
if IsAWSErr(err, "NoCredentialProviders", "") {
creds, err = c.GetCredentialsFromSession()
if err != nil {
return nil, err
}
}
if err != nil {
return nil, fmt.Errorf("Error loading credentials for AWS Provider: %v", err)
}
log.Printf("[INFO] AWS Auth provider used: %q", cp.ProviderName)
// In the "normal" flow (i.e. not assuming a role), we return here.
if c.AssumeRole.AssumeRoleARN == "" {
return creds, nil
}
// create a config for the assume role session based off the config we
// created for our main sessions
assumeRoleAWSConfig := config.Copy()
assumeRoleAWSConfig.CredentialsChainVerboseErrors = aws.Bool(true)
assumeRoleSession, err := session.NewSession(assumeRoleAWSConfig)
if err != nil {
return nil, fmt.Errorf("error creating assume role session: %v", err)
}
stsclient := sts.New(assumeRoleSession)
assumeRoleProvider := &stscreds.AssumeRoleProvider{
Client: stsclient,
RoleARN: c.AssumeRole.AssumeRoleARN,
}
if c.AssumeRole.AssumeRoleDurationSeconds > 0 {
assumeRoleProvider.Duration = time.Duration(c.AssumeRole.AssumeRoleDurationSeconds) * time.Second
}
if c.AssumeRole.AssumeRoleExternalID != "" {
assumeRoleProvider.ExternalID = aws.String(c.AssumeRole.AssumeRoleExternalID)
}
if c.AssumeRole.AssumeRolePolicy != "" {
assumeRoleProvider.Policy = aws.String(c.AssumeRole.AssumeRolePolicy)
}
if len(c.AssumeRole.AssumeRolePolicyARNs) > 0 {
var policyDescriptorTypes []*sts.PolicyDescriptorType
for _, policyARN := range c.AssumeRole.AssumeRolePolicyARNs {
policyDescriptorType := &sts.PolicyDescriptorType{
Arn: aws.String(policyARN),
}
policyDescriptorTypes = append(policyDescriptorTypes, policyDescriptorType)
}
assumeRoleProvider.PolicyArns = policyDescriptorTypes
}
if c.AssumeRole.AssumeRoleSessionName != "" {
assumeRoleProvider.RoleSessionName = c.AssumeRole.AssumeRoleSessionName
}
if len(c.AssumeRole.AssumeRoleTags) > 0 {
var tags []*sts.Tag
for k, v := range c.AssumeRole.AssumeRoleTags {
tag := &sts.Tag{
Key: aws.String(k),
Value: aws.String(v),
}
tags = append(tags, tag)
}
assumeRoleProvider.Tags = tags
}
if len(c.AssumeRole.AssumeRoleTransitiveTagKeys) > 0 {
assumeRoleProvider.TransitiveTagKeys = aws.StringSlice(c.AssumeRole.AssumeRoleTransitiveTagKeys)
}
providers = []awsCredentials.Provider{assumeRoleProvider}
assumeRoleCreds := awsCredentials.NewChainCredentials(providers)
_, err = assumeRoleCreds.Get()
if err != nil {
return nil, fmt.Errorf("Unable to assume role: %w", err)
}
return assumeRoleCreds, nil
}
// GetCredentialsFromSession returns credentials derived from a session. A
// session uses the AWS SDK Go chain of providers so may use a provider (e.g.,
// ProcessProvider) that is not part of the Packer provider chain.
func (c *AccessConfig) GetCredentialsFromSession() (*awsCredentials.Credentials, error) {
log.Printf("[INFO] Attempting to use session-derived credentials")
// Avoid setting HTTPClient here as it will prevent the ec2metadata
// client from automatically lowering the timeout to 1 second.
options := &session.Options{
Config: aws.Config{
MaxRetries: aws.Int(0),
Region: aws.String(c.RawRegion),
},
Profile: c.ProfileName,
SharedConfigState: session.SharedConfigEnable,
}
sess, err := session.NewSessionWithOptions(*options)
if err != nil {
if IsAWSErr(err, "NoCredentialProviders", "") {
return nil, c.NewNoValidCredentialSourcesError(err)
}
return nil, fmt.Errorf("Error creating AWS session: %v", err)
}
creds := sess.Config.Credentials
cp, err := sess.Config.Credentials.Get()
if err != nil {
return nil, c.NewNoValidCredentialSourcesError(err)
}
log.Printf("[INFO] Successfully derived credentials from session")
log.Printf("[INFO] AWS Auth provider used: %q", cp.ProviderName)
return creds, nil
}
func (c *AccessConfig) GetCredsFromVault() error {
@@ -413,7 +549,7 @@ func (c *AccessConfig) NewNoValidCredentialSourcesError(err error) error {
return fmt.Errorf("No valid credential sources found for AWS Builder. "+
"Please see https://www.packer.io/docs/builders/amazon#authentication "+
"for more information on providing credentials for the AWS Builder. "+
"Error: %w", err)
"Error: %v", err)
}
func (c *AccessConfig) NewEC2Connection() (ec2iface.EC2API, error) {
+2 -2
View File
@@ -8,8 +8,8 @@ import (
"regexp"
"github.com/hashicorp/packer/hcl2template"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
// AMIConfig is for common configuration related to creating AMIs.
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer/helper/config"
)
func testAMIConfig() *AMIConfig {
-18
View File
@@ -1,18 +0,0 @@
package awserrors
import (
"strings"
"github.com/aws/aws-sdk-go/aws/awserr"
)
// Returns true if the err matches all these conditions:
// * err is of type awserr.Error
// * Error.Code() matches code
// * Error.Message() contains message
func Matches(err error, code string, message string) bool {
if err, ok := err.(awserr.Error); ok {
return err.Code() == code && strings.Contains(err.Message(), message)
}
return false
}
+4 -4
View File
@@ -9,8 +9,8 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/template/interpolate"
)
// These will be attached when launching your instance. Your
@@ -134,8 +134,8 @@ func (blockDevice BlockDevice) BuildEC2BlockDeviceMapping() *ec2.BlockDeviceMapp
ebsBlockDevice.VolumeSize = aws.Int64(blockDevice.VolumeSize)
}
// IOPS is only valid for io1 and io2 types
if blockDevice.VolumeType == "io1" || blockDevice.VolumeType == "io2" {
// IOPS is only valid for io1 type
if blockDevice.VolumeType == "io1" {
ebsBlockDevice.Iops = aws.Int64(blockDevice.IOPS)
}
+1 -20
View File
@@ -6,7 +6,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer/helper/config"
)
func TestBlockDevice(t *testing.T) {
@@ -66,25 +66,6 @@ func TestBlockDevice(t *testing.T) {
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
VolumeType: "io2",
VolumeSize: 8,
DeleteOnTermination: true,
IOPS: 1000,
},
Result: &ec2.BlockDeviceMapping{
DeviceName: aws.String("/dev/sdb"),
Ebs: &ec2.EbsBlockDevice{
VolumeType: aws.String("io2"),
VolumeSize: aws.Int64(8),
DeleteOnTermination: aws.Bool(true),
Iops: aws.Int64(1000),
},
},
},
{
Config: &BlockDevice{
DeviceName: "/dev/sdb",
+16 -4
View File
@@ -4,12 +4,13 @@ import (
"context"
"fmt"
"log"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/builder/amazon/common/awserrors"
"github.com/hashicorp/packer/packer-plugin-sdk/retry"
"github.com/hashicorp/packer/common/retry"
)
// DestroyAMIs deregisters the AWS machine images in imageids from an active AWS account
@@ -30,7 +31,7 @@ func DestroyAMIs(imageids []*string, ec2conn *ec2.EC2) error {
err = retry.Config{
Tries: 11,
ShouldRetry: func(err error) bool {
return awserrors.Matches(err, "UnauthorizedOperation", "")
return IsAWSErr(err, "UnauthorizedOperation", "")
},
RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 30 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
@@ -53,7 +54,7 @@ func DestroyAMIs(imageids []*string, ec2conn *ec2.EC2) error {
err = retry.Config{
Tries: 11,
ShouldRetry: func(err error) bool {
return awserrors.Matches(err, "UnauthorizedOperation", "")
return IsAWSErr(err, "UnauthorizedOperation", "")
},
RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 30 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) error {
@@ -73,3 +74,14 @@ func DestroyAMIs(imageids []*string, ec2conn *ec2.EC2) error {
}
return nil
}
// Returns true if the error matches all these conditions:
// * err is of type awserr.Error
// * Error.Code() matches code
// * Error.Message() contains message
func IsAWSErr(err error, code string, message string) bool {
if err, ok := err.(awserr.Error); ok {
return err.Code() == code && strings.Contains(err.Message(), message)
}
return false
}
@@ -3,8 +3,8 @@ package common
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/packerbuilderdata"
"github.com/hashicorp/packer/builder"
"github.com/hashicorp/packer/helper/multistep"
)
type BuildInfoTemplate struct {
@@ -17,7 +17,7 @@ type BuildInfoTemplate struct {
SourceAMITags map[string]string
}
func extractBuildInfo(region string, state multistep.StateBag, generatedData *packerbuilderdata.GeneratedData) *BuildInfoTemplate {
func extractBuildInfo(region string, state multistep.StateBag, generatedData *builder.GeneratedData) *BuildInfoTemplate {
rawSourceAMI, hasSourceAMI := state.GetOk("source_image")
if !hasSourceAMI {
return &BuildInfoTemplate{
@@ -6,8 +6,8 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/packerbuilderdata"
"github.com/hashicorp/packer/builder"
"github.com/hashicorp/packer/helper/multistep"
)
func testImage() *ec2.Image {
@@ -17,7 +17,6 @@ func testImage() *ec2.Image {
Name: aws.String("ami_test_name"),
OwnerId: aws.String("ami_test_owner_id"),
ImageOwnerAlias: aws.String("ami_test_owner_alias"),
RootDeviceType: aws.String("ebs"),
Tags: []*ec2.Tag{
{
Key: aws.String("key-1"),
@@ -36,8 +35,8 @@ func testState() multistep.StateBag {
return state
}
func testGeneratedData(state multistep.StateBag) packerbuilderdata.GeneratedData {
generatedData := packerbuilderdata.GeneratedData{State: state}
func testGeneratedData(state multistep.StateBag) builder.GeneratedData {
generatedData := builder.GeneratedData{State: state}
return generatedData
}
+6 -15
View File
@@ -11,10 +11,10 @@ import (
"strings"
"time"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/hcl2template"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/packer-plugin-sdk/uuid"
"github.com/hashicorp/packer/template/interpolate"
)
var reShutdownBehavior = regexp.MustCompile("^(stop|terminate)$")
@@ -376,12 +376,6 @@ type RunConfig struct {
// subnet-12345def, where Packer will launch the EC2 instance. This field is
// required if you are using an non-default VPC.
SubnetId string `mapstructure:"subnet_id" required:"false"`
// [Tenancy](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/dedicated-instance.html) used
// when Packer launches the EC2 instance, allowing it to be launched on dedicated hardware.
//
// The default is "default", meaning shared tenancy. Allowed values are "default",
// "dedicated" and "host".
Tenancy string `mapstructure:"tenancy" required:"false"`
// The name of the temporary key pair to
// generate. By default, Packer generates a name that looks like
// `packer_<UUID>`, where &lt;UUID&gt; is a 36 character unique identifier.
@@ -548,6 +542,10 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
msg := fmt.Errorf(`no iam_instance_profile defined; session_manager connectivity requires a valid instance profile with AmazonSSMManagedInstanceCore permissions. Alternatively a temporary_iam_instance_profile_policy_document can be used.`)
errs = append(errs, msg)
}
if c.PauseBeforeSSM == 0 {
c.PauseBeforeSSM = 10 * time.Second
}
}
if c.Comm.SSHKeyPairName != "" {
@@ -633,13 +631,6 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
}
}
if c.Tenancy != "" &&
c.Tenancy != "default" &&
c.Tenancy != "dedicated" &&
c.Tenancy != "host" {
errs = append(errs, fmt.Errorf("Error: Unknown tenancy type %s", c.Tenancy))
}
return errs
}
-20
View File
@@ -232,23 +232,3 @@ func TestRunConfigPrepare_TemporaryKeyPairName(t *testing.T) {
t.Fatal("keypair name does not match")
}
}
func TestRunConfigPrepare_TenancyBad(t *testing.T) {
c := testConfig()
c.Tenancy = "not_real"
if err := c.Prepare(nil); len(err) != 1 {
t.Fatal("Should error if tenancy is set to an invalid type")
}
}
func TestRunConfigPrepare_TenancyGood(t *testing.T) {
validTenancy := []string{"", "default", "dedicated", "host"}
for _, vt := range validTenancy {
c := testConfig()
c.Tenancy = vt
if err := c.Prepare(nil); len(err) != 0 {
t.Fatalf("Should not error if tenancy is set to %s", vt)
}
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"time"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/helper/multistep"
)
type ec2Describer interface {
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/helper/multistep"
)
const (
-117
View File
@@ -1,117 +0,0 @@
package ssm
import (
"context"
"encoding/json"
"fmt"
"log"
"os/exec"
"strconv"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ssm"
"github.com/aws/aws-sdk-go/service/ssm/ssmiface"
"github.com/hashicorp/packer/builder/amazon/common/awserrors"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/retry"
"github.com/hashicorp/packer/packer-plugin-sdk/shell-local/localexec"
)
type Session struct {
SvcClient ssmiface.SSMAPI
Region string
InstanceID string
LocalPort, RemotePort int
}
func (s Session) buildTunnelInput() *ssm.StartSessionInput {
portNumber, localPortNumber := strconv.Itoa(s.RemotePort), strconv.Itoa(s.LocalPort)
params := map[string][]*string{
"portNumber": []*string{aws.String(portNumber)},
"localPortNumber": []*string{aws.String(localPortNumber)},
}
return &ssm.StartSessionInput{
DocumentName: aws.String("AWS-StartPortForwardingSession"),
Parameters: params,
Target: aws.String(s.InstanceID),
}
}
// getCommand return a valid ordered set of arguments to pass to the driver command.
func (s Session) getCommand(ctx context.Context) ([]string, string, error) {
input := s.buildTunnelInput()
var session *ssm.StartSessionOutput
err := retry.Config{
ShouldRetry: func(err error) bool { return awserrors.Matches(err, "TargetNotConnected", "") },
RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 60 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) (err error) {
session, err = s.SvcClient.StartSessionWithContext(ctx, input)
return err
})
if err != nil {
return nil, "", err
}
if session == nil {
return nil, "", fmt.Errorf("an active Amazon SSM Session is required before trying to open a session tunnel")
}
// AWS session-manager-plugin requires a valid session be passed in JSON.
sessionDetails, err := json.Marshal(session)
if err != nil {
return nil, *session.SessionId, fmt.Errorf("error encountered in reading session details %s", err)
}
// AWS session-manager-plugin requires the parameters used in the session to be passed in JSON as well.
sessionParameters, err := json.Marshal(input)
if err != nil {
return nil, "", fmt.Errorf("error encountered in reading session parameter details %s", err)
}
// Args must be in this order
args := []string{
string(sessionDetails),
s.Region,
"StartSession",
"", // ProfileName
string(sessionParameters),
*session.StreamUrl,
}
return args, *session.SessionId, nil
}
// Start an interactive Systems Manager session with a remote instance via the
// AWS session-manager-plugin. To terminate the session you must cancell the
// context. If you do not wish to terminate the session manually: calling
// StopSession on a instance of this driver will terminate the active session
// created from calling StartSession.
func (s Session) Start(ctx context.Context, ui packer.Ui) error {
for ctx.Err() == nil {
log.Printf("ssm: Starting PortForwarding session to instance %s", s.InstanceID)
args, sessionID, err := s.getCommand(ctx)
if sessionID != "" {
defer func() {
_, err := s.SvcClient.TerminateSession(&ssm.TerminateSessionInput{SessionId: aws.String(sessionID)})
if err != nil {
ui.Error(fmt.Sprintf("Error terminating SSM Session %q. Please terminate the session manually: %s", sessionID, err))
}
}()
}
if err != nil {
return err
}
cmd := exec.CommandContext(ctx, "session-manager-plugin", args...)
ui.Message(fmt.Sprintf("Starting portForwarding session %q.", sessionID))
err = localexec.RunAndStream(cmd, ui, nil)
if err != nil {
ui.Error(err.Error())
}
}
return nil
}
+197
View File
@@ -0,0 +1,197 @@
package common
import (
"context"
"encoding/json"
"fmt"
"log"
"os/exec"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ssm"
"github.com/aws/aws-sdk-go/service/ssm/ssmiface"
"github.com/hashicorp/packer/common/retry"
"github.com/mitchellh/iochan"
)
const (
sessionManagerPluginName string = "session-manager-plugin"
//sessionCommand is the AWS-SDK equivalent to the command you would specify to `aws ssm ...`
sessionCommand string = "StartSession"
)
type SSMDriverConfig struct {
SvcClient ssmiface.SSMAPI
Region string
ProfileName string
SvcEndpoint string
}
type SSMDriver struct {
SSMDriverConfig
session *ssm.StartSessionOutput
sessionParams ssm.StartSessionInput
pluginCmdFunc func(context.Context) error
}
func NewSSMDriver(config SSMDriverConfig) *SSMDriver {
d := SSMDriver{SSMDriverConfig: config}
return &d
}
// StartSession starts an interactive Systems Manager session with a remote instance via the AWS session-manager-plugin
// This ssm.StartSessionOutput returned by this function can be used for terminating the session manually. If you do
// not wish to manage the session manually calling StopSession on a instance of this driver will terminate the active session
// created from calling StartSession.
func (d *SSMDriver) StartSession(ctx context.Context, input ssm.StartSessionInput) (*ssm.StartSessionOutput, error) {
log.Printf("Starting PortForwarding session to instance %q", aws.StringValue(input.Target))
var output *ssm.StartSessionOutput
err := retry.Config{
ShouldRetry: func(err error) bool { return IsAWSErr(err, "TargetNotConnected", "") },
RetryDelay: (&retry.Backoff{InitialBackoff: 200 * time.Millisecond, MaxBackoff: 60 * time.Second, Multiplier: 2}).Linear,
}.Run(ctx, func(ctx context.Context) (err error) {
output, err = d.SvcClient.StartSessionWithContext(ctx, &input)
return err
})
if err != nil {
return nil, fmt.Errorf("error encountered in starting session for instance %q: %s", aws.StringValue(input.Target), err)
}
d.session = output
d.sessionParams = input
if d.pluginCmdFunc == nil {
d.pluginCmdFunc = d.openTunnelForSession
}
if err := d.pluginCmdFunc(ctx); err != nil {
return nil, fmt.Errorf("error encountered in starting session for instance %q: %s", aws.StringValue(input.Target), err)
}
return d.session, nil
}
func (d *SSMDriver) openTunnelForSession(ctx context.Context) error {
args, err := d.Args()
if err != nil {
return fmt.Errorf("error encountered validating session details: %s", err)
}
cmd := exec.CommandContext(ctx, sessionManagerPluginName, args...)
// Let's build up our logging
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}
stderr, err := cmd.StderrPipe()
if err != nil {
return err
}
// Create the channels we'll use for data
stdoutCh := iochan.DelimReader(stdout, '\n')
stderrCh := iochan.DelimReader(stderr, '\n')
/* Loop and get all our output
This particular logger will continue to run through an entire Packer run.
The decision to continue logging is due to the fact that session-manager-plugin
doesn't give a good way of knowing if the command failed or was successful other
than looking at the logs. Seeing as the plugin is updated frequently and that the
log information is a bit sparse this logger will indefinitely relying on other
steps to fail if the tunnel is unable to be created. If successful then the user
will get more information on the tunnel connection when running in a debug mode.
*/
go func(ctx context.Context, prefix string) {
for {
select {
case <-ctx.Done():
return
case output, ok := <-stderrCh:
if !ok {
stderrCh = nil
break
}
if output != "" {
log.Printf("[ERROR] %s: %s", prefix, output)
}
case output, ok := <-stdoutCh:
if !ok {
stdoutCh = nil
break
}
if output != "" {
log.Printf("[DEBUG] %s: %s", prefix, output)
}
}
if stdoutCh == nil && stderrCh == nil {
log.Printf("[DEBUG] %s: %s", prefix, "active session has been terminated; stopping all log polling processes.")
return
}
}
}(ctx, sessionManagerPluginName)
log.Printf("[DEBUG %s] opening session tunnel to instance %q for session %q", sessionManagerPluginName,
aws.StringValue(d.sessionParams.Target),
aws.StringValue(d.session.SessionId),
)
if err := cmd.Start(); err != nil {
err = fmt.Errorf("error encountered when calling %s: %s\n", sessionManagerPluginName, err)
return err
}
return nil
}
// StopSession terminates an active Session Manager session
func (d *SSMDriver) StopSession() error {
if d.session == nil || d.session.SessionId == nil {
return fmt.Errorf("Unable to find a valid session to instance %q; skipping the termination step",
aws.StringValue(d.sessionParams.Target))
}
_, err := d.SvcClient.TerminateSession(&ssm.TerminateSessionInput{SessionId: d.session.SessionId})
if err != nil {
err = fmt.Errorf("Error terminating SSM Session %q. Please terminate the session manually: %s", aws.StringValue(d.session.SessionId), err)
}
return err
}
// Args validates the driver inputs before returning an ordered set of arguments to pass to the driver command.
func (d *SSMDriver) Args() ([]string, error) {
if d.session == nil {
return nil, fmt.Errorf("an active Amazon SSM Session is required before trying to open a session tunnel")
}
// AWS session-manager-plugin requires a valid session be passed in JSON.
sessionDetails, err := json.Marshal(d.session)
if err != nil {
return nil, fmt.Errorf("error encountered in reading session details %s", err)
}
// AWS session-manager-plugin requires the parameters used in the session to be passed in JSON as well.
sessionParameters, err := json.Marshal(d.sessionParams)
if err != nil {
return nil, fmt.Errorf("error encountered in reading session parameter details %s", err)
}
// Args must be in this order
args := []string{
string(sessionDetails),
d.Region,
sessionCommand,
d.ProfileName,
string(sessionParameters),
d.SvcEndpoint,
}
return args, nil
}
+188
View File
@@ -0,0 +1,188 @@
package common
import (
"context"
"fmt"
"reflect"
"strings"
"testing"
)
func NewSSMDriverWithMockSvc(svc *MockSSMSvc) *SSMDriver {
config := SSMDriverConfig{
SvcClient: svc,
Region: "east",
ProfileName: "default",
SvcEndpoint: "example.com",
}
driver := SSMDriver{
SSMDriverConfig: config,
pluginCmdFunc: func(ctx context.Context) error { return nil },
}
return &driver
}
func TestSSMDriver_StartSession(t *testing.T) {
mockSvc := MockSSMSvc{}
driver := NewSSMDriverWithMockSvc(&mockSvc)
if driver.SvcClient == nil {
t.Fatalf("SvcClient for driver should not be nil")
}
session, err := driver.StartSession(context.TODO(), MockStartSessionInput("fakeinstance"))
if err != nil {
t.Fatalf("calling StartSession should not error but got %v", err)
}
if !mockSvc.StartSessionCalled {
t.Fatalf("expected test to call ssm mocks but didn't")
}
if session == nil {
t.Errorf("expected session to be set after a successful call to StartSession")
}
if !reflect.DeepEqual(session, MockStartSessionOutput()) {
t.Errorf("expected session to be %v but got %v", MockStartSessionOutput(), session)
}
}
func TestSSMDriver_StartSessionWithError(t *testing.T) {
mockSvc := MockSSMSvc{StartSessionError: fmt.Errorf("bogus error")}
driver := NewSSMDriverWithMockSvc(&mockSvc)
if driver.SvcClient == nil {
t.Fatalf("SvcClient for driver should not be nil")
}
session, err := driver.StartSession(context.TODO(), MockStartSessionInput("fakeinstance"))
if err == nil {
t.Fatalf("StartSession should have thrown an error but didn't")
}
if !mockSvc.StartSessionCalled {
t.Errorf("expected test to call StartSession mock but didn't")
}
if session != nil {
t.Errorf("expected session to be nil after a bad StartSession call, but got %v", session)
}
}
func TestSSMDriver_StopSession(t *testing.T) {
mockSvc := MockSSMSvc{}
driver := NewSSMDriverWithMockSvc(&mockSvc)
if driver.SvcClient == nil {
t.Fatalf("SvcClient for driver should not be nil")
}
// Calling StopSession before StartSession should fail
err := driver.StopSession()
if err == nil {
t.Fatalf("calling StopSession() on a driver that has no started session should fail")
}
if driver.session != nil {
t.Errorf("expected session to be default to nil")
}
if mockSvc.TerminateSessionCalled {
t.Fatalf("a call to TerminateSession should not occur when there is no valid SSM session")
}
// Lets try calling start session, then stopping to see what happens.
session, err := driver.StartSession(context.TODO(), MockStartSessionInput("fakeinstance"))
if err != nil {
t.Fatalf("calling StartSession should not error but got %v", err)
}
if !mockSvc.StartSessionCalled {
t.Fatalf("expected test to call StartSession mock but didn't")
}
if session == nil || driver.session != session {
t.Errorf("expected session to be set after a successful call to StartSession")
}
if !reflect.DeepEqual(session, MockStartSessionOutput()) {
t.Errorf("expected session to be %v but got %v", MockStartSessionOutput(), session)
}
err = driver.StopSession()
if err != nil {
t.Errorf("calling StopSession() on a driver on a started session should not fail")
}
if !mockSvc.TerminateSessionCalled {
t.Fatalf("expected test to call StopSession mock but didn't")
}
}
func TestSSMDriver_Args(t *testing.T) {
tt := []struct {
Name string
ProfileName string
SkipStartSession bool
ErrorExpected bool
}{
{
Name: "NilSession",
SkipStartSession: true,
ErrorExpected: true,
},
{
Name: "NonNilSession",
ErrorExpected: false,
},
{
Name: "SessionWithProfileName",
ProfileName: "default",
ErrorExpected: false,
},
}
for _, tc := range tt {
tc := tc
t.Run(tc.Name, func(t *testing.T) {
mockSvc := MockSSMSvc{}
driver := NewSSMDriverWithMockSvc(&mockSvc)
driver.ProfileName = tc.ProfileName
if driver.SvcClient == nil {
t.Fatalf("svcclient for driver should not be nil")
}
if !tc.SkipStartSession {
_, err := driver.StartSession(context.TODO(), MockStartSessionInput("fakeinstance"))
if err != nil {
t.Fatalf("got an error when calling StartSession %v", err)
}
}
args, err := driver.Args()
if tc.ErrorExpected && err == nil {
t.Fatalf("Driver.Args with a %q should have failed but instead no error was returned", tc.Name)
}
if tc.ErrorExpected {
return
}
if err != nil {
t.Fatalf("got an error when it should've worked %v", err)
}
// validate launch script
expectedArgString := fmt.Sprintf(`{"SessionId":"packerid","StreamUrl":"http://packer.io","TokenValue":"packer-token"} east StartSession %s {"DocumentName":"AWS-StartPortForwardingSession","Parameters":{"localPortNumber":["8001"],"portNumber":["22"]},"Target":"fakeinstance"} example.com`, tc.ProfileName)
argString := strings.Join(args, " ")
if argString != expectedArgString {
t.Errorf("Expected launch script to be %q but got %q", expectedArgString, argString)
}
})
}
}
+56
View File
@@ -0,0 +1,56 @@
package common
import (
"context"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ssm"
"github.com/aws/aws-sdk-go/service/ssm/ssmiface"
)
type MockSSMSvc struct {
ssmiface.SSMAPI
StartSessionError error
TerminateSessionError error
StartSessionCalled bool
TerminateSessionCalled bool
}
func (svc *MockSSMSvc) StartSessionWithContext(ctx aws.Context, input *ssm.StartSessionInput, options ...request.Option) (*ssm.StartSessionOutput, error) {
svc.StartSessionCalled = true
return MockStartSessionOutput(), svc.StartSessionError
}
func (svc *MockSSMSvc) TerminateSession(input *ssm.TerminateSessionInput) (*ssm.TerminateSessionOutput, error) {
svc.TerminateSessionCalled = true
return new(ssm.TerminateSessionOutput), svc.TerminateSessionError
}
func MockPluginCmdFunc(ctx context.Context) error {
return nil
}
func MockStartSessionOutput() *ssm.StartSessionOutput {
id, url, token := "packerid", "http://packer.io", "packer-token"
output := ssm.StartSessionOutput{
SessionId: &id,
StreamUrl: &url,
TokenValue: &token,
}
return &output
}
func MockStartSessionInput(instance string) ssm.StartSessionInput {
params := map[string][]*string{
"portNumber": []*string{aws.String("22")},
"localPortNumber": []*string{aws.String("8001")},
}
input := ssm.StartSessionInput{
DocumentName: aws.String("AWS-StartPortForwardingSession"),
Parameters: params,
Target: aws.String(instance),
}
return input
}
+1 -1
View File
@@ -14,7 +14,7 @@ import (
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/helper/multistep"
)
// StateRefreshFunc is a function type used for StateChangeConf that is
@@ -8,9 +8,9 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
)
type StepAMIRegionCopy struct {
@@ -11,9 +11,9 @@ import (
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
)
// Define a mock struct to be used in unit tests for common aws steps.
@@ -6,8 +6,8 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
// stepCleanupVolumes cleans up any orphaned volumes that were not designated to
+45 -24
View File
@@ -3,16 +3,16 @@ package common
import (
"context"
"fmt"
"strconv"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ssm"
pssm "github.com/hashicorp/packer/builder/amazon/common/ssm"
"github.com/hashicorp/packer/common/net"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/net"
)
type StepCreateSSMTunnel struct {
@@ -21,8 +21,9 @@ type StepCreateSSMTunnel struct {
LocalPortNumber int
RemotePortNumber int
SSMAgentEnabled bool
instanceId string
PauseBeforeSSM time.Duration
stopSSMCommand func()
driver *SSMDriver
}
// Run executes the Packer build step that creates a session tunnel.
@@ -35,7 +36,7 @@ func (s *StepCreateSSMTunnel) Run(ctx context.Context, state multistep.StateBag)
// Wait for the remote port to become available
if s.PauseBeforeSSM > 0 {
ui.Say(fmt.Sprintf("Waiting %s before establishing the SSM session...", s.PauseBeforeSSM))
ui.Say(fmt.Sprintf("Waiting %s for establishing the SSM session...", s.PauseBeforeSSM))
select {
case <-time.After(s.PauseBeforeSSM):
break
@@ -60,38 +61,42 @@ func (s *StepCreateSSMTunnel) Run(ctx context.Context, state multistep.StateBag)
state.Put("error", err)
return multistep.ActionHalt
}
s.instanceId = aws.StringValue(instance.InstanceId)
state.Put("sessionPort", s.LocalPortNumber)
ssmCtx, ssmCancel := context.WithCancel(ctx)
s.stopSSMCommand = ssmCancel
go func() {
if s.driver == nil {
ssmconn := ssm.New(s.AWSSession)
err := pssm.Session{
SvcClient: ssmconn,
InstanceID: aws.StringValue(instance.InstanceId),
RemotePort: s.RemotePortNumber,
LocalPort: s.LocalPortNumber,
Region: s.Region,
}.Start(ssmCtx, ui)
if err != nil {
ui.Error(fmt.Sprintf("ssm error: %s", err))
cfg := SSMDriverConfig{
SvcClient: ssmconn,
Region: s.Region,
SvcEndpoint: ssmconn.Endpoint,
}
}()
driver := SSMDriver{SSMDriverConfig: cfg}
s.driver = &driver
}
input := s.BuildTunnelInputForInstance(s.instanceId)
_, err := s.driver.StartSession(ctx, input)
if err != nil {
err = fmt.Errorf("error encountered in establishing a tunnel %s", err)
ui.Error(err.Error())
state.Put("error", err)
return multistep.ActionHalt
}
ui.Message(fmt.Sprintf("PortForwarding session %q has been started", s.instanceId))
state.Put("sessionPort", s.LocalPortNumber)
return multistep.ActionContinue
}
// Cleanup terminates an active session on AWS, which in turn terminates the associated tunnel process running on the local machine.
func (s *StepCreateSSMTunnel) Cleanup(state multistep.StateBag) {
ui := state.Get("ui").(packer.Ui)
if !s.SSMAgentEnabled {
return
}
if s.stopSSMCommand != nil {
s.stopSSMCommand()
if err := s.driver.StopSession(); err != nil {
ui.Error(err.Error())
}
}
@@ -124,3 +129,19 @@ func (s *StepCreateSSMTunnel) ConfigureLocalHostPort(ctx context.Context) error
return nil
}
func (s *StepCreateSSMTunnel) BuildTunnelInputForInstance(instance string) ssm.StartSessionInput {
dst, src := strconv.Itoa(s.RemotePortNumber), strconv.Itoa(s.LocalPortNumber)
params := map[string][]*string{
"portNumber": []*string{aws.String(dst)},
"localPortNumber": []*string{aws.String(src)},
}
input := ssm.StartSessionInput{
DocumentName: aws.String("AWS-StartPortForwardingSession"),
Parameters: params,
Target: aws.String(instance),
}
return input
}
@@ -0,0 +1,139 @@
package common
import (
"context"
"reflect"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/packer"
)
func TestStepCreateSSMTunnel_Run(t *testing.T) {
mockSvc := MockSSMSvc{}
config := SSMDriverConfig{
SvcClient: &mockSvc,
SvcEndpoint: "example.com",
}
mockDriver := NewSSMDriver(config)
mockDriver.pluginCmdFunc = MockPluginCmdFunc
state := testState()
state.Put("ui", &packer.NoopUi{})
state.Put("instance", &ec2.Instance{InstanceId: aws.String("i-something")})
step := StepCreateSSMTunnel{
driver: mockDriver,
}
step.Run(context.Background(), state)
err := state.Get("error")
if err != nil {
err = err.(error)
t.Fatalf("the call to Run failed with an error when it should've executed: %v", err)
}
if mockSvc.StartSessionCalled {
t.Errorf("StartSession should not be called when SSMAgentEnabled is false")
}
// Run when SSMAgentEnabled is true
step.SSMAgentEnabled = true
step.Run(context.Background(), state)
err = state.Get("error")
if err != nil {
err = err.(error)
t.Fatalf("the call to Run failed with an error when it should've executed: %v", err)
}
if !mockSvc.StartSessionCalled {
t.Errorf("calling run with the correct inputs should call StartSession")
}
step.Cleanup(state)
if !mockSvc.TerminateSessionCalled {
t.Errorf("calling cleanup on a successful run should call TerminateSession")
}
}
func TestStepCreateSSMTunnel_Cleanup(t *testing.T) {
mockSvc := MockSSMSvc{}
config := SSMDriverConfig{
SvcClient: &mockSvc,
SvcEndpoint: "example.com",
}
mockDriver := NewSSMDriver(config)
mockDriver.pluginCmdFunc = MockPluginCmdFunc
step := StepCreateSSMTunnel{
SSMAgentEnabled: true,
driver: mockDriver,
}
state := testState()
state.Put("ui", &packer.NoopUi{})
state.Put("instance", &ec2.Instance{InstanceId: aws.String("i-something")})
step.Cleanup(state)
if mockSvc.TerminateSessionCalled {
t.Fatalf("calling cleanup on a non started session should not call TerminateSession")
}
}
func TestStepCreateSSMTunnel_BuildTunnelInputForInstance(t *testing.T) {
step := StepCreateSSMTunnel{
Region: "region",
LocalPortNumber: 8001,
RemotePortNumber: 22,
SSMAgentEnabled: true,
}
input := step.BuildTunnelInputForInstance("i-something")
target := aws.StringValue(input.Target)
if target != "i-something" {
t.Errorf("input should contain instance id as target but it got %q", target)
}
params := map[string][]*string{
"portNumber": []*string{aws.String("22")},
"localPortNumber": []*string{aws.String("8001")},
}
if !reflect.DeepEqual(input.Parameters, params) {
t.Errorf("input should contain the expected port parameters but it got %v", input.Parameters)
}
}
func TestStepCreateSSMTunnel_ConfigureLocalHostPort(t *testing.T) {
tt := []struct {
Name string
Step StepCreateSSMTunnel
PortCheck func(int) bool
}{
{"WithLocalPortNumber", StepCreateSSMTunnel{LocalPortNumber: 9001}, func(port int) bool { return port == 9001 }},
{"WithNoLocalPortNumber", StepCreateSSMTunnel{}, func(port int) bool { return port >= 8000 && port <= 9000 }},
}
for _, tc := range tt {
tc := tc
t.Run(tc.Name, func(t *testing.T) {
step := tc.Step
if err := step.ConfigureLocalHostPort(context.TODO()); err != nil {
t.Errorf("failed to configure a port on localhost")
}
if !tc.PortCheck(step.LocalPortNumber) {
t.Errorf("failed to configure a port on localhost")
}
})
}
}
+4 -5
View File
@@ -8,11 +8,10 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/builder/amazon/common/awserrors"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/retry"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
type StepCreateTags struct {
@@ -92,7 +91,7 @@ func (s *StepCreateTags) Run(ctx context.Context, state multistep.StateBag) mult
// Retry creating tags for about 2.5 minutes
err = retry.Config{Tries: 11, ShouldRetry: func(error) bool {
if awserrors.Matches(err, "InvalidAMIID.NotFound", "") || awserrors.Matches(err, "InvalidSnapshot.NotFound", "") {
if IsAWSErr(err, "InvalidAMIID.NotFound", "") || IsAWSErr(err, "InvalidSnapshot.NotFound", "") {
return true
}
return false
+1 -1
View File
@@ -6,8 +6,8 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
type StepDeregisterAMI struct {
+2 -2
View File
@@ -12,10 +12,10 @@ import (
"time"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/retry"
)
// StepGetPassword reads the password from a Windows server and sets it
@@ -8,9 +8,9 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/uuid"
)
type StepIamInstanceProfile struct {
+2 -2
View File
@@ -8,10 +8,10 @@ import (
"time"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/retry"
)
type StepKeyPair struct {
@@ -7,10 +7,10 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/builder"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/packerbuilderdata"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
type StepModifyAMIAttributes struct {
@@ -22,7 +22,7 @@ type StepModifyAMIAttributes struct {
Description string
Ctx interpolate.Context
GeneratedData *packerbuilderdata.GeneratedData
GeneratedData *builder.GeneratedData
}
func (s *StepModifyAMIAttributes) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
@@ -7,9 +7,9 @@ import (
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
confighelper "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
confighelper "github.com/hashicorp/packer/packer-plugin-sdk/template/config"
)
type StepModifyEBSBackedInstance struct {
+1 -1
View File
@@ -8,8 +8,8 @@ import (
"sort"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
// StepNetworkInfo queries AWS for information about
+4 -5
View File
@@ -9,10 +9,9 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/hashicorp/packer/builder/amazon/common/awserrors"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/retry"
)
// StepPreValidate provides an opportunity to pre-validate any configuration for
@@ -40,7 +39,7 @@ func (s *StepPreValidate) Run(ctx context.Context, state multistep.StateBag) mul
err := retry.Config{
Tries: 11,
ShouldRetry: func(err error) bool {
if awserrors.Matches(err, "AuthFailure", "") {
if IsAWSErr(err, "AuthFailure", "") {
log.Printf("Waiting for Vault-generated AWS credentials" +
" to pass authentication... trying again.")
return true
@@ -132,7 +131,7 @@ func (s *StepPreValidate) checkVpc(conn ec2iface.EC2API) error {
}
res, err := conn.DescribeVpcs(&ec2.DescribeVpcsInput{VpcIds: []*string{aws.String(s.VpcId)}})
if awserrors.Matches(err, "InvalidVpcID.NotFound", "") || err != nil {
if IsAWSErr(err, "InvalidVpcID.NotFound", "") || err != nil {
return fmt.Errorf("Error retrieving VPC information for vpc_id %s: %s", s.VpcId, err)
}
@@ -11,12 +11,11 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/builder/amazon/common/awserrors"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/retry"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
type StepRunSourceInstance struct {
@@ -34,7 +33,6 @@ type StepRunSourceInstance struct {
IsRestricted bool
SourceAMI string
Tags map[string]string
Tenancy string
UserData string
UserDataFile string
VolumeTags map[string]string
@@ -197,15 +195,11 @@ func (s *StepRunSourceInstance) Run(ctx context.Context, state multistep.StateBa
runOpts.InstanceInitiatedShutdownBehavior = &s.InstanceInitiatedShutdownBehavior
}
if s.Tenancy != "" {
runOpts.Placement.Tenancy = aws.String(s.Tenancy)
}
var runResp *ec2.Reservation
err = retry.Config{
Tries: 11,
ShouldRetry: func(err error) bool {
if awserrors.Matches(err, "InvalidParameterValue", "iamInstanceProfile") {
if IsAWSErr(err, "InvalidParameterValue", "iamInstanceProfile") {
return true
}
return false
@@ -216,7 +210,7 @@ func (s *StepRunSourceInstance) Run(ctx context.Context, state multistep.StateBa
return err
})
if awserrors.Matches(err, "VPCIdNotSpecified", "No default VPC for this user") && subnetId == "" {
if IsAWSErr(err, "VPCIdNotSpecified", "No default VPC for this user") && subnetId == "" {
err := fmt.Errorf("Error launching source instance: a valid Subnet Id was not specified")
state.Put("error", err)
ui.Error(err.Error())
@@ -254,7 +248,7 @@ func (s *StepRunSourceInstance) Run(ctx context.Context, state multistep.StateBa
var r *ec2.DescribeInstancesOutput
err = retry.Config{Tries: 11, ShouldRetry: func(err error) bool {
if awserrors.Matches(err, "InvalidInstanceID.NotFound", "") {
if IsAWSErr(err, "InvalidInstanceID.NotFound", "") {
return true
}
return false
@@ -299,7 +293,7 @@ func (s *StepRunSourceInstance) Run(ctx context.Context, state multistep.StateBa
ec2Tags.Report(ui)
// Retry creating tags for about 2.5 minutes
err = retry.Config{Tries: 11, ShouldRetry: func(error) bool {
if awserrors.Matches(err, "InvalidInstanceID.NotFound", "") {
if IsAWSErr(err, "InvalidInstanceID.NotFound", "") {
return true
}
return false
+16 -27
View File
@@ -11,14 +11,12 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/hashicorp/packer/builder/amazon/common/awserrors"
"github.com/hashicorp/packer/common/random"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/random"
"github.com/hashicorp/packer/packer-plugin-sdk/retry"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
type EC2BlockDeviceMappingsBuilder interface {
@@ -36,7 +34,6 @@ type StepRunSpotInstance struct {
ExpectedRootDevice string
InstanceInitiatedShutdownBehavior string
InstanceType string
Region string
SourceAMI string
SpotPrice string
SpotTags map[string]string
@@ -160,7 +157,7 @@ func (s *StepRunSpotInstance) LoadUserData() (string, error) {
}
func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(ec2iface.EC2API)
ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui)
ui.Say("Launching a spot AWS instance...")
@@ -199,7 +196,7 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag)
}
// Convert tags from the tag map provided by the user into *ec2.Tag s
ec2Tags, err := TagMap(s.Tags).EC2Tags(s.Ctx, s.Region, state)
ec2Tags, err := TagMap(s.Tags).EC2Tags(s.Ctx, *ec2conn.Config.Region, state)
if err != nil {
err := fmt.Errorf("Error generating tags for source instance: %s", err)
state.Put("error", err)
@@ -223,14 +220,6 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag)
}
marketOptions.SetMarketType(ec2.MarketTypeSpot)
spotTags, err := TagMap(s.SpotTags).EC2Tags(s.Ctx, s.Region, state)
if err != nil {
err := fmt.Errorf("Error generating tags for spot request: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Create a launch template for the instance
ui.Message("Loading User Data File...")
@@ -253,14 +242,6 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag)
LaunchTemplateName: aws.String(launchTemplateName),
VersionDescription: aws.String("template generated by packer for launching spot instances"),
}
if len(spotTags) > 0 {
launchTemplate.TagSpecifications = []*ec2.TagSpecification{
{
ResourceType: aws.String("launch-template"),
Tags: spotTags,
},
}
}
// Tell EC2 to create the template
_, err = ec2conn.CreateLaunchTemplate(launchTemplate)
@@ -379,6 +360,14 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag)
instance := describeOutput.Reservations[0].Instances[0]
// Tag the spot instance request (not the eventual spot instance)
spotTags, err := TagMap(s.SpotTags).EC2Tags(s.Ctx, *ec2conn.Config.Region, state)
if err != nil {
err := fmt.Errorf("Error generating tags for spot request: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
if len(spotTags) > 0 && len(s.SpotTags) > 0 {
spotTags.Report(ui)
// Use the instance ID to find out the SIR, so that we can tag the spot
@@ -407,7 +396,7 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag)
// Retry creating tags for about 2.5 minutes
err = retry.Config{Tries: 11, ShouldRetry: func(error) bool {
if awserrors.Matches(err, "InvalidInstanceID.NotFound", "") {
if IsAWSErr(err, "InvalidInstanceID.NotFound", "") {
return true
}
return false
@@ -438,7 +427,7 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag)
if len(volumeIds) > 0 && len(s.VolumeTags) > 0 {
ui.Say("Adding tags to source EBS Volumes")
volumeTags, err := TagMap(s.VolumeTags).EC2Tags(s.Ctx, s.Region, state)
volumeTags, err := TagMap(s.VolumeTags).EC2Tags(s.Ctx, *ec2conn.Config.Region, state)
if err != nil {
err := fmt.Errorf("Error tagging source EBS Volumes on %s: %s", *instance.InstanceId, err)
state.Put("error", err)
@@ -2,16 +2,14 @@ package common
import (
"bytes"
"context"
"fmt"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
)
// Create statebag for running test
@@ -45,7 +43,6 @@ func getBasicStep() *StepRunSpotInstance {
ExpectedRootDevice: "ebs",
InstanceInitiatedShutdownBehavior: "stop",
InstanceType: "t2.micro",
Region: "us-east-1",
SourceAMI: "",
SpotPrice: "auto",
SpotTags: nil,
@@ -137,226 +134,3 @@ func TestCreateTemplateData_NoEphemeral(t *testing.T) {
// t.Fatalf("Should have created 26 mappings to keep ephemeral drives from appearing.")
// }
}
type runSpotEC2ConnMock struct {
ec2iface.EC2API
CreateLaunchTemplateParams []*ec2.CreateLaunchTemplateInput
CreateLaunchTemplateFn func(*ec2.CreateLaunchTemplateInput) (*ec2.CreateLaunchTemplateOutput, error)
CreateFleetParams []*ec2.CreateFleetInput
CreateFleetFn func(*ec2.CreateFleetInput) (*ec2.CreateFleetOutput, error)
CreateTagsParams []*ec2.CreateTagsInput
CreateTagsFn func(*ec2.CreateTagsInput) (*ec2.CreateTagsOutput, error)
DescribeInstancesParams []*ec2.DescribeInstancesInput
DescribeInstancesFn func(input *ec2.DescribeInstancesInput) (*ec2.DescribeInstancesOutput, error)
}
func (m *runSpotEC2ConnMock) CreateLaunchTemplate(req *ec2.CreateLaunchTemplateInput) (*ec2.CreateLaunchTemplateOutput, error) {
m.CreateLaunchTemplateParams = append(m.CreateLaunchTemplateParams, req)
resp, err := m.CreateLaunchTemplateFn(req)
return resp, err
}
func (m *runSpotEC2ConnMock) CreateFleet(req *ec2.CreateFleetInput) (*ec2.CreateFleetOutput, error) {
m.CreateFleetParams = append(m.CreateFleetParams, req)
if m.CreateFleetFn != nil {
resp, err := m.CreateFleetFn(req)
return resp, err
} else {
return nil, nil
}
}
func (m *runSpotEC2ConnMock) DescribeInstances(req *ec2.DescribeInstancesInput) (*ec2.DescribeInstancesOutput, error) {
m.DescribeInstancesParams = append(m.DescribeInstancesParams, req)
if m.DescribeInstancesFn != nil {
resp, err := m.DescribeInstancesFn(req)
return resp, err
} else {
return nil, nil
}
}
func (m *runSpotEC2ConnMock) CreateTags(req *ec2.CreateTagsInput) (*ec2.CreateTagsOutput, error) {
m.CreateTagsParams = append(m.CreateTagsParams, req)
if m.CreateTagsFn != nil {
resp, err := m.CreateTagsFn(req)
return resp, err
} else {
return nil, nil
}
}
func defaultEc2Mock(instanceId, spotRequestId, volumeId *string) *runSpotEC2ConnMock {
instance := &ec2.Instance{
InstanceId: instanceId,
SpotInstanceRequestId: spotRequestId,
BlockDeviceMappings: []*ec2.InstanceBlockDeviceMapping{
{
Ebs: &ec2.EbsInstanceBlockDevice{
VolumeId: volumeId,
},
},
},
}
return &runSpotEC2ConnMock{
CreateLaunchTemplateFn: func(in *ec2.CreateLaunchTemplateInput) (*ec2.CreateLaunchTemplateOutput, error) {
return &ec2.CreateLaunchTemplateOutput{
LaunchTemplate: nil,
Warning: nil,
}, nil
},
CreateFleetFn: func(*ec2.CreateFleetInput) (*ec2.CreateFleetOutput, error) {
return &ec2.CreateFleetOutput{
Errors: nil,
FleetId: nil,
Instances: []*ec2.CreateFleetInstance{
{
InstanceIds: []*string{instanceId},
},
},
}, nil
},
DescribeInstancesFn: func(input *ec2.DescribeInstancesInput) (*ec2.DescribeInstancesOutput, error) {
return &ec2.DescribeInstancesOutput{
NextToken: nil,
Reservations: []*ec2.Reservation{
{
Instances: []*ec2.Instance{instance},
},
},
}, nil
},
}
}
func TestRun(t *testing.T) {
instanceId := aws.String("test-instance-id")
spotRequestId := aws.String("spot-id")
volumeId := aws.String("volume-id")
ec2Mock := defaultEc2Mock(instanceId, spotRequestId, volumeId)
uiMock := packer.TestUi(t)
state := tStateSpot()
state.Put("ec2", ec2Mock)
state.Put("ui", uiMock)
state.Put("source_image", testImage())
stepRunSpotInstance := getBasicStep()
stepRunSpotInstance.Tags["Name"] = "Packer Builder"
stepRunSpotInstance.Tags["test-tag"] = "test-value"
stepRunSpotInstance.SpotTags = map[string]string{
"spot-tag": "spot-tag-value",
}
stepRunSpotInstance.VolumeTags = map[string]string{
"volume-tag": "volume-tag-value",
}
ctx := context.TODO()
action := stepRunSpotInstance.Run(ctx, state)
if err := state.Get("error"); err != nil {
t.Fatalf("should not error, but: %v", err)
}
if action != multistep.ActionContinue {
t.Fatalf("shoul continue, but: %v", action)
}
if len(ec2Mock.CreateLaunchTemplateParams) != 1 {
t.Fatalf("createLaunchTemplate should be invoked once, but invoked %v", len(ec2Mock.CreateLaunchTemplateParams))
}
launchTemplateName := ec2Mock.CreateLaunchTemplateParams[0].LaunchTemplateName
if len(ec2Mock.CreateLaunchTemplateParams[0].TagSpecifications) != 1 {
t.Fatalf("exactly one launch template tag specification expected")
}
if *ec2Mock.CreateLaunchTemplateParams[0].TagSpecifications[0].ResourceType != "launch-template" {
t.Fatalf("resource type 'launch-template' expected")
}
if len(ec2Mock.CreateLaunchTemplateParams[0].TagSpecifications[0].Tags) != 1 {
t.Fatalf("1 launch template tag expected")
}
nameTag := ec2Mock.CreateLaunchTemplateParams[0].TagSpecifications[0].Tags[0]
if *nameTag.Key != "spot-tag" || *nameTag.Value != "spot-tag-value" {
t.Fatalf("expected spot-tag: spot-tag-value")
}
if len(ec2Mock.CreateFleetParams) != 1 {
t.Fatalf("createFleet should be invoked once, but invoked %v", len(ec2Mock.CreateLaunchTemplateParams))
}
if *ec2Mock.CreateFleetParams[0].TargetCapacitySpecification.DefaultTargetCapacityType != "spot" {
t.Fatalf("capacity type should be spot")
}
if *ec2Mock.CreateFleetParams[0].TargetCapacitySpecification.TotalTargetCapacity != 1 {
t.Fatalf("target capacity should be 1")
}
if len(ec2Mock.CreateFleetParams[0].LaunchTemplateConfigs) != 1 {
t.Fatalf("exactly one launch config template expected")
}
if *ec2Mock.CreateFleetParams[0].LaunchTemplateConfigs[0].LaunchTemplateSpecification.LaunchTemplateName != *launchTemplateName {
t.Fatalf("launchTemplateName should match in createLaunchTemplate and createFleet requests")
}
if len(ec2Mock.DescribeInstancesParams) != 1 {
t.Fatalf("describeInstancesParams should be invoked once, but invoked %v", len(ec2Mock.DescribeInstancesParams))
}
if *ec2Mock.DescribeInstancesParams[0].InstanceIds[0] != *instanceId {
t.Fatalf("instanceId should match from createFleet response")
}
uiMock.Say(fmt.Sprintf("%v", ec2Mock.CreateTagsParams))
if len(ec2Mock.CreateTagsParams) != 3 {
t.Fatalf("createTags should be invoked 3 times")
}
if len(ec2Mock.CreateTagsParams[0].Resources) != 1 || *ec2Mock.CreateTagsParams[0].Resources[0] != *spotRequestId {
t.Fatalf("should create tags for spot request")
}
if len(ec2Mock.CreateTagsParams[1].Resources) != 1 || *ec2Mock.CreateTagsParams[1].Resources[0] != *instanceId {
t.Fatalf("should create tags for instance")
}
if len(ec2Mock.CreateTagsParams[2].Resources) != 1 || ec2Mock.CreateTagsParams[2].Resources[0] != volumeId {
t.Fatalf("should create tags for volume")
}
}
func TestRun_NoSpotTags(t *testing.T) {
instanceId := aws.String("test-instance-id")
spotRequestId := aws.String("spot-id")
volumeId := aws.String("volume-id")
ec2Mock := defaultEc2Mock(instanceId, spotRequestId, volumeId)
uiMock := packer.TestUi(t)
state := tStateSpot()
state.Put("ec2", ec2Mock)
state.Put("ui", uiMock)
state.Put("source_image", testImage())
stepRunSpotInstance := getBasicStep()
stepRunSpotInstance.Tags["Name"] = "Packer Builder"
stepRunSpotInstance.Tags["test-tag"] = "test-value"
stepRunSpotInstance.VolumeTags = map[string]string{
"volume-tag": "volume-tag-value",
}
ctx := context.TODO()
action := stepRunSpotInstance.Run(ctx, state)
if err := state.Get("error"); err != nil {
t.Fatalf("should not error, but: %v", err)
}
if action != multistep.ActionContinue {
t.Fatalf("shoul continue, but: %v", action)
}
if len(ec2Mock.CreateLaunchTemplateParams[0].TagSpecifications) != 0 {
t.Fatalf("0 launch template tags expected")
}
}
+2 -2
View File
@@ -10,10 +10,10 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/common/uuid"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/uuid"
)
type StepSecurityGroup struct {
@@ -4,8 +4,8 @@ import (
"context"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/packerbuilderdata"
"github.com/hashicorp/packer/builder"
"github.com/hashicorp/packer/helper/multistep"
)
// &awscommon.StepSetGeneratedData{
@@ -13,7 +13,7 @@ import (
// },
type StepSetGeneratedData struct {
GeneratedData *packerbuilderdata.GeneratedData
GeneratedData *builder.GeneratedData
}
func (s *StepSetGeneratedData) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
@@ -8,9 +8,9 @@ import (
"time"
"github.com/aws/aws-sdk-go/service/ec2"
confighelper "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
confighelper "github.com/hashicorp/packer/packer-plugin-sdk/template/config"
)
// StepSourceAMIInfo extracts critical information from the source AMI
@@ -6,10 +6,9 @@ import (
"time"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/builder/amazon/common/awserrors"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/retry"
)
type StepStopEBSBackedInstance struct {
@@ -43,7 +42,7 @@ func (s *StepStopEBSBackedInstance) Run(ctx context.Context, state multistep.Sta
// Work around this by retrying a few times, up to about 5 minutes.
err := retry.Config{Tries: 6, ShouldRetry: func(error) bool {
if awserrors.Matches(err, "InvalidInstanceID.NotFound", "") {
if IsAWSErr(err, "InvalidInstanceID.NotFound", "") {
return true
}
return false
+4 -4
View File
@@ -5,10 +5,10 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/hashicorp/packer/builder"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/packerbuilderdata"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
type TagMap map[string]string
@@ -23,7 +23,7 @@ func (t EC2Tags) Report(ui packer.Ui) {
func (t TagMap) EC2Tags(ictx interpolate.Context, region string, state multistep.StateBag) (EC2Tags, error) {
var ec2Tags []*ec2.Tag
generatedData := packerbuilderdata.GeneratedData{State: state}
generatedData := builder.GeneratedData{State: state}
ictx.Data = extractBuildInfo(region, state, &generatedData)
for key, value := range t {
+9 -18
View File
@@ -15,16 +15,15 @@ import (
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer/builder"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/hcl2template"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/common"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep/commonsteps"
"github.com/hashicorp/packer/packer-plugin-sdk/packerbuilderdata"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
// The unique ID for this builder
@@ -86,22 +85,16 @@ func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstruct
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
b.config.ctx.Funcs = awscommon.TemplateFuncs
err := config.Decode(&b.config, &config.DecodeOpts{
PluginType: BuilderId,
Interpolate: true,
InterpolateContext: &b.config.ctx,
InterpolateFilter: &interpolate.RenderFilter{
Exclude: []string{
"ami_description",
"run_tags",
"run_tag",
"run_volume_tags",
"run_volume_tag",
"spot_tags",
"spot_tag",
"snapshot_tags",
"snapshot_tag",
"tags",
"tag",
},
},
}, raws...)
@@ -170,7 +163,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
state.Put("awsSession", session)
state.Put("hook", hook)
state.Put("ui", ui)
generatedData := &packerbuilderdata.GeneratedData{State: state}
generatedData := &builder.GeneratedData{State: state}
var instanceStep multistep.Step
@@ -187,7 +180,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
ExpectedRootDevice: "ebs",
InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior,
InstanceType: b.config.InstanceType,
Region: *ec2conn.Config.Region,
SourceAMI: b.config.SourceAmi,
SpotPrice: b.config.SpotPrice,
SpotTags: b.config.SpotTags,
@@ -214,7 +206,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
IsRestricted: b.config.IsChinaCloud() || b.config.IsGovCloud(),
SourceAMI: b.config.SourceAmi,
Tags: b.config.RunTags,
Tenancy: b.config.Tenancy,
UserData: b.config.UserData,
UserDataFile: b.config.UserDataFile,
VolumeTags: b.config.VolumeRunTags,
@@ -299,8 +290,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&awscommon.StepSetGeneratedData{
GeneratedData: generatedData,
},
&commonsteps.StepProvision{},
&commonsteps.StepCleanupTempKeys{
&common.StepProvision{},
&common.StepCleanupTempKeys{
Comm: &b.config.RunConfig.Comm,
},
&awscommon.StepStopEBSBackedInstance{
@@ -351,7 +342,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
}
// Run!
b.runner = commonsteps.NewRunner(steps, b.config.PackerConfig, ui)
b.runner = common.NewRunner(steps, b.config.PackerConfig, ui)
b.runner.Run(ctx, state)
// If there was an error, return that
if rawErr, ok := state.GetOk("error"); ok {
-10
View File
@@ -13,7 +13,6 @@ import (
type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
@@ -32,7 +31,6 @@ type FlatConfig struct {
SecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key" hcl:"secret_key"`
SkipValidation *bool `mapstructure:"skip_region_validation" required:"false" cty:"skip_region_validation" hcl:"skip_region_validation"`
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check" hcl:"skip_metadata_api_check"`
SkipCredsValidation *bool `mapstructure:"skip_credential_validation" cty:"skip_credential_validation" hcl:"skip_credential_validation"`
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"`
@@ -82,7 +80,6 @@ type FlatConfig struct {
SpotTag []hcl2template.FlatKeyValue `mapstructure:"spot_tag" required:"false" cty:"spot_tag" hcl:"spot_tag"`
SubnetFilter *common.FlatSubnetFilterOptions `mapstructure:"subnet_filter" required:"false" cty:"subnet_filter" hcl:"subnet_filter"`
SubnetId *string `mapstructure:"subnet_id" required:"false" cty:"subnet_id" hcl:"subnet_id"`
Tenancy *string `mapstructure:"tenancy" required:"false" cty:"tenancy" hcl:"tenancy"`
TemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" required:"false" cty:"temporary_key_pair_name" hcl:"temporary_key_pair_name"`
TemporarySGSourceCidrs []string `mapstructure:"temporary_security_group_source_cidrs" required:"false" cty:"temporary_security_group_source_cidrs" hcl:"temporary_security_group_source_cidrs"`
UserData *string `mapstructure:"user_data" required:"false" cty:"user_data" hcl:"user_data"`
@@ -97,8 +94,6 @@ type FlatConfig struct {
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username" hcl:"ssh_username"`
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password" hcl:"ssh_password"`
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" undocumented:"true" cty:"ssh_keypair_name" hcl:"ssh_keypair_name"`
SSHTemporaryKeyPairType *string `mapstructure:"temporary_key_pair_type" cty:"temporary_key_pair_type" hcl:"temporary_key_pair_type"`
SSHTemporaryKeyPairBits *int `mapstructure:"temporary_key_pair_bits" cty:"temporary_key_pair_bits" hcl:"temporary_key_pair_bits"`
SSHCiphers []string `mapstructure:"ssh_ciphers" cty:"ssh_ciphers" hcl:"ssh_ciphers"`
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys" hcl:"ssh_clear_authorized_keys"`
SSHKEXAlgos []string `mapstructure:"ssh_key_exchange_algorithms" cty:"ssh_key_exchange_algorithms" hcl:"ssh_key_exchange_algorithms"`
@@ -162,7 +157,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
"packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false},
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
@@ -181,7 +175,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false},
"skip_region_validation": &hcldec.AttrSpec{Name: "skip_region_validation", Type: cty.Bool, Required: false},
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
"skip_credential_validation": &hcldec.AttrSpec{Name: "skip_credential_validation", 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())},
@@ -231,7 +224,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"spot_tag": &hcldec.BlockListSpec{TypeName: "spot_tag", Nested: hcldec.ObjectSpec((*hcl2template.FlatKeyValue)(nil).HCL2Spec())},
"subnet_filter": &hcldec.BlockSpec{TypeName: "subnet_filter", Nested: hcldec.ObjectSpec((*common.FlatSubnetFilterOptions)(nil).HCL2Spec())},
"subnet_id": &hcldec.AttrSpec{Name: "subnet_id", Type: cty.String, Required: false},
"tenancy": &hcldec.AttrSpec{Name: "tenancy", Type: cty.String, Required: false},
"temporary_key_pair_name": &hcldec.AttrSpec{Name: "temporary_key_pair_name", Type: cty.String, Required: false},
"temporary_security_group_source_cidrs": &hcldec.AttrSpec{Name: "temporary_security_group_source_cidrs", Type: cty.List(cty.String), Required: false},
"user_data": &hcldec.AttrSpec{Name: "user_data", Type: cty.String, Required: false},
@@ -246,8 +238,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"ssh_username": &hcldec.AttrSpec{Name: "ssh_username", Type: cty.String, Required: false},
"ssh_password": &hcldec.AttrSpec{Name: "ssh_password", Type: cty.String, Required: false},
"ssh_keypair_name": &hcldec.AttrSpec{Name: "ssh_keypair_name", Type: cty.String, Required: false},
"temporary_key_pair_type": &hcldec.AttrSpec{Name: "temporary_key_pair_type", Type: cty.String, Required: false},
"temporary_key_pair_bits": &hcldec.AttrSpec{Name: "temporary_key_pair_bits", Type: cty.Number, Required: false},
"ssh_ciphers": &hcldec.AttrSpec{Name: "ssh_ciphers", Type: cty.List(cty.String), Required: false},
"ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false},
"ssh_key_exchange_algorithms": &hcldec.AttrSpec{Name: "ssh_key_exchange_algorithms", Type: cty.List(cty.String), Required: false},
-33
View File
@@ -246,14 +246,6 @@ func checkBootEncrypted() builderT.TestCheckFunc {
}
}
func TestBuilderAcc_SessionManagerInterface(t *testing.T) {
builderT.Test(t, builderT.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Builder: &Builder{},
Template: testBuilderAccSessionManagerInterface,
})
}
func testAccPreCheck(t *testing.T) {
}
@@ -358,31 +350,6 @@ const testBuilderAccEncrypted = `
}
`
const testBuilderAccSessionManagerInterface = `
{
"builders": [{
"type": "test",
"region": "us-east-1",
"instance_type": "m3.medium",
"source_ami_filter": {
"filters": {
"virtualization-type": "hvm",
"name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
"root-device-type": "ebs"
},
"owners": [
"099720109477"
],
"most_recent": true
},
"ssh_username": "ubuntu",
"ssh_interface": "session_manager",
"iam_instance_profile": "SSMInstanceProfile",
"ami_name": "packer-ssm-test-{{timestamp}}"
}]
}
`
func buildForceDeregisterConfig(val, name string) string {
return fmt.Sprintf(testBuilderAccForceDeregister, val, name)
}
+4 -5
View File
@@ -9,11 +9,10 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/builder/amazon/common/awserrors"
"github.com/hashicorp/packer/common/random"
"github.com/hashicorp/packer/common/retry"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/random"
"github.com/hashicorp/packer/packer-plugin-sdk/retry"
)
type stepCreateAMI struct {
@@ -62,7 +61,7 @@ func (s *stepCreateAMI) Run(ctx context.Context, state multistep.StateBag) multi
err = retry.Config{
Tries: 0,
ShouldRetry: func(err error) bool {
if awserrors.Matches(err, "InvalidParameterValue", "Instance is not in state") {
if awscommon.IsAWSErr(err, "InvalidParameterValue", "Instance is not in state") {
return true
}
return false
+1 -1
View File
@@ -5,7 +5,7 @@ package ebssurrogate
import (
"github.com/aws/aws-sdk-go/service/ec2"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
type BlockDevice struct {
+9 -20
View File
@@ -13,16 +13,15 @@ import (
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/hashicorp/packer/builder"
awscommon "github.com/hashicorp/packer/builder/amazon/common"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/hcl2template"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/packer-plugin-sdk/common"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep"
"github.com/hashicorp/packer/packer-plugin-sdk/multistep/commonsteps"
"github.com/hashicorp/packer/packer-plugin-sdk/packerbuilderdata"
"github.com/hashicorp/packer/packer-plugin-sdk/template/config"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
const BuilderId = "mitchellh.amazon.ebssurrogate"
@@ -85,22 +84,16 @@ func (b *Builder) ConfigSpec() hcldec.ObjectSpec { return b.config.FlatMapstruct
func (b *Builder) Prepare(raws ...interface{}) ([]string, []string, error) {
b.config.ctx.Funcs = awscommon.TemplateFuncs
err := config.Decode(&b.config, &config.DecodeOpts{
PluginType: BuilderId,
Interpolate: true,
InterpolateContext: &b.config.ctx,
InterpolateFilter: &interpolate.RenderFilter{
Exclude: []string{
"ami_description",
"run_tags",
"run_tag",
"run_volume_tags",
"run_volume_tag",
"snapshot_tags",
"snapshot_tag",
"spot_tags",
"spot_tag",
"tags",
"tag",
},
},
}, raws...)
@@ -193,7 +186,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
state.Put("awsSession", session)
state.Put("hook", hook)
state.Put("ui", ui)
generatedData := &packerbuilderdata.GeneratedData{State: state}
generatedData := &builder.GeneratedData{State: state}
var instanceStep multistep.Step
@@ -210,7 +203,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
ExpectedRootDevice: "ebs",
InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior,
InstanceType: b.config.InstanceType,
Region: *ec2conn.Config.Region,
SourceAMI: b.config.SourceAmi,
SpotPrice: b.config.SpotPrice,
SpotInstanceTypes: b.config.SpotInstanceTypes,
@@ -236,7 +228,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
IsRestricted: b.config.IsChinaCloud() || b.config.IsGovCloud(),
SourceAMI: b.config.SourceAmi,
Tags: b.config.RunTags,
Tenancy: b.config.Tenancy,
UserData: b.config.UserData,
UserDataFile: b.config.UserDataFile,
VolumeTags: b.config.VolumeRunTags,
@@ -323,8 +314,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
&awscommon.StepSetGeneratedData{
GeneratedData: generatedData,
},
&commonsteps.StepProvision{},
&commonsteps.StepCleanupTempKeys{
&common.StepProvision{},
&common.StepCleanupTempKeys{
Comm: &b.config.RunConfig.Comm,
},
&awscommon.StepStopEBSBackedInstance{
@@ -341,8 +332,6 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
PollingConfig: b.config.PollingConfig,
LaunchDevices: launchDevices,
SnapshotOmitMap: b.config.LaunchMappings.GetOmissions(),
SnapshotTags: b.config.SnapshotTags,
Ctx: b.config.ctx,
},
&awscommon.StepDeregisterAMI{
AccessConfig: &b.config.AccessConfig,
@@ -390,7 +379,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
}
// Run!
b.runner = commonsteps.NewRunner(steps, b.config.PackerConfig, ui)
b.runner = common.NewRunner(steps, b.config.PackerConfig, ui)
b.runner.Run(ctx, state)
// If there was an error, return that
@@ -56,7 +56,6 @@ func (*FlatBlockDevice) HCL2Spec() map[string]hcldec.Spec {
type FlatConfig struct {
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"`
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
@@ -75,7 +74,6 @@ type FlatConfig struct {
SecretKey *string `mapstructure:"secret_key" required:"true" cty:"secret_key" hcl:"secret_key"`
SkipValidation *bool `mapstructure:"skip_region_validation" required:"false" cty:"skip_region_validation" hcl:"skip_region_validation"`
SkipMetadataApiCheck *bool `mapstructure:"skip_metadata_api_check" cty:"skip_metadata_api_check" hcl:"skip_metadata_api_check"`
SkipCredsValidation *bool `mapstructure:"skip_credential_validation" cty:"skip_credential_validation" hcl:"skip_credential_validation"`
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"`
@@ -104,7 +102,6 @@ type FlatConfig struct {
SpotTag []hcl2template.FlatKeyValue `mapstructure:"spot_tag" required:"false" cty:"spot_tag" hcl:"spot_tag"`
SubnetFilter *common.FlatSubnetFilterOptions `mapstructure:"subnet_filter" required:"false" cty:"subnet_filter" hcl:"subnet_filter"`
SubnetId *string `mapstructure:"subnet_id" required:"false" cty:"subnet_id" hcl:"subnet_id"`
Tenancy *string `mapstructure:"tenancy" required:"false" cty:"tenancy" hcl:"tenancy"`
TemporaryKeyPairName *string `mapstructure:"temporary_key_pair_name" required:"false" cty:"temporary_key_pair_name" hcl:"temporary_key_pair_name"`
TemporarySGSourceCidrs []string `mapstructure:"temporary_security_group_source_cidrs" required:"false" cty:"temporary_security_group_source_cidrs" hcl:"temporary_security_group_source_cidrs"`
UserData *string `mapstructure:"user_data" required:"false" cty:"user_data" hcl:"user_data"`
@@ -119,8 +116,6 @@ type FlatConfig struct {
SSHUsername *string `mapstructure:"ssh_username" cty:"ssh_username" hcl:"ssh_username"`
SSHPassword *string `mapstructure:"ssh_password" cty:"ssh_password" hcl:"ssh_password"`
SSHKeyPairName *string `mapstructure:"ssh_keypair_name" undocumented:"true" cty:"ssh_keypair_name" hcl:"ssh_keypair_name"`
SSHTemporaryKeyPairType *string `mapstructure:"temporary_key_pair_type" cty:"temporary_key_pair_type" hcl:"temporary_key_pair_type"`
SSHTemporaryKeyPairBits *int `mapstructure:"temporary_key_pair_bits" cty:"temporary_key_pair_bits" hcl:"temporary_key_pair_bits"`
SSHCiphers []string `mapstructure:"ssh_ciphers" cty:"ssh_ciphers" hcl:"ssh_ciphers"`
SSHClearAuthorizedKeys *bool `mapstructure:"ssh_clear_authorized_keys" cty:"ssh_clear_authorized_keys" hcl:"ssh_clear_authorized_keys"`
SSHKEXAlgos []string `mapstructure:"ssh_key_exchange_algorithms" cty:"ssh_key_exchange_algorithms" hcl:"ssh_key_exchange_algorithms"`
@@ -206,7 +201,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
s := map[string]hcldec.Spec{
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
"packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false},
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
@@ -225,7 +219,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"secret_key": &hcldec.AttrSpec{Name: "secret_key", Type: cty.String, Required: false},
"skip_region_validation": &hcldec.AttrSpec{Name: "skip_region_validation", Type: cty.Bool, Required: false},
"skip_metadata_api_check": &hcldec.AttrSpec{Name: "skip_metadata_api_check", Type: cty.Bool, Required: false},
"skip_credential_validation": &hcldec.AttrSpec{Name: "skip_credential_validation", 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())},
@@ -254,7 +247,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"spot_tag": &hcldec.BlockListSpec{TypeName: "spot_tag", Nested: hcldec.ObjectSpec((*hcl2template.FlatKeyValue)(nil).HCL2Spec())},
"subnet_filter": &hcldec.BlockSpec{TypeName: "subnet_filter", Nested: hcldec.ObjectSpec((*common.FlatSubnetFilterOptions)(nil).HCL2Spec())},
"subnet_id": &hcldec.AttrSpec{Name: "subnet_id", Type: cty.String, Required: false},
"tenancy": &hcldec.AttrSpec{Name: "tenancy", Type: cty.String, Required: false},
"temporary_key_pair_name": &hcldec.AttrSpec{Name: "temporary_key_pair_name", Type: cty.String, Required: false},
"temporary_security_group_source_cidrs": &hcldec.AttrSpec{Name: "temporary_security_group_source_cidrs", Type: cty.List(cty.String), Required: false},
"user_data": &hcldec.AttrSpec{Name: "user_data", Type: cty.String, Required: false},
@@ -269,8 +261,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
"ssh_username": &hcldec.AttrSpec{Name: "ssh_username", Type: cty.String, Required: false},
"ssh_password": &hcldec.AttrSpec{Name: "ssh_password", Type: cty.String, Required: false},
"ssh_keypair_name": &hcldec.AttrSpec{Name: "ssh_keypair_name", Type: cty.String, Required: false},
"temporary_key_pair_type": &hcldec.AttrSpec{Name: "temporary_key_pair_type", Type: cty.String, Required: false},
"temporary_key_pair_bits": &hcldec.AttrSpec{Name: "temporary_key_pair_bits", Type: cty.Number, Required: false},
"ssh_ciphers": &hcldec.AttrSpec{Name: "ssh_ciphers", Type: cty.List(cty.String), Required: false},
"ssh_clear_authorized_keys": &hcldec.AttrSpec{Name: "ssh_clear_authorized_keys", Type: cty.Bool, Required: false},
"ssh_key_exchange_algorithms": &hcldec.AttrSpec{Name: "ssh_key_exchange_algorithms", Type: cty.List(cty.String), Required: false},
@@ -5,7 +5,7 @@ package ebssurrogate
import (
"errors"
"github.com/hashicorp/packer/packer-plugin-sdk/template/interpolate"
"github.com/hashicorp/packer/template/interpolate"
)
type RootBlockDevice struct {

Some files were not shown because too many files have changed in this diff Show More