1. Docs
  2. Clouds
  3. AWS
  4. Get started

Get started with Pulumi & AWS

    Pulumi’s infrastructure-as-code SDK helps you create, deploy, and manage AWS containers, serverless functions, and infrastructure using familiar programming languages.

    This tutorial takes you through the steps to easily deploy a static website.

    Install Pulumi

    $ brew install pulumi/tap/pulumi
    $ curl -fsSL https://get.pulumi.com | sh
    > choco install pulumi
    All Windows examples in this tutorial assume you are running in PowerShell.

    Or explore more installation options.

    Install language runtime

    Install Node.js.

    Install Python version 3.7 or later. To reduce potential issues with setting up your Python environment on Windows or macOS, you should install Python through the official Python installer.

    pip is required to install dependencies. If you installed Python from source, with an installer from python.org, or via Homebrew you should already have pip. If Python is installed using your OS package manager, you may have to install pip separately, see Installing pip/setuptools/wheel with Linux Package Managers. For example, on Debian/Ubuntu you must run sudo apt install python3-venv python3-pip.

    If you're having trouble setting up Python on your machine, see Python 3 Installation & Setup Guide for detailed installation instructions on various operating systems and distributions.

    Install Go.

    Pulumi requires a supported version of Go— this typically refers to the two most recent minor releases. If you're using Linux, your distribution may not provide an up to date version of the Go compiler. To check what version of Go you have installed, use: go version.

    Install .NET SDK.

    Pulumi will need the dotnet executable in order to build and run your Pulumi .NET application. Ensure that the dotnet executable can be found on your path after installation.

    Install Java 11 or later and Apache Maven 3.6.1 or later.

    Pulumi will need the java, javac, and mvn executables in order to build and run your Pulumi Java application. Ensure that these executables can be found on your path after installation.

    Good news! You don’t have to install anything else to write Pulumi programs in YAML.

    Configure Pulumi to access AWS

    Pulumi requires cloud credentials to manage and provision resources. Use an IAM user account that has programmatic access with rights to deploy and manage resources.

    If you have previously installed and configured the AWS CLI, Pulumi will respect and use your configuration settings.

    If you do not have the AWS CLI installed or plan on using Pulumi from within a CI/CD pipeline, retrieve your access key ID and secret access key and then set the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables on your workstation:

    $ export AWS_ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID>
    $ export AWS_SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY>
    
    $ export AWS_ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID>
    $ export AWS_SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY>
    
    > $env:AWS_ACCESS_KEY_ID = "<YOUR_ACCESS_KEY_ID>"
    > $env:AWS_SECRET_ACCESS_KEY = "<YOUR_SECRET_ACCESS_KEY>"
    

    Create project

    Let’s create your first Pulumi project, stack, and program. Pulumi projects and stacks organize Pulumi code. Projects are similar to GitHub repos and stacks are an instance of code with separate configuration. Projects can have multiple stacks for different development environments or for different cloud configurations.

    $ mkdir quickstart && cd quickstart
    $ pulumi new aws-javascript
    
    $ mkdir quickstart && cd quickstart
    $ pulumi new aws-typescript
    
    $ mkdir quickstart && cd quickstart
    $ pulumi new aws-python
    
    $ mkdir quickstart && cd quickstart
    $ pulumi new aws-go
    
    $ mkdir quickstart && cd quickstart
    $ pulumi new aws-csharp
    
    $ mkdir quickstart && cd quickstart
    $ pulumi new aws-java
    
    $ mkdir quickstart && cd quickstart
    $ pulumi new aws-yaml
    

    The pulumi new command creates a Pulumi project with basic scaffolding.

    You will be asked for a project name and project description.

    This command will walk you through creating a Pulumi project.
    
    Enter a value or leave blank to accept the (default), and press <ENTER>.
    Press ^C at any time to quit.
    
    project name: (quickstart)
    project description: (A minimal AWS Pulumi program)
    Created project 'quickstart'
    

    Then you will be asked for a stack name.

    Please enter your desired stack name.
    To create a stack in an organization, use the format <org-name>/<stack-name> (e.g. `acmecorp/dev`).
    stack name: (dev)
    Created stack 'dev'
    

    Finally, you will be prompted for a configuration value for the stack, specifically the AWS region.

    aws:region: The AWS region to deploy into: (us-west-2)
    Saved config
    

    After the command completes, the project and stack will be ready.

    Review project

    Let’s review some of the generated project files:

    • Pulumi.yaml defines both the project and the program that manages your stack resources.
    • Program.cs is the Pulumi program that defines your stack resources.
    • src/main/java/myproject defines the project’s Java package root.
    • index.js index.ts main.py main.go Program.cs Program.fs Program.vb App.java Pulumi.yaml is the Pulumi program that defines your stack resources.
    "use strict";
    const pulumi = require("@pulumi/pulumi");
    const aws = require("@pulumi/aws");
    const awsx = require("@pulumi/awsx");
    
    // Create an AWS resource (S3 Bucket)
    const bucket = new aws.s3.Bucket("my-bucket");
    
    // Export the name of the bucket
    exports.bucketName = bucket.id;
    
    import * as pulumi from "@pulumi/pulumi";
    import * as aws from "@pulumi/aws";
    import * as awsx from "@pulumi/awsx";
    
    // Create an AWS resource (S3 Bucket)
    const bucket = new aws.s3.Bucket("my-bucket");
    
    // Export the name of the bucket
    export const bucketName = bucket.id;
    
    import pulumi
    from pulumi_aws import s3
    
    # Create an AWS resource (S3 Bucket)
    bucket = s3.Bucket('my-bucket')
    
    # Export the name of the bucket
    pulumi.export('bucket_name', bucket.id)
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-aws/sdk/v5/go/aws/s3"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
        pulumi.Run(func(ctx *pulumi.Context) error {
            // Create an AWS resource (S3 Bucket)
            bucket, err := s3.NewBucket(ctx, "my-bucket", nil)
            if err != nil {
                return err
            }
    
            // Export the name of the bucket
            ctx.Export("bucketName", bucket.ID())
            return nil
    	  })
    }
    
    using Pulumi;
    using Pulumi.Aws.S3;
    using System.Collections.Generic;
    
    return await Deployment.RunAsync(() =>
    {
       // Create an AWS resource (S3 Bucket)
       var bucket = new Bucket("my-bucket");
    
       // Export the name of the bucket
       return new Dictionary<string, object?>
       {
          ["bucketName"] = bucket.Id
       };
    });
    
    package myproject;
    
    import com.pulumi.Pulumi;
    import com.pulumi.aws.s3.Bucket;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                // Create an AWS resource (S3 Bucket)
                var bucket = new Bucket("my-bucket");
    
                // Export the name of the bucket
                ctx.export("bucketName", bucket.bucket());
            });
        }
    }
    
    name: quickstart
    runtime: yaml
    description: A minimal AWS Pulumi YAML program
    
    resources:
      # Create an AWS resource (S3 Bucket)
      my-bucket:
        type: aws:s3:Bucket
    
    outputs:
      # Export the name of the bucket
      bucketName: ${my-bucket.id}
    
    This Pulumi program creates a new S3 bucket and exports the name of the bucket.
    exports.bucketName = bucket.id;
    
    export const bucketName = bucket.id;
    
    pulumi.export('bucket_name', bucket.id)
    
    ctx.Export("bucketName", bucket.ID())
    
    return new Dictionary<string, object?>
    {
       ["bucketName"] = bucket.Id
    };
    
    ctx.export("bucketName", bucket.bucket());
    
    outputs:
      bucketName: ${my-bucket.id}
    

    Deploy stack

    Let’s deploy the stack:

    $ pulumi up
    

    This command evaluates the program and determines what resources need updates. A preview is shown that outlines the changes that will be made when you run the update:

    Previewing update (dev):
    
         Type                 Name            Plan
     +   pulumi:pulumi:Stack  quickstart-dev  create
     +   └─ aws:s3:Bucket     my-bucket       create
    
    Resources:
        + 2 to create
    
    Do you want to perform this update?
    > yes
      no
      details
    

    Once the preview has finished choose yes to create your new S3 bucket in AWS.

    Do you want to perform this update? yes
    Updating (dev):
    
         Type                 Name            Status
     +   pulumi:pulumi:Stack  quickstart-dev  created (4s)
     +   └─ aws:s3:Bucket     my-bucket       created (2s)
    
    Outputs:
        bucketName: "my-bucket-58ce361"
    
    Resources:
        + 2 created
    
    Duration: 5s
    
    $ pulumi stack output bucketName
    
    $ pulumi stack output bucketName
    
    $ pulumi stack output bucket_name
    
    $ pulumi stack output bucketName
    
    $ pulumi stack output bucketName
    
    $ pulumi stack output bucketName
    
    $ pulumi stack output bucketName
    

    Modify program

    Now that your S3 bucket is provisioned, let’s add a file to it. In the project directory, create a new file called index.html along with some content:

    echo '<html>
        <body>
            <h1>Hello, Pulumi!</h1>
        </body>
    </html>' > index.html
    
    echo '<html>
        <body>
            <h1>Hello, Pulumi!</h1>
        </body>
    </html>' > index.html
    
    @"
    <html>
      <body>
        <h1>Hello, Pulumi!</h1>
      </body>
    </html>
    "@ | Out-File -FilePath index.html
    

    Open the program and add this file to the S3 bucket. This uses Pulumi’s FileAsset resource to assign the content of the file to a new BucketObject:

    In index.js, create the BucketObject right after creating the bucket itself:

    // Create an S3 Bucket object
    const bucketObject = new aws.s3.BucketObject("index.html", {
        bucket: bucket.id,
        source: new pulumi.asset.FileAsset("./index.html")
    });
    

    In index.ts, create the BucketObject right after creating the bucket itself:

    // Create an S3 Bucket object
    const bucketObject = new aws.s3.BucketObject("index.html", {
        bucket: bucket.id,
        source: new pulumi.asset.FileAsset("./index.html")
    });
    

    In __main__.py, create a new bucket object by adding the following right after creating the bucket itself:

    # Create an S3 Bucket object
    bucketObject = s3.BucketObject(
        'index.html',
        bucket=bucket.id,
        source=pulumi.FileAsset('./index.html')
    )
    

    In main.go, create the BucketObject right after creating the bucket itself:

    // Create an S3 Bucket object
    _, err = s3.NewBucketObject(ctx, "index.html", &s3.BucketObjectArgs{
        Bucket:  bucket.ID(),
        Source: pulumi.NewFileAsset("./index.html"),
    })
    if err != nil {
        return err
    }
    

    In Program.cs, create a new BucketObject right after creating the bucket itself.

    // Create an S3 Bucket object
    var bucketObject = new BucketObject("index.html", new BucketObjectArgs
    {
        Bucket = bucket.BucketName,
        Source = new FileAsset("./index.html")
    });
    

    In index.js index.ts main.py main.go Program.cs Program.fs Program.vb App.java Pulumi.yaml , import the FileAsset, BucketObject, and BucketObjectArgs classes, then create the BucketObject right after creating the bucket itself.

    package myproject;
    
    import com.pulumi.Pulumi;
    import com.pulumi.core.Output;
    import com.pulumi.aws.s3.Bucket;
    import com.pulumi.aws.s3.BucketObject;
    import com.pulumi.aws.s3.BucketObjectArgs;
    import com.pulumi.asset.FileAsset;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                // Create an AWS resource (S3 Bucket)
                var bucket = new Bucket("my-bucket");
    
                // Create an S3 Bucket object
                new BucketObject("index.html", BucketObjectArgs.builder()
                    .bucket(bucket.id())
                    .source(new FileAsset("./index.html"))
                    .build()
                );
    
                // Export the name of the bucket
                ctx.export("bucketName", bucket.bucket());
            });
        }
    }
    

    In index.js index.ts main.py main.go Program.cs Program.fs Program.vb App.java Pulumi.yaml , create the BucketObject right below the bucket itself.

    name: quickstart
    runtime: yaml
    description: A minimal AWS Pulumi YAML program
    
    resources:
      # Create an AWS resource (S3 Bucket)
      my-bucket:
        type: aws:s3:Bucket
    
      # Create an S3 Bucket object
      index.html:
        type: aws:s3:BucketObject
        properties:
          bucket: ${my-bucket}
          source:
            fn::fileAsset: ./index.html
    
    outputs:
      # Export the name of the bucket
      bucketName: ${my-bucket.id}
    

    This bucket object is part of the Bucket that we deployed earlier because we reference the bucket name in the properties of the bucket object.

    We refer to this relationship as the BucketObject being a child resource of the S3 Bucket that is the parent resource.

    Deploy changes

    Deploy the changes by running pulumi up again.

    $ pulumi up
    

    Pulumi will run the preview step of the update, which computes the minimally disruptive change to achieve the desired state described by the program.

    Previewing update (dev):
    
         Type                    Name            Plan
         pulumi:pulumi:Stack     quickstart-dev
     +   └─ aws:s3:BucketObject  index.html      create
    
    Resources:
        + 1 to create
        2 unchanged
    
    Do you want to perform this update?
    > yes
      no
      details
    

    Choose yes to proceed with the update and upload the index.html file to your bucket:

    Do you want to perform this update? yes
    Updating (dev):
    
         Type                    Name            Status
         pulumi:pulumi:Stack     quickstart-dev
     +   └─ aws:s3:BucketObject  index.html      created (0.98s)
    
    
    Outputs:
        bucketName: "my-bucket-58ce361"
    
    Resources:
        + 1 created
        2 unchanged
    
    Duration: 3s
    

    Verify the object was created in your bucket by checking the AWS Console or by running the following AWS CLI command:

    $ aws s3 ls $(pulumi stack output bucketName)
    
    $ aws s3 ls $(pulumi stack output bucketName)
    
    $ aws s3 ls $(pulumi stack output bucket_name)
    
    $ aws s3 ls $(pulumi stack output bucketName)
    
    $ aws s3 ls $(pulumi stack output bucketName)
    
    $ aws s3 ls $(pulumi stack output bucketName)
    
    $ aws s3 ls $(pulumi stack output bucketName)
    

    Notice that your index.html file has been added to the bucket:

    2023-04-20 17:01:06        118 index.html
    

    Modify program again

    Update the Bucket declaration to add a website property and make index.html the home page of the website:

    const bucket = new aws.s3.Bucket("my-bucket", {
        website: {
            indexDocument: "index.html",
        },
    });
    
    bucket = s3.Bucket("my-bucket",
        website=s3.BucketWebsiteArgs(
            index_document="index.html",
        ),
    )
    
    bucket, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{
        Website: &s3.BucketWebsiteArgs{
            IndexDocument: pulumi.String("index.html"),
        },
    })
    if err != nil {
        return err
    }
    
    using Pulumi.Aws.S3.Inputs;
    
    var bucket = new Bucket("my-bucket", new()
    {
        Website = new BucketWebsiteArgs
        {
            IndexDocument = "index.html",
        },
    });
    
    import com.pulumi.aws.s3.BucketArgs;
    import com.pulumi.aws.s3.inputs.BucketWebsiteArgs;
    
    var bucket = new Bucket("my-bucket", BucketArgs.builder()
        .website(BucketWebsiteArgs.builder()
            .indexDocument("index.html")
            .build())
        .build());
    
    my-bucket:
      type: aws:s3:Bucket
      properties:
        website:
          indexDocument: index.html
    

    Lastly, you’ll make a few adjustments to make these resources accessible on the Internet.

    For the bucket itself, you’ll need two new resources: a BucketOwnershipControls resource, to define the bucket’s file-ownership settings, and a BucketPublicAccessBlock resource to allow the bucket to be accessed publicly.

    For the BucketObject, you’ll need an access-control (ACL) setting of public-read to allow the page to be accessed anonymously (e.g., in a browser) and a content type of text/html to tell AWS to serve the file as a web page.

    const ownershipControls = new aws.s3.BucketOwnershipControls("ownership-controls", {
        bucket: bucket.id,
        rule: {
            objectOwnership: "ObjectWriter"
        }
    });
    
    const publicAccessBlock = new aws.s3.BucketPublicAccessBlock("public-access-block", {
        bucket: bucket.id,
        blockPublicAcls: false,
    });
    
    const bucketObject = new aws.s3.BucketObject("index.html", {
        bucket: bucket.id,
        source: new pulumi.asset.FileAsset("./index.html"),
        contentType: "text/html",
        acl: "public-read",
    }, { dependsOn: publicAccessBlock });
    
    ownership_controls = s3.BucketOwnershipControls(
        'ownership-controls',
        bucket=bucket.id,
        rule=s3.BucketOwnershipControlsRuleArgs(
            object_ownership='ObjectWriter',
        ),
    )
    
    public_access_block = s3.BucketPublicAccessBlock(
        'public-access-block', bucket=bucket.id, block_public_acls=False
    )
    
    bucket_object = s3.BucketObject(
        'index.html',
        bucket=bucket.id,
        source=pulumi.FileAsset('index.html'),
        content_type='text/html',
        acl='public-read',
        opts=pulumi.ResourceOptions(depends_on=[public_access_block]),
    )
    
    _, err = s3.NewBucketOwnershipControls(ctx, "ownership-controls", &s3.BucketOwnershipControlsArgs{
        Bucket: bucket.ID(),
        Rule: &s3.BucketOwnershipControlsRuleArgs{
            ObjectOwnership: pulumi.String("ObjectWriter"),
        },
    })
    if err != nil {
        return err
    }
    
    publicAccessBlock, err := s3.NewBucketPublicAccessBlock(ctx, "public-access-block", &s3.BucketPublicAccessBlockArgs{
        Bucket:          bucket.ID(),
        BlockPublicAcls: pulumi.Bool(false),
    })
    if err != nil {
        return err
    }
    
    _, err = s3.NewBucketObject(ctx, "index.html", &s3.BucketObjectArgs{
        Bucket:      bucket.ID(),
        Source:      pulumi.NewFileAsset("index.html"),
        ContentType: pulumi.String("text/html"),
        Acl:         pulumi.String("public-read"),
    }, pulumi.DependsOn([]pulumi.Resource{
        publicAccessBlock,
    }))
    if err != nil {
        return err
    }
    
    var ownershipControls = new BucketOwnershipControls("ownership-controls", new()
    {
        Bucket = bucket.Id,
        Rule = new BucketOwnershipControlsRuleArgs
        {
            ObjectOwnership = "ObjectWriter",
        },
    });
    
    var publicAccessBlock = new BucketPublicAccessBlock("public-access-block", new()
    {
        Bucket = bucket.Id,
        BlockPublicAcls = false,
    });
    
    var indexHtml = new BucketObject("index.html", new()
    {
        Bucket = bucket.Id,
        Source = new FileAsset("./index.html"),
        ContentType = "text/html",
        Acl = "public-read",
    }, new CustomResourceOptions
    {
        DependsOn = new[]
        {
            publicAccessBlock,
        },
    });
    
    import com.pulumi.aws.s3.BucketOwnershipControls;
    import com.pulumi.aws.s3.BucketOwnershipControlsArgs;
    import com.pulumi.aws.s3.inputs.BucketOwnershipControlsRuleArgs;
    import com.pulumi.aws.s3.BucketPublicAccessBlock;
    import com.pulumi.aws.s3.BucketPublicAccessBlockArgs;
    import com.pulumi.resources.CustomResourceOptions;
    import com.pulumi.asset.FileAsset;
    
    var ownershipControls = new BucketOwnershipControls("ownershipControls", BucketOwnershipControlsArgs.builder()
        .bucket(bucket.id())
        .rule(BucketOwnershipControlsRuleArgs.builder()
            .objectOwnership("ObjectWriter")
            .build())
        .build());
    
    var publicAccessBlock = new BucketPublicAccessBlock("publicAccessBlock", BucketPublicAccessBlockArgs.builder()
        .bucket(bucket.id())
        .blockPublicAcls(false)
        .build());
    
    var indexHtml = new BucketObject("index.html", BucketObjectArgs.builder()
        .bucket(bucket.id())
        .source(new FileAsset("./index.html"))
        .contentType("text/html")
        .acl("public-read")
        .build(), CustomResourceOptions.builder()
            .dependsOn(publicAccessBlock)
            .build());
    
    ownership-controls:
      type: aws:s3:BucketOwnershipControls
      properties:
        bucket: ${my-bucket.id}
        rule:
          objectOwnership: ObjectWriter
    
    public-access-block:
      type: aws:s3:BucketPublicAccessBlock
      properties:
        bucket: ${my-bucket.id}
        blockPublicAcls: false
    
    index.html:
      type: aws:s3:BucketObject
      properties:
        bucket: ${my-bucket.id}
        source: ${homepage}
        contentType: text/html
        acl: public-read
      options:
        dependsOn:
          - ${public-access-block}
    

    The BucketObject includes the Pulumi resource option dependsOn. This setting tells Pulumi that the BucketObject relies indirectly on the BucketPublicAccessBlock, which is responsible for enabling public access to its contents.

    At the end of the program, export the bucket’s endpoint URL:

    exports.bucketEndpoint = pulumi.interpolate`http://${bucket.websiteEndpoint}`;
    
    export const bucketEndpoint = pulumi.interpolate`http://${bucket.websiteEndpoint}`;
    
    pulumi.export('bucket_endpoint', pulumi.Output.concat('http://', bucket.website_endpoint))
    
    ctx.Export("bucketEndpoint", bucket.WebsiteEndpoint.ApplyT(func(websiteEndpoint string) (string, error) {
        return fmt.Sprintf("http://%v", websiteEndpoint), nil
    }).(pulumi.StringOutput))
    
    return new Dictionary<string, object?>
    {
        // ...
        ["bucketEndpoint"] = bucket.WebsiteEndpoint.Apply(websiteEndpoint => $"http://{websiteEndpoint}"),
    };
    
    // ...
    ctx.export("bucketEndpoint", bucket.websiteEndpoint().applyValue(websiteEndpoint -> String.format("http://%s", websiteEndpoint)));
    
    outputs:
      # ...
      bucketEndpoint: http://${my-bucket.websiteEndpoint}
    

    Deploy website

    Update your stack to deploy these changes to AWS:

    $ pulumi up
    

    Review the preview of the changes before deploying:

    Previewing update (dev):
    
         Type                               Name                 Plan       Info
         pulumi:pulumi:Stack                quickstart-dev
     ~   ├─ aws:s3:Bucket                   my-bucket            update     [diff: +website]
     +   ├─ aws:s3:BucketOwnershipControls  ownership-controls   create
     +   ├─ aws:s3:BucketPublicAccessBlock  public-access-block  create
     ~   └─ aws:s3:BucketObject             index.html           update     [diff: ~acl,contentType]
    
    Outputs:
      + bucketEndpoint: output<string>
    
    Resources:
        + 2 to create
        ~ 2 to update
        4 changes. 1 unchanged
    
    Do you want to perform this update?
    > yes
      no
      details
    

    Choose yes to perform the deployment:

    Do you want to perform this update? yes
    Updating (dev):
    
         Type                               Name                 Status              Info
         pulumi:pulumi:Stack                quickstart-dev
     ~   ├─ aws:s3:Bucket                   my-bucket            updated (3s)        [diff: +website]
     +   ├─ aws:s3:BucketOwnershipControls  ownership-controls   created (0.84s)
     +   ├─ aws:s3:BucketPublicAccessBlock  public-access-block  created (1s)
     ~   └─ aws:s3:BucketObject             index.html           updated (0.53s)     [diff: ~acl,contentType]
    
    Outputs:
      + bucketEndpoint: "http://my-bucket-dfd6bd0.s3-website-us-east-1.amazonaws.com"
        bucketName    : "my-bucket-dfd6bd0"
    
    Resources:
        + 2 created
        ~ 2 updated
        4 changes. 1 unchanged
    
    Duration: 8s
    

    Check out your new website at the URL or make a curl request:

    $ curl $(pulumi stack output bucketEndpoint)
    
    $ curl $(pulumi stack output bucketEndpoint)
    
    $ curl $(pulumi stack output bucket_endpoint)
    
    $ curl $(pulumi stack output bucketEndpoint)
    
    $ curl $(pulumi stack output bucketEndpoint)
    
    $ curl $(pulumi stack output bucketEndpoint)
    
    $ curl $(pulumi stack output bucketEndpoint)
    
    <html>
        <body>
            <h1>Hello, Pulumi!</h1>
        </body>
    </html>
    

    Destroy stack

    Now that you’ve seen how to deploy changes to our program, let’s clean up and tear down the resources that are part of your stack.

    To destroy resources, run the following:

    $ pulumi destroy
    
    Previewing destroy (dev):
    
         Type                               Name                 Plan
     -   pulumi:pulumi:Stack                quickstart-dev       delete
     -   ├─ aws:s3:BucketObject             index.html           delete
     -   ├─ aws:s3:BucketOwnershipControls  ownership-controls   delete
     -   ├─ aws:s3:BucketPublicAccessBlock  public-access-block  delete
     -   └─ aws:s3:Bucket                   my-bucket            delete
    
    Outputs:
      - bucketEndpoint: "http://my-bucket-dfd6bd0.s3-website-us-east-1.amazonaws.com"
      - bucketName    : "my-bucket-dfd6bd0"
    
    Resources:
        - 5 to delete
    
    Do you want to perform this destroy? yes
    Destroying (dev):
    
         Type                               Name                 Status
     -   pulumi:pulumi:Stack                quickstart-dev       deleted
     -   ├─ aws:s3:BucketObject             index.html           deleted (1s)
     -   ├─ aws:s3:BucketPublicAccessBlock  public-access-block  deleted (0.28s)
     -   ├─ aws:s3:BucketOwnershipControls  ownership-controls   deleted (0.47s)
     -   └─ aws:s3:Bucket                   my-bucket            deleted (0.39s)
    
    Outputs:
      - bucketEndpoint: "http://my-bucket-dfd6bd0.s3-website-us-east-1.amazonaws.com"
      - bucketName    : "my-bucket-dfd6bd0"
    
    Resources:
        - 5 deleted
    
    Duration: 4s
    

    To delete the stack itself, run pulumi stack rm. This removes the stack and the update history from Pulumi Cloud.

    Next steps

    Congrats! You’ve deployed your first project on AWS with Pulumi. Try a next step!

      Register for Pulumi UP, June 15, 2023