github.com/hashicorp/packer@v1.14.3/website/content/docs/plugins/creation/custom-post-processors.mdx (about)

     1  ---
     2  description: >
     3    Post-processors compress files, upload files, and perform other tasks that transform artifacts. Learn how to create customm post-processors that extend Packer.
     4  page_title: Create custom post-processors
     5  ---
     6  
     7  # Create custom post-processors
     8  
     9  Packer post-processors transform one artifact into another. For example, a post-processor might compress or upload files.
    10  
    11  In the compression example, the transformation would be taking an artifact with
    12  a set of files, compressing those files, and returning a new artifact with only
    13  a single file (the compressed archive). For the upload example, the
    14  transformation would be taking an artifact with some set of files, uploading
    15  those files, and returning an artifact with a single ID: the URL of the upload.
    16  
    17  Post-processor plugins implement the [`packer.PostProcessor`](https://pkg.go.dev/github.com/hashicorp/packer-plugin-sdk/packer#PostProcessor) interface and are
    18  served using the `plugin.ServePostProcessor` function.
    19  
    20  This page explains how to implement and serve custom post-processors. If you want your post-processor to support HashiCorp Cloud Platform (HCP) Packer, you should also review the [HCP Packer Support](/packer/docs/plugins/creation/hcp-support) documentation.
    21  
    22  ~> **Warning:** This is an advanced topic that requires strong knowledge of Packer and Packer plugins.
    23  
    24  ## Before You Begin
    25  
    26  We recommend reviewing the following resources before you begin development:
    27  - [Developing Plugins - Overview](/packer/docs/plugins/creation)
    28  - The [Go](https://go.dev/) language. You must write custom plugins in Go, so this guide assumes you are familiar with the language.
    29  
    30  ## The Interface
    31  
    32  The interface that must be implemented for a post-processor is the
    33  [`packer.PostProcessor`](https://pkg.go.dev/github.com/hashicorp/packer-plugin-sdk/packer#PostProcessor) interface. It is reproduced below for reference. The
    34  actual interface in the source code contains some basic documentation as well
    35  explaining what each method should do.
    36  
    37  ```go
    38  type PostProcessor interface {
    39    ConfigSpec() hcldec.ObjectSpec
    40    Configure(interface{}) error
    41    PostProcess(context.Context, Ui, Artifact) (a Artifact, keep, mustKeep bool, err error)
    42  }
    43  ```
    44  
    45  ### The "ConfigSpec" Method
    46  
    47  This method returns a hcldec.ObjectSpec, which is a spec necessary for using
    48  HCL2 templates with Packer. For information on how to use and implement this
    49  function, check our
    50  [object spec docs](/packer/guides/hcl/component-object-spec)
    51  
    52  ### The "Configure" Method
    53  
    54  The `Configure` method for each post-processor is called early in the build
    55  process to configure the post-processor. The configuration is passed in as a
    56  raw `interface{}`. The configure method is responsible for translating this
    57  configuration into an internal structure, validating it, and returning any
    58  errors.
    59  
    60  For decoding the `interface{}` into a meaningful structure, the
    61  [mapstructure](https://github.com/mitchellh/mapstructure) library is
    62  recommended. Mapstructure will take an `interface{}` and decode it into an
    63  arbitrarily complex struct. If there are any errors, it generates very
    64  human-friendly errors that can be returned directly from the configure method.
    65  
    66  While it is not actively enforced, **no side effects** should occur from
    67  running the `Configure` method. Specifically, don't create files, don't create
    68  network connections, etc. Configure's purpose is solely to setup internal state
    69  and validate the configuration as much as possible.
    70  
    71  `Configure` being run is not an indication that `PostProcess` will ever run.
    72  For example, `packer validate` will run `Configure` to verify the configuration
    73  validates, but will never actually run the build.
    74  
    75  ### The "PostProcess" Method
    76  
    77  The `PostProcess` method is where the real work goes. PostProcess is
    78  responsible for taking one `packer.Artifact` implementation, and transforming
    79  it into another.
    80  A `PostProcess` call can be cancelled at any moment. Cancellation is triggered
    81  when the done chan of the context struct (`<-ctx.Done()`) unblocks .
    82  
    83  When we say "transform," we don't mean actually modifying the existing
    84  `packer.Artifact` value itself. We mean taking the contents of the artifact and
    85  creating a new artifact from that. For example, if we were creating a
    86  "compress" post-processor that is responsible for compressing files, the
    87  transformation would be taking the `Files()` from the original artifact,
    88  compressing them, and creating a new artifact with a single file: the
    89  compressed archive.
    90  
    91  The result signature of this method is `(Artifact, bool, bool, error)`. Each
    92  return value is explained below:
    93  
    94  - `Artifact` - The newly created artifact if no errors occurred.
    95  - `bool` - If keep true, the input artifact will forcefully be kept. By default,
    96    Packer typically deletes all input artifacts, since the user doesn't
    97    generally want intermediary artifacts. However, some post-processors depend
    98    on the previous artifact existing. If this is `true`, it forces packer to
    99    keep the artifact around.
   100  - `bool` - If forceOverride is true, then any user input for
   101    keep_input_artifact is ignored and the artifact is either kept or discarded
   102    according to the value set in `keep`.
   103  - `error` - Non-nil if there was an error in any way. If this is the case,
   104    the other two return values are ignored.