Usage#
Sync to Amazon S3#
{{< chooser language "typescript,python,go,csharp,yaml" / >}}
{{% choosable language typescript %}}
import * as aws from "@pulumi/aws";
import * as synced from "@pulumi/synced-folder";
const bucket = new aws.s3.Bucket("my-bucket", {
acl: aws.s3.PublicReadAcl,
});
const folder = new synced.S3BucketFolder("synced-folder", {
path: "./my-folder",
bucketName: bucket.bucket,
acl: aws.s3.PublicReadAcl,
});{{% /choosable %}}
{{% choosable language python %}}
from pulumi_aws import s3
import pulumi_synced_folder
bucket = s3.Bucket(
"my-bucket",
acl=s3.CannedAcl.PUBLIC_READ,
)
folder = pulumi_synced_folder.S3BucketFolder(
"synced-folder",
path="./my-folder",
bucket_name=bucket.bucket,
acl=s3.CannedAcl.PUBLIC_READ,
){{% /choosable %}}
{{% choosable language go %}}
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v5/go/aws/s3"
synced "github.com/pulumi/pulumi-synced-folder/sdk/go/synced-folder"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
bucket, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{
Acl: s3.CannedAclPublicRead,
})
if err != nil {
return err
}
_, err = synced.NewS3BucketFolder(ctx, "synced-folder", &synced.S3BucketFolderArgs{
Path: pulumi.String("./my-folder"),
BucketName: bucket.Bucket,
Acl: s3.CannedAclPublicRead,
})
if err != nil {
return err
}
return nil
})
}{{% /choosable %}}
{{% choosable language csharp %}}
using Pulumi;
using Pulumi.Aws.S3;
using Pulumi.SyncedFolder;
return await Deployment.RunAsync(() =>
{
var bucket = new Bucket("my-bucket", new BucketArgs {
Acl = CannedAcl.PublicRead,
});
var folder = new S3BucketFolder("synced-folder", new S3BucketFolderArgs {
Path = "./my-folder",
BucketName = bucket.BucketName,
Acl = (string)CannedAcl.PublicRead,
});
});{{% /choosable %}}
{{% choosable language yaml %}}
name: synced-folder-aws-yaml
runtime: yaml
resources:
my-bucket:
type: aws:s3:Bucket
properties:
acl: public-read
synced-folder:
type: synced-folder:index:S3BucketFolder
properties:
path: ./my-folder
bucketName: ${my-bucket.bucket}
acl: public-read{{% /choosable %}}
Sync to Azure Blob Storage#
{{< chooser language "typescript,python,go,csharp,yaml" / >}}
{{% choosable language typescript %}}
import * as resources from "@pulumi/azure-native/resources";
import * as storage from "@pulumi/azure-native/storage";
import * as synced from "@pulumi/synced-folder";
const resourceGroup = new resources.ResourceGroup("resourceGroup");
const account = new storage.StorageAccount("account", {
resourceGroupName: resourceGroup.name,
kind: storage.Kind.StorageV2,
sku: {
name: storage.SkuName.Standard_LRS,
},
});
const container = new storage.BlobContainer("container", {
resourceGroupName: resourceGroup.name,
accountName: account.name,
});
const folder = new synced.AzureBlobFolder("synced-folder", {
resourceGroupName: resourceGroup.name,
storageAccountName: account.name,
containerName: container.name,
path: "./my-folder",
});{{% /choosable %}}
{{% choosable language python %}}
import resource
from pulumi_azure_native import storage
from pulumi_azure_native import resources
import pulumi_synced_folder
resource_group = resources.ResourceGroup("resource_group")
account = storage.StorageAccount("account", storage.StorageAccountArgs(
resource_group_name=resource_group.name,
kind=storage.Kind.STORAGE_V2,
sku=storage.SkuArgs(
name=storage.SkuName.STANDARD_LRS,
)
))
container = storage.BlobContainer("container", storage.BlobContainerArgs(
resource_group_name=resource_group.name,
account_name=account.name,
))
folder = pulumi_synced_folder.AzureBlobFolder("synced-folder", pulumi_synced_folder.AzureBlobFolderArgs(
resource_group_name=resource_group.name,
storage_account_name=account.name,
container_name=container.name,
path="./my-folder",
)){{% /choosable %}}
{{% choosable language go %}}
package main
import (
"github.com/pulumi/pulumi-azure-native/sdk/go/azure/resources"
"github.com/pulumi/pulumi-azure-native/sdk/go/azure/storage"
synced "github.com/pulumi/pulumi-synced-folder/sdk/go/synced-folder"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
resourceGroup, err := resources.NewResourceGroup(ctx, "resourceGroup", nil)
if err != nil {
return err
}
account, err := storage.NewStorageAccount(ctx, "account", &storage.StorageAccountArgs{
ResourceGroupName: resourceGroup.Name,
Kind: pulumi.String("StorageV2"),
Sku: &storage.SkuArgs{
Name: pulumi.String("Standard_LRS"),
},
})
if err != nil {
return err
}
container, err := storage.NewBlobContainer(ctx, "container", &storage.BlobContainerArgs{
ResourceGroupName: resourceGroup.Name,
AccountName: account.Name,
})
if err != nil {
return err
}
_, err = synced.NewAzureBlobFolder(ctx, "folder", &synced.AzureBlobFolderArgs{
ResourceGroupName: resourceGroup.Name,
StorageAccountName: account.Name,
ContainerName: container.Name,
Path: pulumi.String("./my-folder"),
})
if err != nil {
return err
}
return nil
})
}{{% /choosable %}}
{{% choosable language csharp %}}
using Pulumi.AzureNative.Resources;
using Pulumi.AzureNative.Storage;
using Pulumi.AzureNative.Storage.Inputs;
using Pulumi.SyncedFolder;
return await Pulumi.Deployment.RunAsync(() =>
{
var resourceGroup = new ResourceGroup("resource-group");
var storageAccount = new StorageAccount("account", new StorageAccountArgs
{
ResourceGroupName = resourceGroup.Name,
Kind = Kind.StorageV2,
Sku = new SkuArgs
{
Name = SkuName.Standard_LRS
},
});
var container = new BlobContainer("container", new BlobContainerArgs
{
ResourceGroupName = resourceGroup.Name,
AccountName = storageAccount.Name,
});
var folder = new AzureBlobFolder("synced-folder", new AzureBlobFolderArgs
{
ResourceGroupName = resourceGroup.Name,
StorageAccountName = storageAccount.Name,
ContainerName = container.Name,
Path = "./my-folder",
});
});{{% /choosable %}}
{{% choosable language yaml %}}
name: synced-folder-azure-yaml
runtime: yaml
resources:
resourceGroup:
type: azure-native:resources:ResourceGroup
account:
type: azure-native:storage:StorageAccount
properties:
resourceGroupName: ${resourceGroup.name}
kind: StorageV2
sku:
name: Standard_LRS
container:
type: azure-native:storage:BlobContainer
properties:
resourceGroupName: ${resourceGroup.name}
accountName: ${account.name}
folder:
type: synced-folder:index:AzureBlobFolder
properties:
resourceGroupName: ${resourceGroup.name}
storageAccountName: ${account.name}
containerName: ${container.name}
path: ./my-folder{{% /choosable %}}
Sync to Google Cloud Storage#
{{< chooser language "typescript,python,go,csharp,yaml" / >}}
{{% choosable language typescript %}}
import * as gcp from "@pulumi/gcp";
import * as synced from "@pulumi/synced-folder";
const bucket = new gcp.storage.Bucket("my-bucket", {
location: "US"
});
const binding = new gcp.storage.BucketIAMBinding("binding", {
bucket: bucket.name,
role: "roles/storage.objectViewer",
members: [
"allUsers"
],
});
const folder = new synced.GoogleCloudFolder("folder", {
bucketName: bucket.name,
path: "./my-folder",
});{{% /choosable %}}
{{% choosable language python %}}
from pulumi_gcp import storage
import pulumi_synced_folder
bucket = storage.Bucket("my-bucket", location="US")
binding = storage.BucketIAMBinding(
"binding",
storage.BucketIAMBindingArgs(
bucket=bucket.name,
role="roles/storage.objectViewer",
members=[
"allUsers",
],
)
)
folder = pulumi_synced_folder.GoogleCloudFolder(
"folder",
pulumi_synced_folder.GoogleCloudFolderArgs(
bucket_name=bucket.name,
path="./my-folder",
),
){{% /choosable %}}
{{% choosable language go %}}
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v6/go/gcp/storage"
synced "github.com/pulumi/pulumi-synced-folder/sdk/go/synced-folder"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
bucket, err := storage.NewBucket(ctx, "my-bucket", &storage.BucketArgs{
Location: pulumi.String("US"),
})
if err != nil {
return err
}
_, err = storage.NewBucketIAMBinding(ctx, "binding", &storage.BucketIAMBindingArgs{
Bucket: bucket.Name,
Role: pulumi.String("roles/storage.objectViewer"),
Members: pulumi.ToStringArray([]string{"allUsers"}),
})
if err != nil {
return err
}
_, err = synced.NewGoogleCloudFolder(ctx, "folder", &synced.GoogleCloudFolderArgs{
BucketName: bucket.Name,
Path: pulumi.String("./my-folder"),
})
if err != nil {
return err
}
return nil
})
}{{% /choosable %}}
{{% choosable language csharp %}}
using Pulumi;
using Pulumi.Gcp.Storage;
using Pulumi.SyncedFolder;
return await Deployment.RunAsync(() =>
{
var bucket = new Bucket("my-bucket", new BucketArgs
{
Location = "US"
});
var binding = new BucketIAMBinding("binding", new BucketIAMBindingArgs
{
Bucket = bucket.Name,
Role = "roles/storage.objectViewer",
Members = new[]
{
"allUsers",
}
});
var folder = new GoogleCloudFolder("folder", new GoogleCloudFolderArgs
{
BucketName = bucket.Name,
Path = "./my-folder",
});
});{{% /choosable %}}
{{% choosable language yaml %}}
name: synced-folder-gcp-yaml
runtime: yaml
resources:
bucket:
type: gcp:storage:Bucket
properties:
location: US
binding:
type: gcp:storage:BucketIAMBinding
properties:
bucket: ${bucket.name}
role: roles/storage.objectViewer
members:
- allUsers
folder:
type: synced-folder:index:GoogleCloudFolder
properties:
bucketName: ${bucket.name}
path: ./my-folder{{% /choosable %}}
Notes#
Managed and unmanaged file objects#
By default, the Synced Folder component manages your files as individual Pulumi cloud resources (for example, as multiple aws:S3:BucketObjects), but you can opt out of this behavior by using the component's managedObjects property:
{{< chooser language "typescript,python,go,csharp,yaml" / >}}
{{% choosable language typescript %}}
const folder = new synced.S3BucketFolder("synced-folder", {
path: "./my-folder",
bucketName: bucket.bucket,
acl: aws.s3.PublicReadAcl,
// Set this property to false to manage files outside Pulumi.
managedObjects: false,
});{{% /choosable %}}
{{% choosable language python %}}
folder = pulumi_synced_folder.S3BucketFolder(
"synced-folder",
path="./my-folder",
bucket_name=bucket.bucket,
acl=s3.CannedAcl.PUBLIC_READ,
# Set this property to false to manage files outside Pulumi.
managed_objects=False,
){{% /choosable %}}
{{% choosable language go %}}
folder, err = synced.NewS3BucketFolder(ctx, "synced-folder", &synced.S3BucketFolderArgs{
Path: pulumi.String("./my-folder"),
BucketName: bucket.Bucket,
Acl: s3.CannedAclPublicRead,
// Set this property to false to manage files outside Pulumi.
ManagedObjects: pulumi.Bool(false),
}){{% /choosable %}}
{{% choosable language csharp %}}
var folder = new S3BucketFolder("synced-bucket-folder", new S3BucketFolderArgs {
Path = "./my-folder",
BucketName = bucket.BucketName,
Acl = (string)CannedAcl.PublicRead,
// Set this property to false to manage files outside Pulumi.
ManagedObjects = false,
});{{% /choosable %}}
{{% choosable language yaml %}}
folder:
type: synced-folder:index:S3BucketFolder
properties:
path: ./my-folder
bucketName: ${my-bucket.bucket}
# Set this property to false to manage files outside Pulumi.
managedObjects: false{{% /choosable %}}
When you do this, the component assumes you've installed the cloud provider's official CLI — aws, az, or gcloud/gsutil, depending on the cloud — and uses the Pulumi Command provider to issue commands the CLI tool directly:
S3BucketFolderusesaws s3 syncAzureBlobFolderusesaz storage blob syncGoogleCloudFolderusesgsutil rsync
Files are one-way synchronized to the cloud, and any files that exist remotely but not locally are deleted from the cloud-storage container. All files are deleted from the cloud-storage container on pulumi destroy.
If the folder you're syncing contains a large number of files (e.g., many thousands), you may want to consider using this option.
The component does not yet support switching seamlessly between managedObjects: true and managedObjects: false, however, so if you find after deploying a given folder with managed objects that you'd prefer to use unmanaged objects instead (or vice-versa), we recommend creating a second bucket/storage container and folder and removing the first. You can generally do this within the scope of a single program update. For example:
name: synced-folder-aws-yaml
runtime: yaml
resources:
# Original bucket and synced-folder resources, using managed file objects.
#
# my-first-bucket:
# type: aws:s3:Bucket
# properties:
# acl: public-read
# website:
# indexDocument: index.html
# errorDocument: error.html
#
# my-first-synced-folder:
# type: synced-folder:index:S3BucketFolder
# properties:
# path: ./stuff
# bucketName: ${my-first-bucket.bucket}
# acl: public-read
# A new bucket and synced-folder using unmanaged file objects.
changed-my-mind-bucket:
type: aws:s3:Bucket
properties:
acl: public-read
changed-my-mind-synced-folder:
type: synced-folder:index:S3BucketFolder
properties:
path: ./stuff
bucketName: ${changed-my-mind-bucket.bucket}
acl: public-read
managedObjects: false