Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| acb194c4a6 | |||
| ffbb110167 | |||
| 9afaa5a21f | |||
| f5006d0842 | |||
| 88c516b2d5 | |||
| d7bb60ea86 | |||
| 08e67f8990 | |||
| 8c3b3ca00f | |||
| 4a686ef66d | |||
| f616955ebc | |||
| a1b2e71005 | |||
| d53488db68 | |||
| b6cfe16444 | |||
| 4c02123142 | |||
| 13320650f0 | |||
| 2324f433f7 | |||
| ece5e94c3d | |||
| ad239bd2b9 | |||
| 39d550054d | |||
| ef4d35097b | |||
| a63ad19b0c | |||
| ca123721a6 | |||
| 540effbbc0 |
@@ -1,5 +1,5 @@
|
||||
//go:generate struct-markdown
|
||||
//go:generate mapstructure-to-hcl2 -type AmiFilterOptions,SecurityGroupFilterOptions,SubnetFilterOptions,VpcFilterOptions,PolicyDocument,Statement
|
||||
//go:generate mapstructure-to-hcl2 -type AmiFilterOptions,SecurityGroupFilterOptions,SubnetFilterOptions,VpcFilterOptions,PolicyDocument,Statement,MetadataOptions
|
||||
|
||||
package common
|
||||
|
||||
@@ -44,6 +44,20 @@ type SecurityGroupFilterOptions struct {
|
||||
config.NameValueFilter `mapstructure:",squash"`
|
||||
}
|
||||
|
||||
// Configures the metadata options.
|
||||
// See [Configure IMDS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html) for details.
|
||||
type MetadataOptions struct {
|
||||
// A string to enable or disble the IMDS endpoint for an instance. Defaults to enabled.
|
||||
// Accepts either "enabled" or "disabled"
|
||||
HttpEndpoint string `mapstructure:"http_endpoint" required:"false"`
|
||||
// A string to either set the use of IMDSv2 for the instance to optional or required. Defaults to "optional".
|
||||
// Accepts either "optional" or "required"
|
||||
HttpTokens string `mapstructure:"http_tokens" required:"false"`
|
||||
// A numerical value to set an upper limit for the amount of hops allowed when communicating with IMDS endpoints.
|
||||
// Defaults to 1.
|
||||
HttpPutResponseHopLimit int64 `mapstructure:"http_put_response_hop_limit" required:"false"`
|
||||
}
|
||||
|
||||
// RunConfig contains configuration for running an instance from a source
|
||||
// AMI and details on how to access that launched image.
|
||||
type RunConfig struct {
|
||||
@@ -426,6 +440,9 @@ type RunConfig struct {
|
||||
// 10m
|
||||
WindowsPasswordTimeout time.Duration `mapstructure:"windows_password_timeout" required:"false"`
|
||||
|
||||
// [Metadata Settings](#metadata-settings)
|
||||
Metadata MetadataOptions `mapstructure:"metadata_options" required:"false"`
|
||||
|
||||
// Communicator settings
|
||||
Comm communicator.Config `mapstructure:",squash"`
|
||||
|
||||
@@ -486,6 +503,33 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
// Validation
|
||||
errs := c.Comm.Prepare(ctx)
|
||||
|
||||
if c.Metadata.HttpEndpoint == "" {
|
||||
c.Metadata.HttpEndpoint = "enabled"
|
||||
}
|
||||
|
||||
if c.Metadata.HttpTokens == "" {
|
||||
c.Metadata.HttpTokens = "optional"
|
||||
}
|
||||
|
||||
if c.Metadata.HttpPutResponseHopLimit == 0 {
|
||||
c.Metadata.HttpPutResponseHopLimit = 1
|
||||
}
|
||||
|
||||
if c.Metadata.HttpEndpoint != "enabled" && c.Metadata.HttpEndpoint != "disabled" {
|
||||
msg := fmt.Errorf("http_endpoint requires either disabled or enabled as its value")
|
||||
errs = append(errs, msg)
|
||||
}
|
||||
|
||||
if c.Metadata.HttpTokens != "optional" && c.Metadata.HttpTokens != "required" {
|
||||
msg := fmt.Errorf("http_tokens requires either optional or required as its value")
|
||||
errs = append(errs, msg)
|
||||
}
|
||||
|
||||
if c.Metadata.HttpPutResponseHopLimit < 1 || c.Metadata.HttpPutResponseHopLimit > 64 {
|
||||
msg := fmt.Errorf("http_put_response_hop_limit requires a number between 1 and 64")
|
||||
errs = append(errs, msg)
|
||||
}
|
||||
|
||||
// Copy singular tag maps
|
||||
errs = append(errs, c.RunTag.CopyOn(&c.RunTags)...)
|
||||
errs = append(errs, c.SpotTag.CopyOn(&c.SpotTags)...)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by "mapstructure-to-hcl2 -type AmiFilterOptions,SecurityGroupFilterOptions,SubnetFilterOptions,VpcFilterOptions,PolicyDocument,Statement"; DO NOT EDIT.
|
||||
// Code generated by "mapstructure-to-hcl2 -type AmiFilterOptions,SecurityGroupFilterOptions,SubnetFilterOptions,VpcFilterOptions,PolicyDocument,Statement,MetadataOptions"; DO NOT EDIT.
|
||||
|
||||
package common
|
||||
|
||||
@@ -35,6 +35,33 @@ func (*FlatAmiFilterOptions) HCL2Spec() map[string]hcldec.Spec {
|
||||
return s
|
||||
}
|
||||
|
||||
// FlatMetadataOptions is an auto-generated flat version of MetadataOptions.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatMetadataOptions struct {
|
||||
HttpEndpoint *string `mapstructure:"http_endpoint" required:"false" cty:"http_endpoint" hcl:"http_endpoint"`
|
||||
HttpTokens *string `mapstructure:"http_tokens" required:"false" cty:"http_tokens" hcl:"http_tokens"`
|
||||
HttpPutResponseHopLimit *int64 `mapstructure:"http_put_response_hop_limit" required:"false" cty:"http_put_response_hop_limit" hcl:"http_put_response_hop_limit"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatMetadataOptions.
|
||||
// FlatMetadataOptions is an auto-generated flat version of MetadataOptions.
|
||||
// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up.
|
||||
func (*MetadataOptions) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } {
|
||||
return new(FlatMetadataOptions)
|
||||
}
|
||||
|
||||
// HCL2Spec returns the hcl spec of a MetadataOptions.
|
||||
// This spec is used by HCL to read the fields of MetadataOptions.
|
||||
// The decoded values from this spec will then be applied to a FlatMetadataOptions.
|
||||
func (*FlatMetadataOptions) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"http_endpoint": &hcldec.AttrSpec{Name: "http_endpoint", Type: cty.String, Required: false},
|
||||
"http_tokens": &hcldec.AttrSpec{Name: "http_tokens", Type: cty.String, Required: false},
|
||||
"http_put_response_hop_limit": &hcldec.AttrSpec{Name: "http_put_response_hop_limit", Type: cty.Number, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// FlatPolicyDocument is an auto-generated flat version of PolicyDocument.
|
||||
// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up.
|
||||
type FlatPolicyDocument struct {
|
||||
|
||||
@@ -29,6 +29,9 @@ type StepRunSourceInstance struct {
|
||||
EbsOptimized bool
|
||||
EnableT2Unlimited bool
|
||||
ExpectedRootDevice string
|
||||
HttpEndpoint string
|
||||
HttpTokens string
|
||||
HttpPutResponseHopLimit int64
|
||||
InstanceInitiatedShutdownBehavior string
|
||||
InstanceType string
|
||||
IsRestricted bool
|
||||
@@ -144,6 +147,10 @@ func (s *StepRunSourceInstance) Run(ctx context.Context, state multistep.StateBa
|
||||
runOpts.CreditSpecification = &ec2.CreditSpecificationRequest{CpuCredits: &creditOption}
|
||||
}
|
||||
|
||||
if s.HttpEndpoint == "enabled" {
|
||||
runOpts.MetadataOptions = &ec2.InstanceMetadataOptionsRequest{HttpEndpoint: &s.HttpEndpoint, HttpTokens: &s.HttpTokens, HttpPutResponseHopLimit: &s.HttpPutResponseHopLimit}
|
||||
}
|
||||
|
||||
// Collect tags for tagging on resource creation
|
||||
var tagSpecs []*ec2.TagSpecification
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@ type StepRunSpotInstance struct {
|
||||
Comm *communicator.Config
|
||||
EbsOptimized bool
|
||||
ExpectedRootDevice string
|
||||
HttpEndpoint string
|
||||
HttpTokens string
|
||||
HttpPutResponseHopLimit int64
|
||||
InstanceInitiatedShutdownBehavior string
|
||||
InstanceType string
|
||||
Region string
|
||||
@@ -127,6 +130,10 @@ func (s *StepRunSpotInstance) CreateTemplateData(userData *string, az string,
|
||||
|
||||
}
|
||||
|
||||
if s.HttpEndpoint == "enabled" {
|
||||
templateData.MetadataOptions = &ec2.LaunchTemplateInstanceMetadataOptionsRequest{HttpEndpoint: &s.HttpEndpoint, HttpTokens: &s.HttpTokens, HttpPutResponseHopLimit: &s.HttpPutResponseHopLimit}
|
||||
}
|
||||
|
||||
// If instance type is not set, we'll just pick the lowest priced instance
|
||||
// available.
|
||||
if s.InstanceType != "" {
|
||||
|
||||
@@ -187,6 +187,9 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
|
||||
Debug: b.config.PackerDebug,
|
||||
EbsOptimized: b.config.EbsOptimized,
|
||||
ExpectedRootDevice: "ebs",
|
||||
HttpEndpoint: b.config.Metadata.HttpEndpoint,
|
||||
HttpTokens: b.config.Metadata.HttpTokens,
|
||||
HttpPutResponseHopLimit: b.config.Metadata.HttpPutResponseHopLimit,
|
||||
InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior,
|
||||
InstanceType: b.config.InstanceType,
|
||||
Region: *ec2conn.Config.Region,
|
||||
@@ -211,6 +214,9 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
|
||||
EbsOptimized: b.config.EbsOptimized,
|
||||
EnableT2Unlimited: b.config.EnableT2Unlimited,
|
||||
ExpectedRootDevice: "ebs",
|
||||
HttpEndpoint: b.config.Metadata.HttpEndpoint,
|
||||
HttpTokens: b.config.Metadata.HttpTokens,
|
||||
HttpPutResponseHopLimit: b.config.Metadata.HttpPutResponseHopLimit,
|
||||
InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior,
|
||||
InstanceType: b.config.InstanceType,
|
||||
IsRestricted: b.config.IsChinaCloud() || b.config.IsGovCloud(),
|
||||
|
||||
@@ -90,6 +90,7 @@ type FlatConfig struct {
|
||||
VpcFilter *common.FlatVpcFilterOptions `mapstructure:"vpc_filter" required:"false" cty:"vpc_filter" hcl:"vpc_filter"`
|
||||
VpcId *string `mapstructure:"vpc_id" required:"false" cty:"vpc_id" hcl:"vpc_id"`
|
||||
WindowsPasswordTimeout *string `mapstructure:"windows_password_timeout" required:"false" cty:"windows_password_timeout" hcl:"windows_password_timeout"`
|
||||
Metadata *common.FlatMetadataOptions `mapstructure:"metadata_options" required:"false" cty:"metadata_options" hcl:"metadata_options"`
|
||||
Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"`
|
||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"`
|
||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"`
|
||||
@@ -240,6 +241,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
"vpc_filter": &hcldec.BlockSpec{TypeName: "vpc_filter", Nested: hcldec.ObjectSpec((*common.FlatVpcFilterOptions)(nil).HCL2Spec())},
|
||||
"vpc_id": &hcldec.AttrSpec{Name: "vpc_id", Type: cty.String, Required: false},
|
||||
"windows_password_timeout": &hcldec.AttrSpec{Name: "windows_password_timeout", Type: cty.String, Required: false},
|
||||
"metadata_options": &hcldec.BlockSpec{TypeName: "metadata_options", Nested: hcldec.ObjectSpec((*common.FlatMetadataOptions)(nil).HCL2Spec())},
|
||||
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
|
||||
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
|
||||
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
|
||||
|
||||
@@ -207,6 +207,9 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
|
||||
Debug: b.config.PackerDebug,
|
||||
EbsOptimized: b.config.EbsOptimized,
|
||||
ExpectedRootDevice: "ebs",
|
||||
HttpEndpoint: b.config.Metadata.HttpEndpoint,
|
||||
HttpTokens: b.config.Metadata.HttpTokens,
|
||||
HttpPutResponseHopLimit: b.config.Metadata.HttpPutResponseHopLimit,
|
||||
InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior,
|
||||
InstanceType: b.config.InstanceType,
|
||||
Region: *ec2conn.Config.Region,
|
||||
@@ -230,6 +233,9 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
|
||||
EbsOptimized: b.config.EbsOptimized,
|
||||
EnableT2Unlimited: b.config.EnableT2Unlimited,
|
||||
ExpectedRootDevice: "ebs",
|
||||
HttpEndpoint: b.config.Metadata.HttpEndpoint,
|
||||
HttpTokens: b.config.Metadata.HttpTokens,
|
||||
HttpPutResponseHopLimit: b.config.Metadata.HttpPutResponseHopLimit,
|
||||
InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior,
|
||||
InstanceType: b.config.InstanceType,
|
||||
IsRestricted: b.config.IsChinaCloud() || b.config.IsGovCloud(),
|
||||
|
||||
@@ -113,6 +113,7 @@ type FlatConfig struct {
|
||||
VpcFilter *common.FlatVpcFilterOptions `mapstructure:"vpc_filter" required:"false" cty:"vpc_filter" hcl:"vpc_filter"`
|
||||
VpcId *string `mapstructure:"vpc_id" required:"false" cty:"vpc_id" hcl:"vpc_id"`
|
||||
WindowsPasswordTimeout *string `mapstructure:"windows_password_timeout" required:"false" cty:"windows_password_timeout" hcl:"windows_password_timeout"`
|
||||
Metadata *common.FlatMetadataOptions `mapstructure:"metadata_options" required:"false" cty:"metadata_options" hcl:"metadata_options"`
|
||||
Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"`
|
||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"`
|
||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"`
|
||||
@@ -263,6 +264,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
"vpc_filter": &hcldec.BlockSpec{TypeName: "vpc_filter", Nested: hcldec.ObjectSpec((*common.FlatVpcFilterOptions)(nil).HCL2Spec())},
|
||||
"vpc_id": &hcldec.AttrSpec{Name: "vpc_id", Type: cty.String, Required: false},
|
||||
"windows_password_timeout": &hcldec.AttrSpec{Name: "windows_password_timeout", Type: cty.String, Required: false},
|
||||
"metadata_options": &hcldec.BlockSpec{TypeName: "metadata_options", Nested: hcldec.ObjectSpec((*common.FlatMetadataOptions)(nil).HCL2Spec())},
|
||||
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
|
||||
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
|
||||
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
|
||||
|
||||
@@ -195,6 +195,9 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
|
||||
Debug: b.config.PackerDebug,
|
||||
EbsOptimized: b.config.EbsOptimized,
|
||||
ExpectedRootDevice: "ebs",
|
||||
HttpEndpoint: b.config.Metadata.HttpEndpoint,
|
||||
HttpTokens: b.config.Metadata.HttpTokens,
|
||||
HttpPutResponseHopLimit: b.config.Metadata.HttpPutResponseHopLimit,
|
||||
InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior,
|
||||
InstanceType: b.config.InstanceType,
|
||||
Region: *ec2conn.Config.Region,
|
||||
@@ -218,6 +221,9 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
|
||||
EbsOptimized: b.config.EbsOptimized,
|
||||
EnableT2Unlimited: b.config.EnableT2Unlimited,
|
||||
ExpectedRootDevice: "ebs",
|
||||
HttpEndpoint: b.config.Metadata.HttpEndpoint,
|
||||
HttpTokens: b.config.Metadata.HttpTokens,
|
||||
HttpPutResponseHopLimit: b.config.Metadata.HttpPutResponseHopLimit,
|
||||
InstanceInitiatedShutdownBehavior: b.config.InstanceInitiatedShutdownBehavior,
|
||||
InstanceType: b.config.InstanceType,
|
||||
IsRestricted: b.config.IsChinaCloud() || b.config.IsGovCloud(),
|
||||
|
||||
@@ -115,6 +115,7 @@ type FlatConfig struct {
|
||||
VpcFilter *common.FlatVpcFilterOptions `mapstructure:"vpc_filter" required:"false" cty:"vpc_filter" hcl:"vpc_filter"`
|
||||
VpcId *string `mapstructure:"vpc_id" required:"false" cty:"vpc_id" hcl:"vpc_id"`
|
||||
WindowsPasswordTimeout *string `mapstructure:"windows_password_timeout" required:"false" cty:"windows_password_timeout" hcl:"windows_password_timeout"`
|
||||
Metadata *common.FlatMetadataOptions `mapstructure:"metadata_options" required:"false" cty:"metadata_options" hcl:"metadata_options"`
|
||||
Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"`
|
||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"`
|
||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"`
|
||||
@@ -242,6 +243,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
"vpc_filter": &hcldec.BlockSpec{TypeName: "vpc_filter", Nested: hcldec.ObjectSpec((*common.FlatVpcFilterOptions)(nil).HCL2Spec())},
|
||||
"vpc_id": &hcldec.AttrSpec{Name: "vpc_id", Type: cty.String, Required: false},
|
||||
"windows_password_timeout": &hcldec.AttrSpec{Name: "windows_password_timeout", Type: cty.String, Required: false},
|
||||
"metadata_options": &hcldec.BlockSpec{TypeName: "metadata_options", Nested: hcldec.ObjectSpec((*common.FlatMetadataOptions)(nil).HCL2Spec())},
|
||||
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
|
||||
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
|
||||
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
|
||||
|
||||
@@ -90,6 +90,7 @@ type FlatConfig struct {
|
||||
VpcFilter *common.FlatVpcFilterOptions `mapstructure:"vpc_filter" required:"false" cty:"vpc_filter" hcl:"vpc_filter"`
|
||||
VpcId *string `mapstructure:"vpc_id" required:"false" cty:"vpc_id" hcl:"vpc_id"`
|
||||
WindowsPasswordTimeout *string `mapstructure:"windows_password_timeout" required:"false" cty:"windows_password_timeout" hcl:"windows_password_timeout"`
|
||||
Metadata *common.FlatMetadataOptions `mapstructure:"metadata_options" required:"false" cty:"metadata_options" hcl:"metadata_options"`
|
||||
Type *string `mapstructure:"communicator" cty:"communicator" hcl:"communicator"`
|
||||
PauseBeforeConnect *string `mapstructure:"pause_before_connecting" cty:"pause_before_connecting" hcl:"pause_before_connecting"`
|
||||
SSHHost *string `mapstructure:"ssh_host" cty:"ssh_host" hcl:"ssh_host"`
|
||||
@@ -245,6 +246,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
"vpc_filter": &hcldec.BlockSpec{TypeName: "vpc_filter", Nested: hcldec.ObjectSpec((*common.FlatVpcFilterOptions)(nil).HCL2Spec())},
|
||||
"vpc_id": &hcldec.AttrSpec{Name: "vpc_id", Type: cty.String, Required: false},
|
||||
"windows_password_timeout": &hcldec.AttrSpec{Name: "windows_password_timeout", Type: cty.String, Required: false},
|
||||
"metadata_options": &hcldec.BlockSpec{TypeName: "metadata_options", Nested: hcldec.ObjectSpec((*common.FlatMetadataOptions)(nil).HCL2Spec())},
|
||||
"communicator": &hcldec.AttrSpec{Name: "communicator", Type: cty.String, Required: false},
|
||||
"pause_before_connecting": &hcldec.AttrSpec{Name: "pause_before_connecting", Type: cty.String, Required: false},
|
||||
"ssh_host": &hcldec.AttrSpec{Name: "ssh_host", Type: cty.String, Required: false},
|
||||
|
||||
@@ -22,8 +22,11 @@ func (s *stepCreateServer) Run(ctx context.Context, state multistep.StateBag) mu
|
||||
|
||||
profitbricks.SetAuth(c.PBUsername, c.PBPassword)
|
||||
profitbricks.SetDepth("5")
|
||||
if sshkey, ok := state.GetOk("publicKey"); ok {
|
||||
c.SSHKey = sshkey.(string)
|
||||
if c.Comm.SSHPublicKey != nil {
|
||||
c.SSHKey = string(c.Comm.SSHPublicKey)
|
||||
} else {
|
||||
ui.Error("No ssh private key set; ssh authentication won't be possible. Please specify your private key in the ssh_private_key_file configuration key.")
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
ui.Say("Creating Virtual Data Center...")
|
||||
img := s.getImageId(c.Image, c)
|
||||
@@ -204,7 +207,7 @@ func (d *stepCreateServer) setPB(username string, password string, url string) {
|
||||
|
||||
func (d *stepCreateServer) checkForErrors(instance profitbricks.Resp) error {
|
||||
if instance.StatusCode > 299 {
|
||||
return errors.New(fmt.Sprintf("Error occurred %s", string(instance.Body)))
|
||||
return fmt.Errorf("Error occurred %s", string(instance.Body))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -261,7 +264,9 @@ func (d *stepCreateServer) getImageAlias(imageAlias string, location string, ui
|
||||
|
||||
func parseErrorMessage(raw string) (toreturn string) {
|
||||
var tmp map[string]interface{}
|
||||
json.Unmarshal([]byte(raw), &tmp)
|
||||
if json.Unmarshal([]byte(raw), &tmp) != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, v := range tmp["messages"].([]interface{}) {
|
||||
for index, i := range v.(map[string]interface{}) {
|
||||
|
||||
@@ -3,6 +3,9 @@ package profitbricks
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
@@ -22,9 +25,32 @@ func (s *stepTakeSnapshot) Run(ctx context.Context, state multistep.StateBag) mu
|
||||
|
||||
dcId := state.Get("datacenter_id").(string)
|
||||
volumeId := state.Get("volume_id").(string)
|
||||
serverId := state.Get("instance_id").(string)
|
||||
|
||||
comm, _ := state.Get("communicator").(packersdk.Communicator)
|
||||
if comm == nil {
|
||||
ui.Error("no communicator found")
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
/* sync fs changes from the provisioning step */
|
||||
os, err := s.getOs(dcId, serverId)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("an error occurred while getting the server os: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
ui.Say(fmt.Sprintf("Server OS is %s", os))
|
||||
|
||||
switch strings.ToLower(os) {
|
||||
case "linux":
|
||||
ui.Say("syncing file system changes")
|
||||
if err := s.syncFs(ctx, comm); err != nil {
|
||||
ui.Error(fmt.Sprintf("error syncing fs changes: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
|
||||
snapshot := profitbricks.CreateSnapshot(dcId, volumeId, c.SnapshotName, "")
|
||||
|
||||
state.Put("snapshotname", c.SnapshotName)
|
||||
|
||||
if snapshot.StatusCode > 299 {
|
||||
@@ -42,31 +68,123 @@ func (s *stepTakeSnapshot) Run(ctx context.Context, state multistep.StateBag) mu
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
s.waitTillProvisioned(snapshot.Headers.Get("Location"), *c)
|
||||
ui.Say(fmt.Sprintf("Creating a snapshot for %s/volumes/%s", dcId, volumeId))
|
||||
|
||||
err = s.waitForRequest(snapshot.Headers.Get("Location"), *c, ui)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("An error occurred while waiting for the request to be done: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
err = s.waitTillSnapshotAvailable(snapshot.Id, *c, ui)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("An error occurred while waiting for the snapshot to be created: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *stepTakeSnapshot) Cleanup(state multistep.StateBag) {
|
||||
func (s *stepTakeSnapshot) Cleanup(_ multistep.StateBag) {
|
||||
}
|
||||
|
||||
func (d *stepTakeSnapshot) waitTillProvisioned(path string, config Config) {
|
||||
d.setPB(config.PBUsername, config.PBPassword, config.PBUrl)
|
||||
func (s *stepTakeSnapshot) waitForRequest(path string, config Config, ui packersdk.Ui) error {
|
||||
|
||||
ui.Say(fmt.Sprintf("Watching request %s", path))
|
||||
s.setPB(config.PBUsername, config.PBPassword, config.PBUrl)
|
||||
waitCount := 50
|
||||
var waitInterval = 10 * time.Second
|
||||
if config.Retries > 0 {
|
||||
waitCount = config.Retries
|
||||
}
|
||||
done := false
|
||||
for i := 0; i < waitCount; i++ {
|
||||
request := profitbricks.GetRequestStatus(path)
|
||||
ui.Say(fmt.Sprintf("request status = %s", request.Metadata.Status))
|
||||
if request.Metadata.Status == "DONE" {
|
||||
done = true
|
||||
break
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
if request.Metadata.Status == "FAILED" {
|
||||
return fmt.Errorf("Request failed: %s", request.Response)
|
||||
}
|
||||
time.Sleep(waitInterval)
|
||||
i++
|
||||
}
|
||||
|
||||
if done == false {
|
||||
return fmt.Errorf("request not fulfilled after waiting %d seconds",
|
||||
int64(waitCount)*int64(waitInterval)/int64(time.Second))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *stepTakeSnapshot) setPB(username string, password string, url string) {
|
||||
func (s *stepTakeSnapshot) waitTillSnapshotAvailable(id string, config Config, ui packersdk.Ui) error {
|
||||
s.setPB(config.PBUsername, config.PBPassword, config.PBUrl)
|
||||
waitCount := 50
|
||||
var waitInterval = 10 * time.Second
|
||||
if config.Retries > 0 {
|
||||
waitCount = config.Retries
|
||||
}
|
||||
done := false
|
||||
ui.Say(fmt.Sprintf("waiting for snapshot %s to become available", id))
|
||||
for i := 0; i < waitCount; i++ {
|
||||
snap := profitbricks.GetSnapshot(id)
|
||||
ui.Say(fmt.Sprintf("snapshot status = %s", snap.Metadata.State))
|
||||
if snap.StatusCode != 200 {
|
||||
return fmt.Errorf("%s", snap.Response)
|
||||
}
|
||||
if snap.Metadata.State == "AVAILABLE" {
|
||||
done = true
|
||||
break
|
||||
}
|
||||
time.Sleep(waitInterval)
|
||||
i++
|
||||
ui.Say(fmt.Sprintf("... still waiting, %d seconds have passed", int64(waitInterval)*int64(i)))
|
||||
}
|
||||
|
||||
if done == false {
|
||||
return fmt.Errorf("snapshot not created after waiting %d seconds",
|
||||
int64(waitCount)*int64(waitInterval)/int64(time.Second))
|
||||
}
|
||||
|
||||
ui.Say("snapshot created")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stepTakeSnapshot) syncFs(ctx context.Context, comm packersdk.Communicator) error {
|
||||
cmd := &packersdk.RemoteCmd{
|
||||
Command: "sync",
|
||||
}
|
||||
if err := comm.Start(ctx, cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
if cmd.Wait() != 0 {
|
||||
return fmt.Errorf("sync command exited with code %d", cmd.ExitStatus())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *stepTakeSnapshot) getOs(dcId string, serverId string) (string, error) {
|
||||
server := profitbricks.GetServer(dcId, serverId)
|
||||
if server.StatusCode != 200 {
|
||||
return "", errors.New(server.Response)
|
||||
}
|
||||
|
||||
if server.Properties.BootVolume == nil {
|
||||
return "", errors.New("no boot volume found on server")
|
||||
}
|
||||
|
||||
volumeId := server.Properties.BootVolume.Id
|
||||
volume := profitbricks.GetVolume(dcId, volumeId)
|
||||
if volume.StatusCode != 200 {
|
||||
return "", errors.New(volume.Response)
|
||||
}
|
||||
|
||||
return volume.Properties.LicenceType, nil
|
||||
}
|
||||
|
||||
func (s *stepTakeSnapshot) setPB(username string, password string, url string) {
|
||||
profitbricks.SetAuth(username, password)
|
||||
profitbricks.SetEndpoint(url)
|
||||
}
|
||||
|
||||
+219
-46
@@ -74,9 +74,12 @@ const (
|
||||
# All generated input variables will be of 'string' type as this is how Packer JSON
|
||||
# views them; you can change their type later on. Read the variables type
|
||||
# constraints documentation
|
||||
# https://www.packer.io/docs/templates/hcl_templates/variables#type-constraints for more info.
|
||||
`
|
||||
|
||||
# https://www.packer.io/docs/templates/hcl_templates/variables#type-constraints for more info.`
|
||||
localsVarHeader = `
|
||||
# All locals variables are generated from variables that uses expressions
|
||||
# that are not allowed in HCL2 variables.
|
||||
# Read the documentation for locals blocks here:
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/locals`
|
||||
packerBlockHeader = `
|
||||
# See https://www.packer.io/docs/templates/hcl_templates/blocks/packer for more info
|
||||
`
|
||||
@@ -93,15 +96,28 @@ const (
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/build
|
||||
build {
|
||||
`
|
||||
|
||||
amazonAmiDataHeader = `
|
||||
# The amazon-ami data block is generated from your amazon builder source_ami_filter; a data
|
||||
# from this block can be referenced in source and locals blocks.
|
||||
# Read the documentation for data blocks here:
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/data`
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/data
|
||||
# Read the documentation for the Amazon AMI Data Source here:
|
||||
# https://www.packer.io/docs/datasources/amazon/ami`
|
||||
|
||||
amazonSecretsManagerDataHeader = `
|
||||
# The amazon-secretsmanager data block is generated from your aws_secretsmanager template function; a data
|
||||
# from this block can be referenced in source and locals blocks.
|
||||
# Read the documentation for data blocks here:
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/data
|
||||
# Read the documentation for the Amazon Secrets Manager Data Source here:
|
||||
# https://www.packer.io/docs/datasources/amazon/secretsmanager`
|
||||
)
|
||||
|
||||
var amazonSecretsManagerMap = map[string]map[string]interface{}{}
|
||||
var localsVariableMap = map[string]string{}
|
||||
|
||||
func (c *HCL2UpgradeCommand) RunContext(buildCtx context.Context, cla *HCL2UpgradeArgs) int {
|
||||
out := &bytes.Buffer{}
|
||||
var output io.Writer
|
||||
if err := os.MkdirAll(filepath.Dir(cla.OutputFile), 0); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Failed to create output directory: %v", err))
|
||||
@@ -131,20 +147,16 @@ func (c *HCL2UpgradeCommand) RunContext(buildCtx context.Context, cla *HCL2Upgra
|
||||
}
|
||||
tpl := core.Template
|
||||
|
||||
// Packer section
|
||||
if tpl.MinVersion != "" {
|
||||
out.Write([]byte(packerBlockHeader))
|
||||
fileContent := hclwrite.NewEmptyFile()
|
||||
body := fileContent.Body()
|
||||
packerBody := body.AppendNewBlock("packer", nil).Body()
|
||||
packerBody.SetAttributeValue("required_version", cty.StringVal(fmt.Sprintf(">= %s", tpl.MinVersion)))
|
||||
out.Write(fileContent.Bytes())
|
||||
}
|
||||
// OutPut Locals and Local blocks
|
||||
localsContent := hclwrite.NewEmptyFile()
|
||||
localsBody := localsContent.Body()
|
||||
localsBody.AppendNewline()
|
||||
localBody := localsBody.AppendNewBlock("locals", nil).Body()
|
||||
|
||||
out.Write([]byte(inputVarHeader))
|
||||
localsOut := []byte{}
|
||||
|
||||
// Output variables section
|
||||
|
||||
variablesOut := []byte{}
|
||||
variables := []*template.Variable{}
|
||||
{
|
||||
// sort variables to avoid map's randomness
|
||||
@@ -157,27 +169,47 @@ func (c *HCL2UpgradeCommand) RunContext(buildCtx context.Context, cla *HCL2Upgra
|
||||
})
|
||||
}
|
||||
|
||||
hasLocals := false
|
||||
for _, variable := range variables {
|
||||
variablesContent := hclwrite.NewEmptyFile()
|
||||
variablesBody := variablesContent.Body()
|
||||
|
||||
variablesBody.AppendNewline()
|
||||
variableBody := variablesBody.AppendNewBlock("variable", []string{variable.Key}).Body()
|
||||
variableBody.SetAttributeRaw("type", hclwrite.Tokens{&hclwrite.Token{Bytes: []byte("string")}})
|
||||
|
||||
if variable.Default != "" || !variable.Required {
|
||||
variableBody.SetAttributeValue("default", hcl2shim.HCL2ValueFromConfigValue(variable.Default))
|
||||
}
|
||||
sensitive := false
|
||||
if isSensitiveVariable(variable.Key, tpl.SensitiveVariables) {
|
||||
sensitive = true
|
||||
variableBody.SetAttributeValue("sensitive", cty.BoolVal(true))
|
||||
}
|
||||
variablesBody.AppendNewline()
|
||||
out.Write(transposeTemplatingCalls(variablesContent.Bytes()))
|
||||
isLocal, out := variableTransposeTemplatingCalls(variablesContent.Bytes())
|
||||
if isLocal {
|
||||
if sensitive {
|
||||
// Create Local block because this is sensitive
|
||||
localContent := hclwrite.NewEmptyFile()
|
||||
body := localContent.Body()
|
||||
body.AppendNewline()
|
||||
localBody := body.AppendNewBlock("local", []string{variable.Key}).Body()
|
||||
localBody.SetAttributeValue("sensitive", cty.BoolVal(true))
|
||||
localBody.SetAttributeValue("expression", hcl2shim.HCL2ValueFromConfigValue(variable.Default))
|
||||
localsOut = append(localsOut, transposeTemplatingCalls(localContent.Bytes())...)
|
||||
localsVariableMap[variable.Key] = "local"
|
||||
continue
|
||||
}
|
||||
localBody.SetAttributeValue(variable.Key, hcl2shim.HCL2ValueFromConfigValue(variable.Default))
|
||||
localsVariableMap[variable.Key] = "locals"
|
||||
hasLocals = true
|
||||
continue
|
||||
}
|
||||
variablesOut = append(variablesOut, out...)
|
||||
}
|
||||
|
||||
fmt.Fprintln(out, `# "timestamp" template function replacement`)
|
||||
fmt.Fprintln(out, `locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }`)
|
||||
|
||||
// Output sources section
|
||||
if hasLocals {
|
||||
localsOut = append(localsOut, transposeTemplatingCalls(localsContent.Bytes())...)
|
||||
}
|
||||
|
||||
builders := []*template.Builder{}
|
||||
{
|
||||
@@ -187,7 +219,9 @@ func (c *HCL2UpgradeCommand) RunContext(buildCtx context.Context, cla *HCL2Upgra
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.writeAmazonAmiDatasource(builders, out); err != nil {
|
||||
// Output amazon-ami data source section
|
||||
amazonAmiOut, err := c.writeAmazonAmiDatasource(builders)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -195,8 +229,8 @@ func (c *HCL2UpgradeCommand) RunContext(buildCtx context.Context, cla *HCL2Upgra
|
||||
return builders[i].Type+builders[i].Name < builders[j].Type+builders[j].Name
|
||||
})
|
||||
|
||||
out.Write([]byte(sourcesHeader))
|
||||
|
||||
// Output sources section
|
||||
sourcesOut := []byte{}
|
||||
for i, builderCfg := range builders {
|
||||
sourcesContent := hclwrite.NewEmptyFile()
|
||||
body := sourcesContent.Body()
|
||||
@@ -209,16 +243,16 @@ func (c *HCL2UpgradeCommand) RunContext(buildCtx context.Context, cla *HCL2Upgra
|
||||
if builderCfg.Name == "" || builderCfg.Name == builderCfg.Type {
|
||||
builderCfg.Name = fmt.Sprintf("autogenerated_%d", i+1)
|
||||
}
|
||||
builderCfg.Name = strings.ReplaceAll(strings.TrimSpace(builderCfg.Name), " ", "_")
|
||||
|
||||
sourceBody := body.AppendNewBlock("source", []string{builderCfg.Type, builderCfg.Name}).Body()
|
||||
|
||||
jsonBodyToHCL2Body(sourceBody, builderCfg.Config)
|
||||
|
||||
_, _ = out.Write(transposeTemplatingCalls(sourcesContent.Bytes()))
|
||||
sourcesOut = append(sourcesOut, transposeTemplatingCalls(sourcesContent.Bytes())...)
|
||||
}
|
||||
|
||||
// Output build section
|
||||
out.Write([]byte(buildHeader))
|
||||
|
||||
buildContent := hclwrite.NewEmptyFile()
|
||||
buildBody := buildContent.Body()
|
||||
if tpl.Description != "" {
|
||||
@@ -232,8 +266,10 @@ func (c *HCL2UpgradeCommand) RunContext(buildCtx context.Context, cla *HCL2Upgra
|
||||
}
|
||||
buildBody.SetAttributeValue("sources", hcl2shim.HCL2ValueFromConfigValue(sourceNames))
|
||||
buildBody.AppendNewline()
|
||||
_, _ = buildContent.WriteTo(out)
|
||||
buildOut := buildContent.Bytes()
|
||||
|
||||
// Output provisioners section
|
||||
provisionersOut := []byte{}
|
||||
for _, provisioner := range tpl.Provisioners {
|
||||
provisionerContent := hclwrite.NewEmptyFile()
|
||||
body := provisionerContent.Body()
|
||||
@@ -255,8 +291,11 @@ func (c *HCL2UpgradeCommand) RunContext(buildCtx context.Context, cla *HCL2Upgra
|
||||
}
|
||||
jsonBodyToHCL2Body(block.Body(), cfg)
|
||||
|
||||
out.Write(transposeTemplatingCalls(provisionerContent.Bytes()))
|
||||
provisionersOut = append(provisionersOut, transposeTemplatingCalls(provisionerContent.Bytes())...)
|
||||
}
|
||||
|
||||
// Output post-processors section
|
||||
postProcessorsOut := []byte{}
|
||||
for _, pps := range tpl.PostProcessors {
|
||||
postProcessorContent := hclwrite.NewEmptyFile()
|
||||
body := postProcessorContent.Body()
|
||||
@@ -286,9 +325,69 @@ func (c *HCL2UpgradeCommand) RunContext(buildCtx context.Context, cla *HCL2Upgra
|
||||
jsonBodyToHCL2Body(ppBody, cfg)
|
||||
}
|
||||
|
||||
_, _ = out.Write(transposeTemplatingCalls(postProcessorContent.Bytes()))
|
||||
postProcessorsOut = append(postProcessorsOut, transposeTemplatingCalls(postProcessorContent.Bytes())...)
|
||||
}
|
||||
|
||||
// Output amazon-secretsmanager data source section
|
||||
keys := make([]string, 0, len(amazonSecretsManagerMap))
|
||||
for k := range amazonSecretsManagerMap {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
amazonSecretsDataOut := []byte{}
|
||||
for _, dataSourceName := range keys {
|
||||
datasourceContent := hclwrite.NewEmptyFile()
|
||||
body := datasourceContent.Body()
|
||||
body.AppendNewline()
|
||||
datasourceBody := body.AppendNewBlock("data", []string{"amazon-secretsmanager", dataSourceName}).Body()
|
||||
jsonBodyToHCL2Body(datasourceBody, amazonSecretsManagerMap[dataSourceName])
|
||||
amazonSecretsDataOut = append(amazonSecretsDataOut, datasourceContent.Bytes()...)
|
||||
}
|
||||
|
||||
// Write file
|
||||
out := &bytes.Buffer{}
|
||||
|
||||
// Packer section
|
||||
if tpl.MinVersion != "" {
|
||||
out.Write([]byte(packerBlockHeader))
|
||||
fileContent := hclwrite.NewEmptyFile()
|
||||
body := fileContent.Body()
|
||||
packerBody := body.AppendNewBlock("packer", nil).Body()
|
||||
packerBody.SetAttributeValue("required_version", cty.StringVal(fmt.Sprintf(">= %s", tpl.MinVersion)))
|
||||
out.Write(fileContent.Bytes())
|
||||
}
|
||||
|
||||
out.Write([]byte(inputVarHeader))
|
||||
out.Write(variablesOut)
|
||||
|
||||
if len(amazonSecretsManagerMap) > 0 {
|
||||
out.Write([]byte(amazonSecretsManagerDataHeader))
|
||||
out.Write(amazonSecretsDataOut)
|
||||
}
|
||||
|
||||
if len(amazonAmiOut) > 0 {
|
||||
out.Write([]byte(amazonAmiDataHeader))
|
||||
out.Write(amazonAmiOut)
|
||||
}
|
||||
|
||||
_, _ = out.Write([]byte("\n"))
|
||||
fmt.Fprintln(out, `# "timestamp" template function replacement`)
|
||||
fmt.Fprintln(out, `locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }`)
|
||||
|
||||
if len(localsOut) > 0 {
|
||||
out.Write([]byte(localsVarHeader))
|
||||
out.Write(localsOut)
|
||||
}
|
||||
|
||||
out.Write([]byte(sourcesHeader))
|
||||
out.Write(sourcesOut)
|
||||
|
||||
out.Write([]byte(buildHeader))
|
||||
out.Write(buildOut)
|
||||
out.Write(provisionersOut)
|
||||
out.Write(postProcessorsOut)
|
||||
|
||||
_, _ = out.Write([]byte("}\n"))
|
||||
|
||||
_, _ = output.Write(hclwrite.Format(out.Bytes()))
|
||||
@@ -298,9 +397,9 @@ func (c *HCL2UpgradeCommand) RunContext(buildCtx context.Context, cla *HCL2Upgra
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *HCL2UpgradeCommand) writeAmazonAmiDatasource(builders []*template.Builder, out *bytes.Buffer) error {
|
||||
func (c *HCL2UpgradeCommand) writeAmazonAmiDatasource(builders []*template.Builder) ([]byte, error) {
|
||||
amazonAmiOut := []byte{}
|
||||
amazonAmiFilters := []map[string]interface{}{}
|
||||
first := true
|
||||
i := 1
|
||||
for _, builder := range builders {
|
||||
if strings.HasPrefix(builder.Type, "amazon-") {
|
||||
@@ -308,7 +407,7 @@ func (c *HCL2UpgradeCommand) writeAmazonAmiDatasource(builders []*template.Build
|
||||
sourceAmiFilterCfg := map[string]interface{}{}
|
||||
if err := mapstructure.Decode(sourceAmiFilter, &sourceAmiFilterCfg); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Failed to write amazon-ami data source: %v", err))
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
duplicate := false
|
||||
@@ -336,21 +435,17 @@ func (c *HCL2UpgradeCommand) writeAmazonAmiDatasource(builders []*template.Build
|
||||
builder.Config["source_ami"] = sourceAmiDataRef
|
||||
i++
|
||||
|
||||
if first {
|
||||
out.Write([]byte(amazonAmiDataHeader))
|
||||
first = false
|
||||
}
|
||||
datasourceContent := hclwrite.NewEmptyFile()
|
||||
body := datasourceContent.Body()
|
||||
body.AppendNewline()
|
||||
sourceBody := body.AppendNewBlock("data", []string{"amazon-ami", dataSourceName}).Body()
|
||||
jsonBodyToHCL2Body(sourceBody, sourceAmiFilterCfg)
|
||||
_, _ = out.Write(transposeTemplatingCalls(datasourceContent.Bytes()))
|
||||
amazonAmiOut = append(amazonAmiOut, transposeTemplatingCalls(datasourceContent.Bytes())...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return amazonAmiOut, nil
|
||||
}
|
||||
|
||||
type UnhandleableArgumentError struct {
|
||||
@@ -377,14 +472,71 @@ func transposeTemplatingCalls(s []byte) []byte {
|
||||
|
||||
return append([]byte(fmt.Sprintf("\n# could not parse template for following block: %q\n", err)), s...)
|
||||
}
|
||||
funcMap := texttemplate.FuncMap{
|
||||
"timestamp": func() string {
|
||||
funcMap := templateCommonFunctionMap()
|
||||
|
||||
tpl, err := texttemplate.New("hcl2_upgrade").
|
||||
Funcs(funcMap).
|
||||
Parse(string(s))
|
||||
|
||||
if err != nil {
|
||||
return fallbackReturn(err)
|
||||
}
|
||||
|
||||
str := &bytes.Buffer{}
|
||||
v := struct {
|
||||
HTTPIP string
|
||||
HTTPPort string
|
||||
}{
|
||||
HTTPIP: "{{ .HTTPIP }}",
|
||||
HTTPPort: "{{ .HTTPPort }}",
|
||||
}
|
||||
if err := tpl.Execute(str, v); err != nil {
|
||||
return fallbackReturn(err)
|
||||
}
|
||||
|
||||
return str.Bytes()
|
||||
}
|
||||
|
||||
func templateCommonFunctionMap() texttemplate.FuncMap {
|
||||
return texttemplate.FuncMap{
|
||||
"aws_secretsmanager": func(a ...string) string {
|
||||
if len(a) == 2 {
|
||||
for key, config := range amazonSecretsManagerMap {
|
||||
nameOk := config["name"] == a[0]
|
||||
keyOk := config["key"] == a[1]
|
||||
if nameOk && keyOk {
|
||||
return fmt.Sprintf("${data.amazon-secretsmanager.%s.value}", key)
|
||||
}
|
||||
}
|
||||
id := fmt.Sprintf("autogenerated_%d", len(amazonSecretsManagerMap)+1)
|
||||
amazonSecretsManagerMap[id] = map[string]interface{}{
|
||||
"name": a[0],
|
||||
"key": a[1],
|
||||
}
|
||||
return fmt.Sprintf("${data.amazon-secretsmanager.%s.value}", id)
|
||||
}
|
||||
for key, config := range amazonSecretsManagerMap {
|
||||
nameOk := config["name"] == a[0]
|
||||
if nameOk {
|
||||
return fmt.Sprintf("${data.amazon-secretsmanager.%s.value}", key)
|
||||
}
|
||||
}
|
||||
id := fmt.Sprintf("autogenerated_%d", len(amazonSecretsManagerMap)+1)
|
||||
amazonSecretsManagerMap[id] = map[string]interface{}{
|
||||
"name": a[0],
|
||||
}
|
||||
return fmt.Sprintf("${data.amazon-secretsmanager.%s.value}", id)
|
||||
}, "timestamp": func() string {
|
||||
return "${local.timestamp}"
|
||||
},
|
||||
"isotime": func() string {
|
||||
return "${local.timestamp}"
|
||||
},
|
||||
"user": func(in string) string {
|
||||
if _, ok := localsVariableMap[in]; ok {
|
||||
// variable is now a local
|
||||
return fmt.Sprintf("${local.%s}", in)
|
||||
}
|
||||
return fmt.Sprintf("${var.%s}", in)
|
||||
},
|
||||
"env": func(in string) string {
|
||||
@@ -459,13 +611,34 @@ func transposeTemplatingCalls(s []byte) []byte {
|
||||
return fmt.Sprintf("${build.type}")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// variableTransposeTemplatingCalls executes parts of blocks as go template files and replaces
|
||||
// their result with their hcl2 variant for variables block only. If something goes wrong the template
|
||||
// containing the go template string is returned.
|
||||
// In variableTransposeTemplatingCalls the definition of aws_secretsmanager function will create a data source
|
||||
// with the same name as the variable.
|
||||
func variableTransposeTemplatingCalls(s []byte) (isLocal bool, body []byte) {
|
||||
fallbackReturn := func(err error) []byte {
|
||||
if strings.Contains(err.Error(), "unhandled") {
|
||||
return append([]byte(fmt.Sprintf("\n# %s\n", err)), s...)
|
||||
}
|
||||
|
||||
return append([]byte(fmt.Sprintf("\n# could not parse template for following block: %q\n", err)), s...)
|
||||
}
|
||||
|
||||
funcMap := templateCommonFunctionMap()
|
||||
funcMap["aws_secretsmanager"] = func(a ...string) string {
|
||||
isLocal = true
|
||||
return ""
|
||||
}
|
||||
|
||||
tpl, err := texttemplate.New("hcl2_upgrade").
|
||||
Funcs(funcMap).
|
||||
Parse(string(s))
|
||||
|
||||
if err != nil {
|
||||
return fallbackReturn(err)
|
||||
return isLocal, fallbackReturn(err)
|
||||
}
|
||||
|
||||
str := &bytes.Buffer{}
|
||||
@@ -477,10 +650,10 @@ func transposeTemplatingCalls(s []byte) []byte {
|
||||
HTTPPort: "{{ .HTTPPort }}",
|
||||
}
|
||||
if err := tpl.Execute(str, v); err != nil {
|
||||
return fallbackReturn(err)
|
||||
return isLocal, fallbackReturn(err)
|
||||
}
|
||||
|
||||
return str.Bytes()
|
||||
return isLocal, str.Bytes()
|
||||
}
|
||||
|
||||
func jsonBodyToHCL2Body(out *hclwrite.Body, kvs map[string]interface{}) {
|
||||
|
||||
@@ -19,14 +19,16 @@ func Test_hcl2_upgrade(t *testing.T) {
|
||||
tc := []struct {
|
||||
folder string
|
||||
}{
|
||||
{"hcl2_upgrade_basic"},
|
||||
{"basic"},
|
||||
{"minimal"},
|
||||
{"source-name"},
|
||||
}
|
||||
|
||||
for _, tc := range tc {
|
||||
t.Run(tc.folder, func(t *testing.T) {
|
||||
inputPath := filepath.Join(testFixture(tc.folder, "input.json"))
|
||||
inputPath := filepath.Join(testFixture("hcl2_upgrade", tc.folder, "input.json"))
|
||||
outputPath := inputPath + ".pkr.hcl"
|
||||
expectedPath := filepath.Join(testFixture(tc.folder, "expected.pkr.hcl"))
|
||||
expectedPath := filepath.Join(testFixture("hcl2_upgrade", tc.folder, "expected.pkr.hcl"))
|
||||
p := helperCommand(t, "hcl2_upgrade", inputPath)
|
||||
bs, err := p.CombinedOutput()
|
||||
if err != nil {
|
||||
|
||||
+145
-56
@@ -1,10 +1,9 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sort"
|
||||
"testing"
|
||||
@@ -14,27 +13,46 @@ import (
|
||||
"golang.org/x/mod/sumdb/dirhash"
|
||||
)
|
||||
|
||||
type testCaseInit struct {
|
||||
checkSkip func(*testing.T)
|
||||
name string
|
||||
Meta Meta
|
||||
inPluginFolder map[string]string
|
||||
expectedPackerConfigDirHashBeforeInit string
|
||||
inConfigFolder map[string]string
|
||||
packerConfigDir string
|
||||
packerUserFolder string
|
||||
want int
|
||||
dirFiles []string
|
||||
expectedPackerConfigDirHashAfterInit string
|
||||
moreTests []func(*testing.T, testCaseInit)
|
||||
}
|
||||
|
||||
type testBuild struct {
|
||||
want int
|
||||
}
|
||||
|
||||
func (tb testBuild) fn(t *testing.T, tc testCaseInit) {
|
||||
bc := BuildCommand{
|
||||
Meta: tc.Meta,
|
||||
}
|
||||
|
||||
args := []string{tc.packerUserFolder}
|
||||
want := tb.want
|
||||
if got := bc.Run(args); got != want {
|
||||
t.Errorf("BuildCommand.Run() = %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitCommand_Run(t *testing.T) {
|
||||
// These tests will try to optimise for doing the least amount of github api
|
||||
// requests whilst testing the max amount of things at once. Hopefully they
|
||||
// don't require a GH token just yet. Acc tests are run on linux, darwin and
|
||||
// windows, so requests are done 3 times.
|
||||
|
||||
type testCase struct {
|
||||
checkSkip func(*testing.T)
|
||||
name string
|
||||
inPluginFolder map[string]string
|
||||
expectedPackerConfigDirHashBeforeInit string
|
||||
hclFile string
|
||||
packerConfigDir string
|
||||
want int
|
||||
dirFiles []string
|
||||
expectedPackerConfigDirHashAfterInit string
|
||||
}
|
||||
|
||||
cfg := &configDirSingleton{map[string]string{}}
|
||||
|
||||
tests := []testCase{
|
||||
tests := []testCaseInit{
|
||||
{
|
||||
nil,
|
||||
// here we pre-write plugins with valid checksums, Packer will
|
||||
@@ -43,6 +61,7 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
// that's a no-op. This also should do no GH query, so it is best
|
||||
// to always run it.
|
||||
"already-installed-no-op",
|
||||
testMetaFile(t),
|
||||
map[string]string{
|
||||
"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64": "1",
|
||||
"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM": "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
|
||||
@@ -52,19 +71,27 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM": "59031c50e0dfeedfde2b4e9445754804dce3f29e4efa737eead0ca9b4f5b85a5",
|
||||
},
|
||||
"h1:Q5qyAOdD43hL3CquQdVfaHpOYGf0UsZ/+wVA9Ry6cbA=",
|
||||
`# cfg.pkr.hcl
|
||||
packer {
|
||||
required_plugins {
|
||||
comment = {
|
||||
source = "github.com/sylviamoss/comment"
|
||||
version = "v0.2.018"
|
||||
}
|
||||
}
|
||||
}`,
|
||||
cfg.dir("1"),
|
||||
map[string]string{
|
||||
`cfg.pkr.hcl`: `
|
||||
packer {
|
||||
required_plugins {
|
||||
comment = {
|
||||
source = "github.com/sylviamoss/comment"
|
||||
version = "v0.2.018"
|
||||
}
|
||||
}
|
||||
}`,
|
||||
},
|
||||
cfg.dir("1_pkr_config"),
|
||||
cfg.dir("1_pkr_user_folder"),
|
||||
0,
|
||||
nil,
|
||||
"h1:Q5qyAOdD43hL3CquQdVfaHpOYGf0UsZ/+wVA9Ry6cbA=",
|
||||
[]func(t *testing.T, tc testCaseInit){
|
||||
// test that a build will not work since plugins are broken for
|
||||
// this tests (they are not binaries).
|
||||
testBuild{want: 1}.fn,
|
||||
},
|
||||
},
|
||||
{
|
||||
func(t *testing.T) {
|
||||
@@ -76,6 +103,7 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
// see those as valid installations it did.
|
||||
// But because we require version 0.2.19, we will upgrade.
|
||||
"already-installed-upgrade",
|
||||
testMetaFile(t),
|
||||
map[string]string{
|
||||
"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64": "1",
|
||||
"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64_SHA256SUM": "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b",
|
||||
@@ -85,16 +113,34 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_linux_amd64_SHA256SUM": "59031c50e0dfeedfde2b4e9445754804dce3f29e4efa737eead0ca9b4f5b85a5",
|
||||
},
|
||||
"h1:Q5qyAOdD43hL3CquQdVfaHpOYGf0UsZ/+wVA9Ry6cbA=",
|
||||
`# cfg.pkr.hcl
|
||||
packer {
|
||||
required_plugins {
|
||||
comment = {
|
||||
source = "github.com/sylviamoss/comment"
|
||||
version = "v0.2.019"
|
||||
map[string]string{
|
||||
`cfg.pkr.hcl`: `
|
||||
packer {
|
||||
required_plugins {
|
||||
comment = {
|
||||
source = "github.com/sylviamoss/comment"
|
||||
version = "v0.2.019"
|
||||
}
|
||||
}
|
||||
}`,
|
||||
`source.pkr.hcl`: `
|
||||
source "null" "test" {
|
||||
communicator = "none"
|
||||
}
|
||||
`,
|
||||
`build.pkr.hcl`: `
|
||||
build {
|
||||
sources = ["source.null.test"]
|
||||
provisioner "comment" {
|
||||
comment = "Begin ¡"
|
||||
ui = true
|
||||
bubble_text = true
|
||||
}
|
||||
}
|
||||
}`,
|
||||
cfg.dir("2"),
|
||||
`,
|
||||
},
|
||||
cfg.dir("2_pkr_config"),
|
||||
cfg.dir("2_pkr_user_folder"),
|
||||
0,
|
||||
[]string{
|
||||
"github.com/sylviamoss/comment/packer-plugin-comment_v0.2.18_x5.0_darwin_amd64",
|
||||
@@ -119,6 +165,10 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
"linux": "h1:CGym0+Nd0LEANgzqL0wx/LDjRL8bYwlpZ0HajPJo/hs=",
|
||||
"windows": "h1:ag0/C1YjP7KoEDYOiJHE0K+lhFgs0tVgjriWCXVT1fg=",
|
||||
}[runtime.GOOS],
|
||||
[]func(t *testing.T, tc testCaseInit){
|
||||
// test that a build will work as the plugin was just installed
|
||||
testBuild{want: 0}.fn,
|
||||
},
|
||||
},
|
||||
{
|
||||
func(t *testing.T) {
|
||||
@@ -127,21 +177,61 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
}
|
||||
},
|
||||
"release-with-no-binary",
|
||||
testMetaFile(t),
|
||||
nil,
|
||||
"h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
|
||||
`# cfg.pkr.hcl
|
||||
packer {
|
||||
required_plugins {
|
||||
comment = {
|
||||
source = "github.com/sylviamoss/comment"
|
||||
version = "v0.2.20"
|
||||
}
|
||||
}
|
||||
}`,
|
||||
cfg.dir("3"),
|
||||
map[string]string{
|
||||
`cfg.pkr.hcl`: `
|
||||
packer {
|
||||
required_plugins {
|
||||
comment = {
|
||||
source = "github.com/sylviamoss/comment"
|
||||
version = "v0.2.20"
|
||||
}
|
||||
}
|
||||
}`,
|
||||
},
|
||||
cfg.dir("3_pkr_config"),
|
||||
cfg.dir("3_pkr_user_folder"),
|
||||
1,
|
||||
nil,
|
||||
"h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
|
||||
nil,
|
||||
},
|
||||
{
|
||||
func(t *testing.T) {
|
||||
if os.Getenv(acctest.TestEnvVar) == "" {
|
||||
t.Skipf("Acceptance test skipped unless env '%s' set", acctest.TestEnvVar)
|
||||
}
|
||||
tc := testCaseInit{}
|
||||
if err := getBinary(getBinaryOptions{
|
||||
GetZip: "https://github.com/azr/packer-provisioner-comment/releases/download/v1.0.0/packer-provisioner-comment_v1.0.0_" + runtime.GOOS + "_" + runtime.GOARCH + ".tar.gz",
|
||||
UnzipIn: tc.inPluginFolder,
|
||||
}); err != nil {
|
||||
t.Fatal("getBinary: %v", err)
|
||||
}
|
||||
},
|
||||
"release-with-no-binary",
|
||||
testMetaFile(t),
|
||||
nil,
|
||||
"h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
|
||||
map[string]string{
|
||||
`cfg.pkr.hcl`: `
|
||||
packer {
|
||||
required_plugins {
|
||||
comment = {
|
||||
source = "github.com/sylviamoss/comment"
|
||||
version = "v0.2.20"
|
||||
}
|
||||
}
|
||||
}`,
|
||||
},
|
||||
cfg.dir("3_pkr_config"),
|
||||
cfg.dir("3_pkr_user_folder"),
|
||||
1,
|
||||
nil,
|
||||
"h1:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=",
|
||||
nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -157,6 +247,10 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
_ = os.RemoveAll(tt.packerConfigDir)
|
||||
})
|
||||
createFiles(tt.packerUserFolder, tt.inConfigFolder)
|
||||
t.Cleanup(func() {
|
||||
_ = os.RemoveAll(tt.packerUserFolder)
|
||||
})
|
||||
|
||||
hash, err := dirhash.HashDir(tt.packerConfigDir, "", dirhash.DefaultHash)
|
||||
if err != nil {
|
||||
@@ -166,21 +260,10 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
t.Errorf("unexpected dir hash before init: %s", diff)
|
||||
}
|
||||
|
||||
cfgDir, err := ioutil.TempDir("", "pkr-test-init-file-folder")
|
||||
if err != nil {
|
||||
t.Fatalf("TempDir: %v", err)
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(cfgDir, "cfg.pkr.hcl"), []byte(tt.hclFile), 0666); err != nil {
|
||||
t.Fatalf("WriteFile: %v", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
_ = os.RemoveAll(cfgDir)
|
||||
})
|
||||
|
||||
args := []string{cfgDir}
|
||||
args := []string{tt.packerUserFolder}
|
||||
|
||||
c := &InitCommand{
|
||||
Meta: testMetaFile(t),
|
||||
Meta: tt.Meta,
|
||||
}
|
||||
|
||||
c.CoreConfig.Components.PluginConfig.KnownPluginFolders = []string{tt.packerConfigDir}
|
||||
@@ -207,6 +290,12 @@ func TestInitCommand_Run(t *testing.T) {
|
||||
if diff := cmp.Diff(tt.expectedPackerConfigDirHashAfterInit, hash); diff != "" {
|
||||
t.Errorf("unexpected dir hash after init: %s", diff)
|
||||
}
|
||||
|
||||
for i, subTest := range tt.moreTests {
|
||||
t.Run(fmt.Sprintf("-subtest-%d", i), func(t *testing.T) {
|
||||
subTest(t, tt)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+47
-2
@@ -47,13 +47,36 @@ variable "secret_account" {
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
# "timestamp" template function replacement
|
||||
locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }
|
||||
# The amazon-secretsmanager data block is generated from your aws_secretsmanager template function; a data
|
||||
# from this block can be referenced in source and locals blocks.
|
||||
# Read the documentation for data blocks here:
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/data
|
||||
# Read the documentation for the Amazon Secrets Manager Data Source here:
|
||||
# https://www.packer.io/docs/datasources/amazon/secretsmanager
|
||||
data "amazon-secretsmanager" "autogenerated_1" {
|
||||
name = "sample/app/password"
|
||||
}
|
||||
|
||||
data "amazon-secretsmanager" "autogenerated_2" {
|
||||
key = "api_key"
|
||||
name = "sample/app/passwords"
|
||||
}
|
||||
|
||||
data "amazon-secretsmanager" "autogenerated_3" {
|
||||
name = "some_secret"
|
||||
}
|
||||
|
||||
data "amazon-secretsmanager" "autogenerated_4" {
|
||||
key = "with_key"
|
||||
name = "some_secret"
|
||||
}
|
||||
|
||||
# The amazon-ami data block is generated from your amazon builder source_ami_filter; a data
|
||||
# from this block can be referenced in source and locals blocks.
|
||||
# Read the documentation for data blocks here:
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/data
|
||||
# Read the documentation for the Amazon AMI Data Source here:
|
||||
# https://www.packer.io/docs/datasources/amazon/ami
|
||||
data "amazon-ami" "autogenerated_1" {
|
||||
filters = {
|
||||
name = "ubuntu/images/*/ubuntu-xenial-16.04-amd64-server-*"
|
||||
@@ -64,6 +87,22 @@ data "amazon-ami" "autogenerated_1" {
|
||||
owners = ["099720109477"]
|
||||
}
|
||||
|
||||
# "timestamp" template function replacement
|
||||
locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }
|
||||
|
||||
# All locals variables are generated from variables that uses expressions
|
||||
# that are not allowed in HCL2 variables.
|
||||
# Read the documentation for locals blocks here:
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/locals
|
||||
local "password" {
|
||||
sensitive = true
|
||||
expression = "${data.amazon-secretsmanager.autogenerated_1.value}"
|
||||
}
|
||||
|
||||
locals {
|
||||
password_key = "MY_KEY_${data.amazon-secretsmanager.autogenerated_2.value}"
|
||||
}
|
||||
|
||||
# source blocks are generated from your builders; a source can be referenced in
|
||||
# build blocks. A build block runs provisioner and post-processors on a
|
||||
# source. Read the documentation for source blocks here:
|
||||
@@ -135,6 +174,12 @@ build {
|
||||
inline = ["echo ${var.secret_account}", "echo ${build.ID}", "echo ${build.SSHPublicKey} | head -c 14", "echo ${path.root} is not ${path.cwd}", "echo ${packer.version}", "echo ${uuidv4()}"]
|
||||
max_retries = "5"
|
||||
}
|
||||
provisioner "shell" {
|
||||
inline = ["echo ${local.password}", "echo ${data.amazon-secretsmanager.autogenerated_1.value}", "echo ${local.password_key}", "echo ${data.amazon-secretsmanager.autogenerated_2.value}"]
|
||||
}
|
||||
provisioner "shell" {
|
||||
inline = ["echo ${data.amazon-secretsmanager.autogenerated_3.value}", "echo ${data.amazon-secretsmanager.autogenerated_4.value}"]
|
||||
}
|
||||
|
||||
# template: hcl2_upgrade:2:38: executing "hcl2_upgrade" at <clean_resource_name>: error calling clean_resource_name: unhandled "clean_resource_name" call:
|
||||
# there is no way to automatically upgrade the "clean_resource_name" call.
|
||||
+21
-2
@@ -5,13 +5,16 @@
|
||||
"aws_region": null,
|
||||
"aws_secondary_region": "{{ env `AWS_DEFAULT_REGION` }}",
|
||||
"aws_secret_key": "",
|
||||
"aws_access_key": ""
|
||||
"aws_access_key": "",
|
||||
"password": "{{ aws_secretsmanager `sample/app/password` }}",
|
||||
"password_key": "MY_KEY_{{ aws_secretsmanager `sample/app/passwords` `api_key` }}"
|
||||
},
|
||||
"sensitive-variables": [
|
||||
"aws_secret_key",
|
||||
"aws_access_key",
|
||||
"secret_account",
|
||||
"potato"
|
||||
"potato",
|
||||
"password"
|
||||
],
|
||||
"builders": [
|
||||
{
|
||||
@@ -128,6 +131,22 @@
|
||||
"echo {{ uuid }}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"echo {{ user `password` }}",
|
||||
"echo {{ aws_secretsmanager `sample/app/password` }}",
|
||||
"echo {{ user `password_key` }}",
|
||||
"echo {{ aws_secretsmanager `sample/app/passwords` `api_key` }}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
"echo {{ aws_secretsmanager `some_secret` }}",
|
||||
"echo {{ aws_secretsmanager `some_secret` `with_key` }}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"inline": [
|
||||
@@ -0,0 +1,78 @@
|
||||
# This file was autogenerated by the 'packer hcl2_upgrade' command. We
|
||||
# recommend double checking that everything is correct before going forward. We
|
||||
# also recommend treating this file as disposable. The HCL2 blocks in this
|
||||
# file can be moved to other files. For example, the variable blocks could be
|
||||
# moved to their own 'variables.pkr.hcl' file, etc. Those files need to be
|
||||
# suffixed with '.pkr.hcl' to be visible to Packer. To use multiple files at
|
||||
# once they also need to be in the same folder. 'packer inspect folder/'
|
||||
# will describe to you what is in that folder.
|
||||
|
||||
# Avoid mixing go templating calls ( for example ```{{ upper(`string`) }}``` )
|
||||
# and HCL2 calls (for example '${ var.string_value_example }' ). They won't be
|
||||
# executed together and the outcome will be unknown.
|
||||
|
||||
# See https://www.packer.io/docs/templates/hcl_templates/blocks/packer for more info
|
||||
packer {
|
||||
required_version = ">= 1.6.0"
|
||||
}
|
||||
|
||||
# All generated input variables will be of 'string' type as this is how Packer JSON
|
||||
# views them; you can change their type later on. Read the variables type
|
||||
# constraints documentation
|
||||
# https://www.packer.io/docs/templates/hcl_templates/variables#type-constraints for more info.
|
||||
variable "aws_access_key" {
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "aws_region" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "aws_secret_key" {
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
# "timestamp" template function replacement
|
||||
locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }
|
||||
|
||||
# source blocks are generated from your builders; a source can be referenced in
|
||||
# build blocks. A build block runs provisioner and post-processors on a
|
||||
# source. Read the documentation for source blocks here:
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/source
|
||||
source "amazon-ebs" "autogenerated_1" {
|
||||
access_key = "${var.aws_access_key}"
|
||||
ami_description = "Ubuntu 16.04 LTS - expand root partition"
|
||||
ami_name = "ubuntu-16-04-test-${local.timestamp}"
|
||||
encrypt_boot = true
|
||||
launch_block_device_mappings {
|
||||
delete_on_termination = true
|
||||
device_name = "/dev/sda1"
|
||||
volume_size = 48
|
||||
volume_type = "gp2"
|
||||
}
|
||||
region = "${var.aws_region}"
|
||||
secret_key = "${var.aws_secret_key}"
|
||||
source_ami = "ami1234567"
|
||||
spot_instance_types = ["t2.small", "t2.medium", "t2.large"]
|
||||
spot_price = "0.0075"
|
||||
ssh_interface = "session_manager"
|
||||
ssh_username = "ubuntu"
|
||||
temporary_iam_instance_profile_policy_document {
|
||||
Statement {
|
||||
Action = ["*"]
|
||||
Effect = "Allow"
|
||||
Resource = ["*"]
|
||||
}
|
||||
Version = "2012-10-17"
|
||||
}
|
||||
}
|
||||
|
||||
# a build block invokes sources and runs provisioning steps on them. The
|
||||
# documentation for build blocks can be found here:
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/build
|
||||
build {
|
||||
sources = ["source.amazon-ebs.autogenerated_1"]
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"min_packer_version": "1.6.0",
|
||||
"variables": {
|
||||
"aws_region": null,
|
||||
"aws_secret_key": "",
|
||||
"aws_access_key": ""
|
||||
},
|
||||
"builders": [
|
||||
{
|
||||
"type": "amazon-ebs",
|
||||
"region": "{{ user `aws_region` }}",
|
||||
"secret_key": "{{ user `aws_secret_key` }}",
|
||||
"access_key": "{{ user `aws_access_key` }}",
|
||||
"ami_name": "ubuntu-16-04-test-{{ timestamp }}",
|
||||
"ami_description": "Ubuntu 16.04 LTS - expand root partition",
|
||||
"source_ami": "ami1234567",
|
||||
"launch_block_device_mappings": [
|
||||
{
|
||||
"delete_on_termination": true,
|
||||
"device_name": "/dev/sda1",
|
||||
"volume_type": "gp2",
|
||||
"volume_size": 48
|
||||
}
|
||||
],
|
||||
"spot_price": "0.0075",
|
||||
"spot_instance_types": [
|
||||
"t2.small",
|
||||
"t2.medium",
|
||||
"t2.large"
|
||||
],
|
||||
"encrypt_boot": true,
|
||||
"ssh_username": "ubuntu",
|
||||
"temporary_iam_instance_profile_policy_document": {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"*"
|
||||
],
|
||||
"Resource": ["*"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ssh_interface": "session_manager"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
# This file was autogenerated by the 'packer hcl2_upgrade' command. We
|
||||
# recommend double checking that everything is correct before going forward. We
|
||||
# also recommend treating this file as disposable. The HCL2 blocks in this
|
||||
# file can be moved to other files. For example, the variable blocks could be
|
||||
# moved to their own 'variables.pkr.hcl' file, etc. Those files need to be
|
||||
# suffixed with '.pkr.hcl' to be visible to Packer. To use multiple files at
|
||||
# once they also need to be in the same folder. 'packer inspect folder/'
|
||||
# will describe to you what is in that folder.
|
||||
|
||||
# Avoid mixing go templating calls ( for example ```{{ upper(`string`) }}``` )
|
||||
# and HCL2 calls (for example '${ var.string_value_example }' ). They won't be
|
||||
# executed together and the outcome will be unknown.
|
||||
|
||||
# See https://www.packer.io/docs/templates/hcl_templates/blocks/packer for more info
|
||||
packer {
|
||||
required_version = ">= 1.6.0"
|
||||
}
|
||||
|
||||
# All generated input variables will be of 'string' type as this is how Packer JSON
|
||||
# views them; you can change their type later on. Read the variables type
|
||||
# constraints documentation
|
||||
# https://www.packer.io/docs/templates/hcl_templates/variables#type-constraints for more info.
|
||||
variable "aws_access_key" {
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "aws_region" {
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "aws_secret_key" {
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
# "timestamp" template function replacement
|
||||
locals { timestamp = regex_replace(timestamp(), "[- TZ:]", "") }
|
||||
|
||||
# source blocks are generated from your builders; a source can be referenced in
|
||||
# build blocks. A build block runs provisioner and post-processors on a
|
||||
# source. Read the documentation for source blocks here:
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/source
|
||||
source "amazon-ebs" "party_parrot" {
|
||||
access_key = "${var.aws_access_key}"
|
||||
ami_description = "Ubuntu 16.04 LTS - expand root partition"
|
||||
ami_name = "ubuntu-16-04-test-${local.timestamp}"
|
||||
encrypt_boot = true
|
||||
launch_block_device_mappings {
|
||||
delete_on_termination = true
|
||||
device_name = "/dev/sda1"
|
||||
volume_size = 48
|
||||
volume_type = "gp2"
|
||||
}
|
||||
region = "${var.aws_region}"
|
||||
secret_key = "${var.aws_secret_key}"
|
||||
source_ami = "ami1234567"
|
||||
spot_instance_types = ["t2.small", "t2.medium", "t2.large"]
|
||||
spot_price = "0.0075"
|
||||
ssh_interface = "session_manager"
|
||||
ssh_username = "ubuntu"
|
||||
temporary_iam_instance_profile_policy_document {
|
||||
Statement {
|
||||
Action = ["*"]
|
||||
Effect = "Allow"
|
||||
Resource = ["*"]
|
||||
}
|
||||
Version = "2012-10-17"
|
||||
}
|
||||
}
|
||||
|
||||
# a build block invokes sources and runs provisioning steps on them. The
|
||||
# documentation for build blocks can be found here:
|
||||
# https://www.packer.io/docs/templates/hcl_templates/blocks/build
|
||||
build {
|
||||
sources = ["source.amazon-ebs.party_parrot"]
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"min_packer_version": "1.6.0",
|
||||
"variables": {
|
||||
"aws_region": null,
|
||||
"aws_secret_key": "",
|
||||
"aws_access_key": ""
|
||||
},
|
||||
"builders": [
|
||||
{
|
||||
"type": "amazon-ebs",
|
||||
"name": " party parrot ",
|
||||
"region": "{{ user `aws_region` }}",
|
||||
"secret_key": "{{ user `aws_secret_key` }}",
|
||||
"access_key": "{{ user `aws_access_key` }}",
|
||||
"ami_name": "ubuntu-16-04-test-{{ timestamp }}",
|
||||
"ami_description": "Ubuntu 16.04 LTS - expand root partition",
|
||||
"source_ami": "ami1234567",
|
||||
"launch_block_device_mappings": [
|
||||
{
|
||||
"delete_on_termination": true,
|
||||
"device_name": "/dev/sda1",
|
||||
"volume_type": "gp2",
|
||||
"volume_size": 48
|
||||
}
|
||||
],
|
||||
"spot_price": "0.0075",
|
||||
"spot_instance_types": [
|
||||
"t2.small",
|
||||
"t2.medium",
|
||||
"t2.large"
|
||||
],
|
||||
"encrypt_boot": true,
|
||||
"ssh_username": "ubuntu",
|
||||
"temporary_iam_instance_profile_policy_document": {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"*"
|
||||
],
|
||||
"Resource": ["*"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ssh_interface": "session_manager"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -100,6 +100,4 @@ require (
|
||||
google.golang.org/grpc v1.32.0
|
||||
)
|
||||
|
||||
// replace github.com/hashicorp/packer-plugin-sdk => /Users/azr/go/src/github.com/hashicorp/packer-plugin-sdk
|
||||
|
||||
go 1.13
|
||||
|
||||
@@ -530,6 +530,7 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZX
|
||||
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI=
|
||||
github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4=
|
||||
github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
|
||||
@@ -97,7 +97,8 @@ func (cfg *PackerConfig) detectPluginBinaries() hcl.Diagnostics {
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: fmt.Sprintf("Failed to discover plugin %s", pluginRequirement.Identifier.ForDisplay()),
|
||||
Summary: fmt.Sprintf("Error discovering plugin %s", pluginRequirement.Identifier.ForDisplay()),
|
||||
Detail: err.Error(),
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -59,9 +59,10 @@ func (cfg *PackerConfig) startPostProcessor(source SourceUseBlock, pp *PostProce
|
||||
postProcessor, err := cfg.parser.PluginConfig.PostProcessors.Start(pp.PType)
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: fmt.Sprintf("Failed loading %s", pp.PType),
|
||||
Subject: pp.DefRange.Ptr(),
|
||||
Detail: err.Error(),
|
||||
Severity: hcl.DiagError,
|
||||
Summary: fmt.Sprintf("Failed loading %s", pp.PType),
|
||||
Subject: pp.DefRange.Ptr(),
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
@@ -146,9 +146,10 @@ func (cfg *PackerConfig) startProvisioner(source SourceUseBlock, pb *Provisioner
|
||||
provisioner, err := cfg.parser.PluginConfig.Provisioners.Start(pb.PType)
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: fmt.Sprintf("failed loading %s", pb.PType),
|
||||
Subject: pb.HCL2Ref.LabelsRanges[0].Ptr(),
|
||||
Detail: err.Error(),
|
||||
Severity: hcl.DiagError,
|
||||
Summary: fmt.Sprintf("failed loading %s", pb.PType),
|
||||
Subject: pb.HCL2Ref.LabelsRanges[0].Ptr(),
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return nil, diags
|
||||
}
|
||||
|
||||
@@ -101,8 +101,9 @@ func (cfg *PackerConfig) startBuilder(source SourceUseBlock, ectx *hcl.EvalConte
|
||||
builder, err := cfg.parser.PluginConfig.Builders.Start(source.Type)
|
||||
if err != nil {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Summary: "Failed to load " + sourceLabel + " type",
|
||||
Detail: err.Error(),
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Failed to load " + sourceLabel + " type",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return builder, diags, nil
|
||||
}
|
||||
|
||||
@@ -8,33 +8,6 @@
|
||||
},
|
||||
{
|
||||
"pattern": "^https://www.linode.com"
|
||||
},
|
||||
{
|
||||
"pattern": "^https://github.com/hashicorp/packer-plugin-scaffolding"
|
||||
},
|
||||
{
|
||||
"pattern": "^https://www.packer.io/docs/templates/hcl_templates/"
|
||||
},
|
||||
{
|
||||
"pattern": "^https://packer.io/docs/templates/hcl_templates/"
|
||||
},
|
||||
{
|
||||
"pattern": "^/docs/templates/hcl_templates/"
|
||||
},
|
||||
{
|
||||
"pattern": "^/commands/init"
|
||||
},
|
||||
{
|
||||
"pattern": "^/docs/datasources"
|
||||
},
|
||||
{
|
||||
"pattern": "^/docs/extending/custom-datasources"
|
||||
},
|
||||
{
|
||||
"pattern": "^/docs/templates/legacy_json_templates"
|
||||
},
|
||||
{
|
||||
"pattern": "^https://packer.io/docs/templates/legacy_json_templates"
|
||||
}
|
||||
],
|
||||
"replacementPatterns": [
|
||||
|
||||
+13
-4
@@ -121,7 +121,9 @@ func (c *PluginConfig) discoverExternalComponents(path string) error {
|
||||
}
|
||||
for pluginName, pluginPath := range pluginPaths {
|
||||
newPath := pluginPath // this needs to be stored in a new variable for the func below
|
||||
c.Builders.Set(pluginName, c.Client(newPath).Builder)
|
||||
c.Builders.Set(pluginName, func() (packersdk.Builder, error) {
|
||||
return c.Client(newPath).Builder()
|
||||
})
|
||||
externallyUsed = append(externallyUsed, pluginName)
|
||||
}
|
||||
if len(externallyUsed) > 0 {
|
||||
@@ -136,7 +138,9 @@ func (c *PluginConfig) discoverExternalComponents(path string) error {
|
||||
}
|
||||
for pluginName, pluginPath := range pluginPaths {
|
||||
newPath := pluginPath // this needs to be stored in a new variable for the func below
|
||||
c.PostProcessors.Set(pluginName, c.Client(newPath).PostProcessor)
|
||||
c.PostProcessors.Set(pluginName, func() (packersdk.PostProcessor, error) {
|
||||
return c.Client(newPath).PostProcessor()
|
||||
})
|
||||
externallyUsed = append(externallyUsed, pluginName)
|
||||
}
|
||||
if len(externallyUsed) > 0 {
|
||||
@@ -151,12 +155,15 @@ func (c *PluginConfig) discoverExternalComponents(path string) error {
|
||||
}
|
||||
for pluginName, pluginPath := range pluginPaths {
|
||||
newPath := pluginPath // this needs to be stored in a new variable for the func below
|
||||
c.Provisioners.Set(pluginName, c.Client(newPath).Provisioner)
|
||||
c.Provisioners.Set(pluginName, func() (packersdk.Provisioner, error) {
|
||||
return c.Client(newPath).Provisioner()
|
||||
})
|
||||
externallyUsed = append(externallyUsed, pluginName)
|
||||
}
|
||||
if len(externallyUsed) > 0 {
|
||||
sort.Strings(externallyUsed)
|
||||
log.Printf("using external provisioners %v", externallyUsed)
|
||||
externallyUsed = nil
|
||||
}
|
||||
|
||||
pluginPaths, err = c.discoverSingle(filepath.Join(path, "packer-datasource-*"))
|
||||
@@ -165,7 +172,9 @@ func (c *PluginConfig) discoverExternalComponents(path string) error {
|
||||
}
|
||||
for pluginName, pluginPath := range pluginPaths {
|
||||
newPath := pluginPath // this needs to be stored in a new variable for the func below
|
||||
c.DataSources.Set(pluginName, c.Client(newPath).Datasource)
|
||||
c.DataSources.Set(pluginName, func() (packersdk.Datasource, error) {
|
||||
return c.Client(newPath).Datasource()
|
||||
})
|
||||
externallyUsed = append(externallyUsed, pluginName)
|
||||
}
|
||||
if len(externallyUsed) > 0 {
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Alicloud ECS
|
||||
# Alicloud Image Builder
|
||||
|
||||
Type: `alicloud-ecs`
|
||||
Artifact BuilderId: `alibaba.alicloud`
|
||||
|
||||
The `alicloud-ecs` Packer builder plugin provide the capability to build
|
||||
customized images based on an existing base images.
|
||||
@@ -17,7 +18,7 @@ customized images based on an existing base images.
|
||||
|
||||
The following configuration options are available for building Alicloud images.
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Required:
|
||||
|
||||
@@ -15,6 +15,7 @@ sidebar_title: chroot
|
||||
# AMI Builder (chroot)
|
||||
|
||||
Type: `amazon-chroot`
|
||||
Artifact BuilderId: `mitchellh.amazon.chroot`
|
||||
|
||||
The `amazon-chroot` Packer builder is able to create Amazon AMIs backed by an
|
||||
EBS volume as the root device. For more information on the difference between
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: EBS
|
||||
# AMI Builder (EBS backed)
|
||||
|
||||
Type: `amazon-ebs`
|
||||
Artifact BuilderId: `mitchellh.amazonebs`
|
||||
|
||||
The `amazon-ebs` Packer builder is able to create Amazon AMIs backed by EBS
|
||||
volumes for use in [EC2](https://aws.amazon.com/ec2/). For more information on
|
||||
@@ -90,6 +91,64 @@ necessary for this build to succeed and can be found further down the page.
|
||||
|
||||
@include 'builder/amazon/common/RunConfig-not-required.mdx'
|
||||
|
||||
#### Metadata Settings
|
||||
|
||||
@include 'builder/amazon/common/MetadataOptions.mdx'
|
||||
|
||||
@include 'builder/amazon/common/MetadataOptions-not-required.mdx'
|
||||
|
||||
Usage Example
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="HCL2">
|
||||
|
||||
```hcl
|
||||
source "amazon-ebs" "basic-example" {
|
||||
region = "us-east-1"
|
||||
source_ami = "ami-fce3c696"
|
||||
instance_type = "t2.micro"
|
||||
ssh_username = "ubuntu"
|
||||
ami_name = "packer_AWS_example_{{timestamp}}"
|
||||
metadata_options {
|
||||
http_endpoint = "enabled"
|
||||
http_tokens = "required"
|
||||
http_put_response_hop_limit = 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="JSON">
|
||||
|
||||
```json
|
||||
{
|
||||
"variables": {
|
||||
"aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
|
||||
"aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}"
|
||||
},
|
||||
"builders": [
|
||||
{
|
||||
"type": "amazon-ebs",
|
||||
"access_key": "{{user `aws_access_key`}}",
|
||||
"secret_key": "{{user `aws_secret_key`}}",
|
||||
"region": "us-east-1",
|
||||
"source_ami": "ami-fce3c696",
|
||||
"instance_type": "t2.micro",
|
||||
"ssh_username": "ubuntu",
|
||||
"ami_name": "packer_AWS {{timestamp}}",
|
||||
"metadata_options": {
|
||||
"http_endpoint": "enabled",
|
||||
"http_tokens": "required",
|
||||
"http_put_response_hop_limit": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@include 'builders/aws-session-manager.mdx'
|
||||
|
||||
### Block Devices Configuration
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: EBS Surrogate
|
||||
# EBS Surrogate Builder
|
||||
|
||||
Type: `amazon-ebssurrogate`
|
||||
Artifact BuilderId: `mitchellh.amazon.ebssurrogate`
|
||||
|
||||
The `amazon-ebssurrogate` Packer builder is able to create Amazon AMIs by
|
||||
running a source instance with an attached volume, provisioning the attached
|
||||
@@ -86,6 +87,64 @@ necessary for this build to succeed and can be found further down the page.
|
||||
|
||||
@include 'builder/amazon/common/RunConfig-not-required.mdx'
|
||||
|
||||
#### Metadata Settings
|
||||
|
||||
@include 'builder/amazon/common/MetadataOptions.mdx'
|
||||
|
||||
@include 'builder/amazon/common/MetadataOptions-not-required.mdx'
|
||||
|
||||
Usage Example
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="HCL2">
|
||||
|
||||
```hcl
|
||||
source "amazon-ebs" "basic-example" {
|
||||
region = "us-east-1"
|
||||
source_ami = "ami-fce3c696"
|
||||
instance_type = "t2.micro"
|
||||
ssh_username = "ubuntu"
|
||||
ami_name = "packer_AWS_example_{{timestamp}}"
|
||||
metadata_options {
|
||||
http_endpoint = "enabled"
|
||||
http_tokens = "required"
|
||||
http_put_response_hop_limit = 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="JSON">
|
||||
|
||||
```json
|
||||
{
|
||||
"variables": {
|
||||
"aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
|
||||
"aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}"
|
||||
},
|
||||
"builders": [
|
||||
{
|
||||
"type": "amazon-ebs",
|
||||
"access_key": "{{user `aws_access_key`}}",
|
||||
"secret_key": "{{user `aws_secret_key`}}",
|
||||
"region": "us-east-1",
|
||||
"source_ami": "ami-fce3c696",
|
||||
"instance_type": "t2.micro",
|
||||
"ssh_username": "ubuntu",
|
||||
"ami_name": "packer_AWS {{timestamp}}",
|
||||
"metadata_options": {
|
||||
"http_endpoint": "enabled",
|
||||
"http_tokens": "required",
|
||||
"http_put_response_hop_limit": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@include 'builders/aws-session-manager.mdx'
|
||||
|
||||
### Block Devices Configuration
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: EBS Volume
|
||||
# EBS Volume Builder
|
||||
|
||||
Type: `amazon-ebsvolume`
|
||||
Artifact BuilderId: `mitchellh.amazon.ebsvolume`
|
||||
|
||||
The `amazon-ebsvolume` Packer builder is able to create Amazon Elastic Block
|
||||
Store volumes which are prepopulated with filesystems or data.
|
||||
@@ -105,6 +106,64 @@ Block devices can be nested in the
|
||||
|
||||
@include 'builder/amazon/common/RunConfig-not-required.mdx'
|
||||
|
||||
#### Metadata Settings
|
||||
|
||||
@include 'builder/amazon/common/MetadataOptions.mdx'
|
||||
|
||||
@include 'builder/amazon/common/MetadataOptions-not-required.mdx'
|
||||
|
||||
Usage Example
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="HCL2">
|
||||
|
||||
```hcl
|
||||
source "amazon-ebs" "basic-example" {
|
||||
region = "us-east-1"
|
||||
source_ami = "ami-fce3c696"
|
||||
instance_type = "t2.micro"
|
||||
ssh_username = "ubuntu"
|
||||
ami_name = "packer_AWS_example_{{timestamp}}"
|
||||
metadata_options {
|
||||
http_endpoint = "enabled"
|
||||
http_tokens = "required"
|
||||
http_put_response_hop_limit = 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="JSON">
|
||||
|
||||
```json
|
||||
{
|
||||
"variables": {
|
||||
"aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
|
||||
"aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}"
|
||||
},
|
||||
"builders": [
|
||||
{
|
||||
"type": "amazon-ebs",
|
||||
"access_key": "{{user `aws_access_key`}}",
|
||||
"secret_key": "{{user `aws_secret_key`}}",
|
||||
"region": "us-east-1",
|
||||
"source_ami": "ami-fce3c696",
|
||||
"instance_type": "t2.micro",
|
||||
"ssh_username": "ubuntu",
|
||||
"ami_name": "packer_AWS {{timestamp}}",
|
||||
"metadata_options": {
|
||||
"http_endpoint": "enabled",
|
||||
"http_tokens": "required",
|
||||
"http_put_response_hop_limit": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@include 'builders/aws-session-manager.mdx'
|
||||
|
||||
### Communicator Configuration
|
||||
|
||||
@@ -15,6 +15,7 @@ sidebar_title: Instance
|
||||
# AMI Builder (instance-store)
|
||||
|
||||
Type: `amazon-instance`
|
||||
Artifact BuilderId: `mitchellh.amazon.instance`
|
||||
|
||||
The `amazon-instance` Packer builder is able to create Amazon AMIs backed by
|
||||
instance storage as the root device. For more information on the difference
|
||||
|
||||
@@ -7,6 +7,7 @@ sidebar_title: ARM
|
||||
# Azure Resource Manager Builder
|
||||
|
||||
Type: `azure-arm`
|
||||
Artifact BuilderId: `Azure.ResourceManagement.VMImage`
|
||||
|
||||
Packer supports building Virtual Hard Disks (VHDs) and Managed Images in [Azure Resource
|
||||
Manager](https://azure.microsoft.com/en-us/documentation/articles/resource-group-overview/).
|
||||
@@ -25,7 +26,7 @@ CLI](https://azure.microsoft.com/en-us/documentation/articles/xplat-cli-install/
|
||||
|
||||
There are many configuration options available for the builder. We'll start
|
||||
with authentication parameters, then go over the Azure ARM builder specific
|
||||
options. In addition to the options listed here, a [communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this builder.
|
||||
options. In addition to the options listed here, a [communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this builder.
|
||||
|
||||
### Authentication options
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: chroot
|
||||
# Azure Builder (chroot)
|
||||
|
||||
Type: `azure-chroot`
|
||||
Artifact BuilderId: `azure.chroot`
|
||||
|
||||
The `azure-chroot` builder is able to build Azure managed disk (MD) images. For
|
||||
more information on managed disks, see [Azure Managed Disks Overview](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/managed-disks-overview).
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: CloudStack
|
||||
# CloudStack Builder
|
||||
|
||||
Type: `cloudstack`
|
||||
Artifact BuilderId: `packer.cloudstack`
|
||||
|
||||
The `cloudstack` Packer builder is able to create new templates for use with
|
||||
[CloudStack](https://cloudstack.apache.org/). The builder takes either an ISO
|
||||
@@ -27,7 +28,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Required:
|
||||
|
||||
@@ -17,6 +17,7 @@ sidebar_title: DigitalOcean
|
||||
# DigitalOcean Builder
|
||||
|
||||
Type: `digitalocean`
|
||||
Artifact BuilderId: `pearkes.digitalocean`
|
||||
|
||||
The `digitalocean` Packer builder is able to create new images for use with
|
||||
[DigitalOcean](https://www.digitalocean.com). The builder takes a source image,
|
||||
@@ -36,7 +37,7 @@ each category, the available configuration keys are alphabetized.
|
||||
### Communicator Config
|
||||
|
||||
In addition to the builder options, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this builder.
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this builder.
|
||||
|
||||
@include 'packer-plugin-sdk/communicator/Config-not-required.mdx'
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ sidebar_title: Docker
|
||||
# Docker Builder
|
||||
|
||||
Type: `docker`
|
||||
Artifact BuilderId: `packer.docker`
|
||||
|
||||
The `docker` Packer builder builds [Docker](https://www.docker.io) images using
|
||||
Docker. The builder starts a Docker container, runs provisioners within this
|
||||
@@ -200,7 +201,7 @@ optional. Within each category, the available options are alphabetized and
|
||||
described.
|
||||
|
||||
The Docker builder uses a special Docker communicator _and will not use_ the
|
||||
standard [communicators](/docs/templates/legacy_json_templates/communicators).
|
||||
standard [communicators](/docs/templates/legacy_json_templates/communicator).
|
||||
|
||||
### Required:
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ sidebar_title: File
|
||||
# File Builder
|
||||
|
||||
Type: `file`
|
||||
Artifact BuilderId: `packer.file`
|
||||
|
||||
The `file` Packer builder is not really a builder, it just creates an artifact
|
||||
from a file. It can be used to debug post-processors without incurring high
|
||||
@@ -54,7 +55,7 @@ Configuration options are organized below into two categories: required and
|
||||
optional. Within each category, the available options are alphabetized and
|
||||
described.
|
||||
|
||||
Any [communicator](/docs/templates/legacy_json_templates/communicators) defined is ignored.
|
||||
Any [communicator](/docs/templates/legacy_json_templates/communicator) defined is ignored.
|
||||
|
||||
### Required:
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Google Cloud
|
||||
# Google Compute Builder
|
||||
|
||||
Type: `googlecompute`
|
||||
Artifact BuilderId: `packer.googlecompute`
|
||||
|
||||
The `googlecompute` Packer builder is able to create
|
||||
[images](https://developers.google.com/compute/docs/images) for use with
|
||||
@@ -342,7 +343,7 @@ optional. Within each category, the available options are alphabetized and
|
||||
described.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Communicator Configuration
|
||||
|
||||
@@ -12,6 +12,7 @@ sidebar_title: Hetzner Cloud
|
||||
# Hetzner Cloud Builder
|
||||
|
||||
Type: `hcloud`
|
||||
Artifact BuilderId: `hcloud.builder`
|
||||
|
||||
The `hcloud` Packer builder is able to create new images for use with [Hetzner
|
||||
Cloud](https://www.hetzner.cloud). The builder takes a source image, runs any
|
||||
@@ -29,7 +30,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Required Builder Configuration options:
|
||||
|
||||
@@ -10,6 +10,7 @@ sidebar_title: HyperOne
|
||||
# HyperOne Builder
|
||||
|
||||
Type: `hyperone`
|
||||
Artifact BuilderId: `hyperone.builder`
|
||||
|
||||
The `hyperone` Packer builder is able to create new images on the [HyperOne
|
||||
platform](http://www.hyperone.com/). The builder takes a source image, runs
|
||||
@@ -86,7 +87,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Required:
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: ISO
|
||||
# Hyper-V Builder (from an ISO)
|
||||
|
||||
Type: `hyperv-iso`
|
||||
Artifact BuilderId: `MSOpenTech.hyperv`
|
||||
|
||||
The Hyper-V Packer builder is able to create
|
||||
[Hyper-V](https://www.microsoft.com/en-us/server-cloud/solutions/virtualization.aspx)
|
||||
@@ -65,7 +66,7 @@ are organized below into two categories: required and optional. Within each
|
||||
category, the available options are alphabetized and described.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Optional:
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: VMCX
|
||||
# Hyper-V Builder (from a vmcx)
|
||||
|
||||
Type: `hyperv-vmcx`
|
||||
Artifact BuilderId: `MSOpenTech.hyperv`
|
||||
|
||||
The Hyper-V Packer builder is able to use exported virtual machines or clone
|
||||
existing
|
||||
@@ -66,7 +67,7 @@ are organized below into two categories: required and optional. Within each
|
||||
category, the available options are alphabetized and described.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
## ISO Configuration Reference
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: JDCloud
|
||||
# JDCloud Image Builder
|
||||
|
||||
Type: `jdcloud`
|
||||
Artifact BuilderId: `hashicorp.jdcloud`
|
||||
|
||||
The `jdcloud` Packer builder helps you to build instance images
|
||||
based on an existing image
|
||||
|
||||
@@ -17,6 +17,7 @@ sidebar_title: Linode
|
||||
# Linode Builder
|
||||
|
||||
Type: `linode`
|
||||
Artifact BuilderId: `packer.linode`
|
||||
|
||||
The `linode` Packer builder is able to create [Linode
|
||||
Images](https://www.linode.com/docs/platform/disk-images/linode-images/) for
|
||||
@@ -35,7 +36,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder. In addition to the options defined there, a private key file
|
||||
can also be supplied to override the typical auto-generated key:
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ sidebar_title: LXC
|
||||
# LXC Builder
|
||||
|
||||
Type: `lxc`
|
||||
Artifact BuilderId: `ustream.lxc`
|
||||
|
||||
The `lxc` Packer builder builds containers for lxc1. The builder starts an LXC
|
||||
container, runs provisioners within this container, then exports the container
|
||||
|
||||
@@ -13,6 +13,7 @@ sidebar_title: LXD
|
||||
# LXD Builder
|
||||
|
||||
Type: `lxd`
|
||||
Artifact BuilderId: `lxd`
|
||||
|
||||
The `lxd` Packer builder builds containers for LXD. The builder starts an LXD
|
||||
container, runs provisioners within this container, then saves the container as
|
||||
|
||||
@@ -8,6 +8,9 @@ sidebar_title: NAVER Cloud
|
||||
|
||||
# NAVER CLOUD PLATFORM Builder
|
||||
|
||||
Type: `ncloud`
|
||||
Artifact BuilderId: `ncloud.server.image`
|
||||
|
||||
The `ncloud` builder allows you to create server images using the [NAVER Cloud
|
||||
Platform](https://www.ncloud.com/).
|
||||
|
||||
|
||||
@@ -55,4 +55,4 @@ build {
|
||||
## Configuration Reference
|
||||
|
||||
The null builder has no configuration parameters other than the
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) settings.
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) settings.
|
||||
|
||||
@@ -7,6 +7,7 @@ sidebar_title: 1&1
|
||||
# 1&1 Builder
|
||||
|
||||
Type: `oneandone`
|
||||
Artifact BuilderId: `packer.oneandone`
|
||||
|
||||
The 1&1 Builder is able to create virtual machines for
|
||||
[1&1](https://www.1and1.com/).
|
||||
@@ -18,7 +19,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder. In addition to the options defined there, a private key file
|
||||
can also be supplied to override the typical auto-generated key:
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ sidebar_title: OpenStack
|
||||
# OpenStack Builder
|
||||
|
||||
Type: `openstack`
|
||||
Artifact BuilderId: `mitchellh.openstack`
|
||||
|
||||
The `openstack` Packer builder is able to create new images for use with
|
||||
[OpenStack](http://www.openstack.org). The builder takes a source image, runs
|
||||
@@ -51,7 +52,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Required:
|
||||
@@ -140,7 +141,7 @@ Here is a basic example. This is a working example to build a Ubuntu 12.04 LTS
|
||||
(Precise Pangolin) on Rackspace OpenStack cloud offering.
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="JSON">
|
||||
<Tab heading="JSON">
|
||||
|
||||
```json
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Oracle Classic
|
||||
# Oracle Cloud Infrastructure Classic Compute Builder
|
||||
|
||||
Type: `oracle-classic`
|
||||
Artifact BuilderId: `packer.oracle.classic`
|
||||
|
||||
The `oracle-classic` Packer builder is able to create custom images for use
|
||||
with [Oracle Cloud Infrastructure Classic
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Oracle OCI
|
||||
# Oracle Cloud Infrastructure (OCI) Builder
|
||||
|
||||
Type: `oracle-oci`
|
||||
Artifact BuilderId: `packer.oracle.oci`
|
||||
|
||||
The `oracle-oci` Packer builder is able to create new custom images for use
|
||||
with [Oracle Cloud Infrastructure](https://cloud.oracle.com) (OCI). The builder
|
||||
@@ -40,7 +41,7 @@ in which case you don't need the above user authorization.
|
||||
|
||||
There are many configuration options available for the `oracle-oci` builder. In
|
||||
addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
In addition to the options defined there, a private key file
|
||||
|
||||
@@ -13,6 +13,7 @@ sidebar_title: BSU
|
||||
# OMI Builder (BSU backed)
|
||||
|
||||
Type: `osc-bsu`
|
||||
Artifact BuilderId: `oapi.outscale.bsu`
|
||||
|
||||
The `osc-bsu` Packer builder is able to create Outscale OMIs backed by BSU
|
||||
volumes for use in [Flexible Compute Unit](https://wiki.outscale.net/pages/viewpage.action?pageId=43060893). For more information on
|
||||
@@ -41,7 +42,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Required:
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: BSU Surrogate
|
||||
# BSU Surrogate Builder
|
||||
|
||||
Type: `osc-bsusurrogate`
|
||||
Artifact BuilderId: `oapi.outscale.bsusurrogate`
|
||||
|
||||
The `osc-bsusurrogate` Packer builder is able to create Outscale OMIs by
|
||||
running a source virtual machine with an attached volume, provisioning the attached
|
||||
@@ -29,7 +30,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Required:
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: BSU Volume
|
||||
# BSU Volume Builder
|
||||
|
||||
Type: `osc-bsuvolume`
|
||||
Artifact BuilderId: `oapi.outscale.bsuvolume`
|
||||
|
||||
The `osc-bsuvolume` Packer builder is able to create Ouscale Block Stogate Unit
|
||||
volumes which are prepopulated with filesystems or data.
|
||||
@@ -35,7 +36,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Required:
|
||||
|
||||
@@ -15,6 +15,7 @@ sidebar_title: chroot
|
||||
# OMI Builder (chroot)
|
||||
|
||||
Type: `osc-chroot`
|
||||
Artifact BuilderId: `oapi.outscale.chroot`
|
||||
|
||||
The `osc-chroot` Packer builder is able to create Outscale Machine Images (OMIs) backed by an
|
||||
BSU volume as the root device. For more information on the difference between
|
||||
|
||||
@@ -12,6 +12,7 @@ sidebar_title: ISO
|
||||
# Parallels Builder (from an ISO)
|
||||
|
||||
Type: `parallels-iso`
|
||||
Artifact BuilderId: `packer.parallels`
|
||||
|
||||
The Parallels Packer builder is able to create [Parallels Desktop for
|
||||
Mac](https://www.parallels.com/products/desktop/) virtual machines and export
|
||||
@@ -53,7 +54,7 @@ are organized below into two categories: required and optional. Within each
|
||||
category, the available options are alphabetized and described.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder. In addition to the options defined there, a private key file
|
||||
can also be supplied to override the typical auto-generated key:
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ sidebar_title: PVM
|
||||
# Parallels Builder (from a PVM)
|
||||
|
||||
Type: `parallels-pvm`
|
||||
Artifact BuilderId: `packer.parallels`
|
||||
|
||||
This Parallels builder is able to create [Parallels Desktop for
|
||||
Mac](https://www.parallels.com/products/desktop/) virtual machines and export
|
||||
@@ -50,7 +51,7 @@ are organized below into two categories: required and optional. Within each
|
||||
category, the available options are alphabetized and described.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder. In addition to the options defined there, a private key file
|
||||
can also be supplied to override the typical auto-generated key:
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ sidebar_title: ProfitBricks
|
||||
# ProfitBricks Builder
|
||||
|
||||
Type: `profitbricks`
|
||||
Artifact BuilderId: `packer.profitbricks`
|
||||
|
||||
The ProfitBricks Builder is able to create virtual machines for
|
||||
[ProfitBricks](https://www.profitbricks.com).
|
||||
@@ -18,7 +19,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder. In addition to the options defined there, a private key file
|
||||
can also be supplied to override the typical auto-generated key:
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: Clone
|
||||
# Proxmox Builder (from an image)
|
||||
|
||||
Type: `proxmox-clone`
|
||||
Artifact BuilderId: `proxmox.clone`
|
||||
|
||||
The `proxmox-clone` Packer builder is able to create new images for use with
|
||||
[Proxmox](https://www.proxmox.com/en/proxmox-ve). The builder takes a virtual
|
||||
@@ -28,7 +29,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
If no communicator is defined, an SSH key is generated for use, and is used
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: ISO
|
||||
# Proxmox Builder (from an ISO)
|
||||
|
||||
Type: `proxmox-iso`
|
||||
Artifact BuilderId: `proxmox.iso`
|
||||
|
||||
The `proxmox-iso` Packer builder is able to create new images for use with
|
||||
[Proxmox](https://www.proxmox.com/en/proxmox-ve). The builder takes an ISO
|
||||
@@ -28,7 +29,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Required:
|
||||
|
||||
@@ -10,6 +10,7 @@ sidebar_title: QEMU
|
||||
# QEMU Builder
|
||||
|
||||
Type: `qemu`
|
||||
Artifact BuilderId: `transcend.qemu`
|
||||
|
||||
The Qemu Packer builder is able to create [KVM](http://www.linux-kvm.org) virtual
|
||||
machine images.
|
||||
|
||||
@@ -17,6 +17,7 @@ sidebar_title: Scaleway
|
||||
# Scaleway Builder
|
||||
|
||||
Type: `scaleway`
|
||||
Artifact BuilderId: `hashicorp.scaleway`
|
||||
|
||||
The `scaleway` Packer builder is able to create new images for use with
|
||||
[Scaleway](https://www.scaleway.com). The builder takes a source image, runs
|
||||
@@ -34,7 +35,7 @@ segmented below into two categories: required and optional parameters. Within
|
||||
each category, the available configuration keys are alphabetized.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder. In addition to the options defined there, a private key file
|
||||
can also be supplied to override the typical auto-generated key:
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Tencent Cloud
|
||||
# Tencentcloud Image Builder
|
||||
|
||||
Type: `tencentcloud-cvm`
|
||||
Artifact BuilderId: `tencent.cloud`
|
||||
|
||||
The `tencentcloud-cvm` Packer builder plugin provide the capability to build
|
||||
customized images based on an existing base images.
|
||||
@@ -17,7 +18,7 @@ customized images based on an existing base images.
|
||||
|
||||
The following configuration options are available for building Tencentcloud images.
|
||||
In addition to the options listed here,
|
||||
a [communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this builder.
|
||||
a [communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this builder.
|
||||
|
||||
### Required:
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ sidebar_title: Triton
|
||||
# Triton Builder
|
||||
|
||||
Type: `triton`
|
||||
Artifact BuilderId: `joyent.triton`
|
||||
|
||||
The `triton` Packer builder is able to create new images for use with Triton.
|
||||
These images can be used with both the [Joyent public
|
||||
@@ -47,7 +48,7 @@ There are many configuration options available for the builder. They are
|
||||
segmented below into two categories: required and optional parameters.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder. In addition to the options defined there, a private key file
|
||||
can also be supplied to override the typical auto-generated key:
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: UCloud
|
||||
# UCloud Image Builder
|
||||
|
||||
Type: `ucloud-uhost`
|
||||
Artifact BuilderId: `ucloud.uhost`
|
||||
|
||||
The `ucloud-uhost` Packer builder plugin provides the capability to build
|
||||
customized images based on an existing base image for use in UHost Instance.
|
||||
@@ -22,7 +23,7 @@ The following configuration options are available for building UCloud images. Th
|
||||
segmented below into two categories: required and optional parameters.
|
||||
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
~> **Note:** The builder doesn't support Windows images for now and only supports CentOS and Ubuntu images via SSH authentication with `ssh_username` (Required) and `ssh_password` (Optional). The `ssh_username` must be `root` for CentOS images and `ubuntu` for Ubuntu images. The `ssh_password` may contain 8-30 characters, and must consist of at least 2 items out of the capital letters, lower case letters, numbers and special characters. The special characters include `()~!@#\$%^&\*-+=\_|{}\[]:;'<>,.?/`.
|
||||
|
||||
@@ -8,6 +8,9 @@ sidebar_title: Vagrant
|
||||
|
||||
# Vagrant Builder
|
||||
|
||||
Type: `vagrant`
|
||||
Artifact BuilderId: `vagrant`
|
||||
|
||||
The Vagrant builder is intended for building new boxes from already-existing
|
||||
boxes. Your source should be a URL or path to a .box file or a Vagrant Cloud
|
||||
box name such as `hashicorp/precise64`.
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: ISO
|
||||
# VirtualBox Builder (from an ISO)
|
||||
|
||||
Type: `virtualbox-iso`
|
||||
Artifact BuilderId: `mitchellh.virtualbox`
|
||||
|
||||
The VirtualBox Packer builder is able to create
|
||||
[VirtualBox](https://www.virtualbox.org/) virtual machines and export them in
|
||||
|
||||
@@ -12,6 +12,7 @@ sidebar_title: OVF
|
||||
# VirtualBox Builder (from an OVF/OVA)
|
||||
|
||||
Type: `virtualbox-ovf`
|
||||
Artifact BuilderId: `mitchellh.virtualbox`
|
||||
|
||||
This VirtualBox Packer builder is able to create
|
||||
[VirtualBox](https://www.virtualbox.org/) virtual machines and export them in
|
||||
|
||||
@@ -13,6 +13,7 @@ sidebar_title: VM
|
||||
# VirtualBox Builder (from an existing VM)
|
||||
|
||||
Type: `virtualbox-vm`
|
||||
Artifact BuilderId: `mitchellh.virtualbox`
|
||||
|
||||
The VirtualBox Packer builder is able to create
|
||||
[VirtualBox](https://www.virtualbox.org/) virtual machines snapshots and
|
||||
@@ -100,7 +101,7 @@ references for [ISO](#iso-configuration),
|
||||
configuration references, which are
|
||||
necessary for this build to succeed and can be found further down the page.
|
||||
In addition to the options listed here, a
|
||||
[communicator](/docs/templates/legacy_json_templates/communicators) can be configured for this
|
||||
[communicator](/docs/templates/legacy_json_templates/communicator) can be configured for this
|
||||
builder.
|
||||
|
||||
### Required:
|
||||
|
||||
@@ -14,6 +14,8 @@ sidebar_title: VMWare ISO
|
||||
# VMware Builder (from ISO)
|
||||
|
||||
Type: `vmware-iso`
|
||||
Artifact BuilderId: `mitchellh.vmware`
|
||||
If remote_type is esx: Artifact BuilderId: `mitchellh.vmware-esx`
|
||||
|
||||
This VMware Packer builder is able to create VMware virtual machines from an ISO
|
||||
file as a source. It currently supports building virtual machines on hosts
|
||||
|
||||
@@ -13,6 +13,8 @@ sidebar_title: VMWare VMX
|
||||
# VMware Builder (from VMX)
|
||||
|
||||
Type: `vmware-vmx`
|
||||
Artifact BuilderId: `mitchellh.vmware`
|
||||
If remote_type is esx: Artifact BuilderId: `mitchellh.vmware-esx`
|
||||
|
||||
This VMware Packer builder is able to create VMware virtual machines from an
|
||||
existing VMware virtual machine (a VMX file). It currently supports building
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: VSphere Clone
|
||||
# VMWare Vsphere Clone Builder
|
||||
|
||||
Type: `vsphere-clone`
|
||||
Artifact BuilderId: `jetbrains.vsphere`
|
||||
|
||||
This builder clones VMs from existing templates.
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: VSphere ISO
|
||||
# Packer Builder for VMware vSphere
|
||||
|
||||
Type: `vsphere-iso`
|
||||
Artifact BuilderId: `jetbrains.vsphere`
|
||||
|
||||
This builder uses the vSphere API, and creates virtual machines remotely. It
|
||||
starts from an ISO file and creates new VMs from scratch.
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Yandex.Cloud
|
||||
# Yandex Compute Builder
|
||||
|
||||
Type: `yandex`
|
||||
Artifact BuilderId: `packer.yandex`
|
||||
|
||||
The `yandex` Packer builder is able to create
|
||||
[images](https://cloud.yandex.com/docs/compute/concepts/images) for use with
|
||||
@@ -64,7 +65,7 @@ Configuration options are organized below into two categories: required and
|
||||
optional. Within each category, the available options are alphabetized and
|
||||
described.
|
||||
|
||||
In addition to the options listed here, a [communicator](/docs/templates/legacy_json_templates/communicators)
|
||||
In addition to the options listed here, a [communicator](/docs/templates/legacy_json_templates/communicator)
|
||||
can be configured for this builder. In addition to the options defined there, a private key file
|
||||
can also be supplied to override the typical auto-generated key:
|
||||
|
||||
|
||||
@@ -7,23 +7,6 @@ sidebar_title: <tt>init</tt>
|
||||
|
||||
# `init` Command
|
||||
|
||||
-> **Note:** Packer does not currently have the notion of a state like Terraform
|
||||
has. In other words, currently `packer init` is only in charge of installing
|
||||
packer plugins.
|
||||
|
||||
-> **Note:** Currently, `packer init` can only fetch binaries from public
|
||||
projects on *Github*.
|
||||
|
||||
-> **Note:** Currently, `packer init` only fetches binaries using Github's
|
||||
public API, which [limits the number of unauthenticated requests per hour one IP
|
||||
can
|
||||
do](https://docs.github.com/en/developers/apps/rate-limits-for-github-apps#normal-user-to-server-rate-limits).
|
||||
Packer will do its best to avoid hitting those limits and in an average local
|
||||
usage this should not be an issue. Otherwise you can set the
|
||||
`PKR_GITHUB_API_TOKEN` env var in order to get more requests per hour. Go to
|
||||
your personal [access token page](https://github.com/settings/tokens) to
|
||||
generate a new token.
|
||||
|
||||
-> **Note:** Packer init does not work with legacy JSON templates. You can
|
||||
upgrade your JSON config files to HCL using the hcl2ugprade command.
|
||||
|
||||
@@ -32,10 +15,22 @@ that are named `packer-plugin-*` -- to install a single plugin binary -- that is
|
||||
`packer-provisioner-*`, `packer-builder-*`, etc. -- nothing changes, you will
|
||||
have to [install the plugin manually](/docs/plugins#installing-plugins).
|
||||
|
||||
The `packer init` command is used to download Packer plugin binaries.
|
||||
This is the first command that should be executed when working with a new or
|
||||
existing template. This command is always safe to run multiple times. Though
|
||||
subsequent runs may give errors, this command will never delete anything.
|
||||
The `packer init` command is used to download Packer plugin binaries. This is
|
||||
the first command that should be executed when working with a new or existing
|
||||
template. This command is always safe to run multiple times. Though subsequent
|
||||
runs may give errors, this command will never delete anything.
|
||||
|
||||
Packer does not currently have the notion of a state like Terraform has. In other words,
|
||||
currently `packer init` is only in charge of installing packer plugins.
|
||||
|
||||
Currently, `packer init` can only fetch binaries from public projects on **GitHub**. GitHub's public API, [limits the number of unauthenticated requests
|
||||
per hour one IP can
|
||||
do](https://docs.github.com/en/developers/apps/rate-limits-for-github-apps#normal-user-to-server-rate-limits).
|
||||
Packer will do its best to avoid hitting those limits and in an average local
|
||||
usage this should not be an issue. Otherwise you can set the
|
||||
`PKR_GITHUB_API_TOKEN` env var in order to get more requests per hour. Go to
|
||||
your personal [access token page](https://github.com/settings/tokens) to
|
||||
generate a new token.
|
||||
|
||||
`packer init` will list all installed plugins then download the latest versions
|
||||
for the ones that are missing.
|
||||
|
||||
@@ -110,6 +110,10 @@ each can be found below:
|
||||
- `PACKER_CONFIG_DIR` - The location for the home directory of Packer. See
|
||||
[Packer's home directory](#packer-s-home-directory) for more.
|
||||
|
||||
- `PKR_GITHUB_API_TOKEN` - When using Packer init on HCL2 templates, Packer
|
||||
queries the public API from Github which limits the ammount of queries on can
|
||||
set the `PKR_GITHUB_API_TOKEN` with a Github Token to make it higher.
|
||||
|
||||
- `PACKER_LOG` - Setting this to any value other than "" (empty string) or
|
||||
"0" will enable the logger. See the [debugging
|
||||
page](/docs/other/debugging).
|
||||
|
||||
@@ -173,7 +173,11 @@ builder, followed by the platform it is building for. For example, the builder
|
||||
ID of the VMware builder is "hashicorp.vmware".
|
||||
|
||||
Post-processors use the builder ID value in order to make some assumptions
|
||||
about the artifact results, so it is important it never changes.
|
||||
about the artifact results and to determine whether they are even able to run
|
||||
against a given artifact, so it is important that this ID never changes once
|
||||
the builder is published.
|
||||
|
||||
The builder ID for each builder is documented on its website docs page.
|
||||
|
||||
## Provisioning
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Alicloud Import
|
||||
# Alicloud Import Post-Processor
|
||||
|
||||
Type: `alicloud-import`
|
||||
Artifact BuilderId: `packer.post-processor.alicloud-import`
|
||||
|
||||
The Packer Alicloud Import post-processor takes a RAW or VHD artifact from
|
||||
various builders and imports it to an Alicloud ECS Image.
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Amazon Import
|
||||
# Amazon Import Post-Processor
|
||||
|
||||
Type: `amazon-import`
|
||||
Artifact BuilderId: `packer.post-processor.amazon-import`
|
||||
|
||||
The Packer Amazon Import post-processor takes an OVA artifact from various
|
||||
builders and imports it to an AMI available to Amazon Web Services EC2.
|
||||
|
||||
@@ -19,6 +19,7 @@ sidebar_title: Artifice
|
||||
# Artifice Post-Processor
|
||||
|
||||
Type: `artifice`
|
||||
Artifact BuilderId: `packer.post-processor.artifice`
|
||||
|
||||
The artifice post-processor overrides the artifact list from an upstream
|
||||
builder or post-processor. All downstream post-processors will see the new
|
||||
|
||||
@@ -13,6 +13,7 @@ sidebar_title: Checksum
|
||||
# Checksum Post-Processor
|
||||
|
||||
Type: `checksum`
|
||||
Artifact BuilderId: `packer.post-processor.checksum`
|
||||
|
||||
The checksum post-processor computes specified checksum for the artifact list
|
||||
from an upstream builder or post-processor. All downstream post-processors will
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Compress
|
||||
# Compress Post-Processor
|
||||
|
||||
Type: `compress`
|
||||
Artifact BuilderId: `packer.post-processor.compress`
|
||||
|
||||
The Packer compress post-processor takes an artifact with files (such as from
|
||||
VMware or VirtualBox) and compresses the artifact into a single archive.
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: DigitalOcean Import
|
||||
# DigitalOcean Import Post-Processor
|
||||
|
||||
Type: `digitalocean-import`
|
||||
Artifact BuilderId: `packer.post-processor.digitalocean-import`
|
||||
|
||||
The Packer DigitalOcean Import post-processor is used to import images created by other Packer builders to DigitalOcean.
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: Docker Import
|
||||
# Docker Import Post-Processor
|
||||
|
||||
Type: `docker-import`
|
||||
Artifact BuilderId: `packer.post-processor.docker-import`
|
||||
|
||||
The Packer Docker import post-processor takes an artifact from the [docker
|
||||
builder](/docs/builders/docker) and imports it with Docker locally. This
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Docker Push
|
||||
# Docker Push Post-Processor
|
||||
|
||||
Type: `docker-push`
|
||||
Artifact BuilderId: `packer.post-processor.docker-import`
|
||||
|
||||
The Packer Docker push post-processor takes an artifact from the
|
||||
[docker-import](/docs/post-processors/docker-import) post-processor and
|
||||
|
||||
@@ -15,6 +15,7 @@ sidebar_title: Docker Save
|
||||
# Docker Save Post-Processor
|
||||
|
||||
Type: `docker-save`
|
||||
Artifact BuilderId: `packer.post-processor.docker-save`
|
||||
|
||||
The Packer Docker Save post-processor takes an artifact from the [docker
|
||||
builder](/docs/builders/docker) that was committed and saves it to a file.
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: Docker Tag
|
||||
# Docker Tag Post-Processor
|
||||
|
||||
Type: `docker-tag`
|
||||
Artifact BuilderId: `packer.post-processor.docker-tag`
|
||||
|
||||
The Packer Docker Tag post-processor takes an artifact from the [docker
|
||||
builder](/docs/builders/docker) that was committed and tags it into a
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Exoscale Import
|
||||
# Exoscale Import Post-Processor
|
||||
|
||||
Type: `exoscale-import`
|
||||
Artifact BuilderId: `packer.post-processor.exoscale-import`
|
||||
|
||||
The Packer Exoscale Import post-processor takes an image artifact from
|
||||
the QEMU, Artifice, or File builders and imports it to Exoscale.
|
||||
|
||||
@@ -11,6 +11,7 @@ sidebar_title: Google Compute Export
|
||||
# Google Compute Image Exporter Post-Processor
|
||||
|
||||
Type: `googlecompute-export`
|
||||
Artifact BuilderId: `packer.post-processor.googlecompute-export`
|
||||
|
||||
The Google Compute Image Exporter post-processor exports the resultant image
|
||||
from a googlecompute build as a gzipped tarball to Google Cloud Storage (GCS).
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Google Compute Import
|
||||
# Google Compute Image Import Post-Processor
|
||||
|
||||
Type: `googlecompute-import`
|
||||
Artifact BuilderId: `packer.post-processor.googlecompute-import`
|
||||
|
||||
The Google Compute Image Import post-processor takes a compressed raw disk
|
||||
image and imports it to a GCE image available to Google Compute Engine.
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Manifest
|
||||
# Manifest Post-Processor
|
||||
|
||||
Type: `manifest`
|
||||
Artifact BuilderId: `packer.post-processor.manifest`
|
||||
|
||||
The manifest post-processor writes a JSON file with a list of all of the
|
||||
artifacts packer produces during a run. If your packer template includes
|
||||
|
||||
@@ -10,6 +10,7 @@ sidebar_title: UCloud Import
|
||||
# UCloud Import Post-Processor
|
||||
|
||||
Type: `ucloud-import`
|
||||
Artifact BuilderId: `packer.post-processor.ucloud-import`
|
||||
|
||||
The Packer UCloud Import post-processor takes the RAW, VHD, VMDK, or qcow2 artifact from various builders and imports it to UCloud customized image list for UHost Instance.
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ sidebar_title: Vagrant Cloud
|
||||
# Vagrant Cloud Post-Processor
|
||||
|
||||
Type: `vagrant-cloud`
|
||||
Artifact BuilderId: `pearkes.post-processor.vagrant-cloud`
|
||||
|
||||
[Vagrant Cloud](https://app.vagrantup.com/boxes/search) hosts and serves boxes
|
||||
to Vagrant, allowing you to version and distribute boxes to an organization in a
|
||||
|
||||
@@ -15,6 +15,7 @@ sidebar_title: Vagrant
|
||||
# Vagrant Post-Processor
|
||||
|
||||
Type: `vagrant`
|
||||
Artifact BuilderId: `mitchellh.post-processor.vagrant`
|
||||
|
||||
The Packer Vagrant post-processor takes a build and converts the artifact into
|
||||
a valid [Vagrant](https://www.vagrantup.com) box, if it can. This lets you use
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user