1. Packages
  2. Synced Folder
Synced Folder v0.11.1 published on Wednesday, Aug 2, 2023 by Pulumi

Synced Folder

synced-folder logo
Synced Folder v0.11.1 published on Wednesday, Aug 2, 2023 by Pulumi

    A Pulumi component that synchronizes the contents of a local folder to any Amazon S3 bucket, Azure Blob Storage container, or Google Cloud Storage bucket. Use this component to publish content easily to your cloud provider of choice.

    Usage

    Sync to Amazon S3

    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,
    });
    
    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,
    )
    
    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
    	})
    }
    
    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,
        });
    });
    
    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
    

    Sync to Azure Blob Storage

    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",
    });
    
    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",
    ))
    
    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
    	})
    }
    
    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",
        });
    });
    
    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
    

    Sync to Google Cloud Storage

    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",
    });
    
    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",
        ),
    )
    
    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
    	})
    }
    
    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",
        });
    });
    
    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
    

    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:

    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,
    });
    
    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,
    )
    
    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),
    })
    
    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,
    });
    
    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
    

    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:

    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
    
    synced-folder logo
    Synced Folder v0.11.1 published on Wednesday, Aug 2, 2023 by Pulumi