Skip to main content

Publish Artifacts to S3 and Git

· 2 min read
Erik Osterman
Founder @ Cloud Posse

Packaging a Lambda archive is only part of a deployment: the archive must also reach S3. The new publish step uploads files and directories from workflows, custom commands, and component hooks, and skips unchanged objects.

The Problem​

Artifact uploads often need an AWS CLI command alongside an archive step. Those scripts must handle credentials, content types, and repeated uploads themselves.

The Fix​

Use type: publish with an aws/s3 target to upload through the step runner. Atmos compares SHA-256 metadata, object size, and delivery headers before uploading. Files that already match stay untouched, and files removed locally are retained in S3.

How to Use It​

steps:
- name: package
type: archive
source: src/
destination: handler.zip
mtime: epoch
- name: upload
type: publish
source: '{{ .steps.package.value }}'
target:
kind: aws/s3
bucket: acme-artifacts
prefix: lambda/v1/
region: us-east-1

Create the bucket first and grant the caller permission to inspect and upload objects. For a directory, set source: dist/ and a target prefix. Configure the target's cache_control when publishing assets with caching headers.

CloudFormation hooks can now package and upload local assets without a shell upload command. See the complete hook example. Template references remain explicit; use a new key per release so CloudFormation can detect the artifact change.

The advanced CloudFormation example runs the complete pipeline in Floci. Its hooks build and test a Lambda, archive and publish the code, then validate the deployed function with an http step.

Build, publish, and deploy a Lambda
 
00:00.0 / 00:00.0

View the full example

Git targets use the same step:

steps:
- type: publish
source: dist/
target:
kind: git
repository: deployment-repo
path: generated/service
commit:
message: Publish service configuration

Declare deployment-repo in your managed Git configuration first. Atmos writes raw files, commits changes, and pushes. Destination-only files stay intact; an unchanged run creates no commit. In component hooks, use a target name to reuse a definition from provision.targets.

Get Involved​

Read the step reference for credentials, outputs, and limits. Report problems or share use cases in GitHub discussions.