Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

611 lines
14 KiB
Markdown
Raw Permalink Normal View History

---
title_tag: Deploy the Changes | AWS
title: Deploy changes
h1: "Pulumi & AWS: Deploy changes"
meta_desc: Learn how to deploy changes to an AWS project in this guide.
weight: 7
menu:
clouds:
parent: aws-get-started
identifier: aws-get-started-deploy-changes
aliases:
- /docs/quickstart/aws/deploy-changes/
- /docs/get-started/aws/deploy-changes/
---
Now let's deploy your changes.
```bash
$ 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
```
Choosing `yes` will 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
```
Once the update has completed, you can verify the object was created in your bucket by checking the AWS Console or by running the following AWS CLI command:
{{% choosable language javascript %}}
```bash
$ aws s3 ls $(pulumi stack output bucketName)
```
{{% /choosable %}}
{{% choosable language typescript %}}
```bash
$ aws s3 ls $(pulumi stack output bucketName)
```
{{% /choosable %}}
{{% choosable language python %}}
```bash
$ aws s3 ls $(pulumi stack output bucket_name)
```
{{% /choosable %}}
{{% choosable language go %}}
```bash
$ aws s3 ls $(pulumi stack output bucketName)
```
{{% /choosable %}}
{{% choosable language csharp %}}
```bash
$ aws s3 ls $(pulumi stack output bucketName)
```
{{% /choosable %}}
{{% choosable language java %}}
```bash
$ aws s3 ls $(pulumi stack output bucketName)
```
{{% /choosable %}}
{{% choosable language yaml %}}
```bash
$ aws s3 ls $(pulumi stack output bucketName)
```
{{% /choosable %}}
Notice that your `index.html` file has been added to the bucket:
```bash
2023-04-20 17:01:06 118 index.html
```
Now that `index.html` is in the bucket, update the program to turn the bucket into a website.
## Update the program
Update the `Bucket` declaration to add a `website` property and make `index.html` the home page of the website:
{{< chooser language "javascript,typescript,python,go,csharp,java,yaml" / >}}
{{% choosable language "javascript,typescript" %}}
```typescript
const bucket = new aws.s3.Bucket("my-bucket", {
website: {
indexDocument: "index.html",
},
});
```
{{% /choosable %}}
{{% choosable language python %}}
```python
bucket = s3.Bucket("my-bucket",
website=s3.BucketWebsiteArgs(
index_document="index.html",
),
)
```
{{% /choosable %}}
{{% choosable language go %}}
```go
bucket, err := s3.NewBucket(ctx, "my-bucket", &s3.BucketArgs{
Website: &s3.BucketWebsiteArgs{
IndexDocument: pulumi.String("index.html"),
},
})
if err != nil {
return err
}
```
{{% /choosable %}}
{{% choosable language csharp %}}
```csharp
using Pulumi.Aws.S3.Inputs;
var bucket = new Bucket("my-bucket", new()
{
Website = new BucketWebsiteArgs
{
IndexDocument = "index.html",
},
});
```
{{% /choosable %}}
{{% choosable language java %}}
```java
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());
```
{{% /choosable %}}
{{% choosable language yaml %}}
```yaml
my-bucket:
type: aws:s3:Bucket
properties:
website:
indexDocument: index.html
```
{{% /choosable %}}
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. Add the following lines to your program, updating the `BucketObject` in place:
{{< chooser language "javascript,typescript,python,go,csharp,java,yaml" / >}}
{{% choosable language "javascript,typescript" %}}
```typescript
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 });
```
{{% /choosable %}}
{{% choosable language python %}}
```python
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]),
)
```
{{% /choosable %}}
{{% choosable language go %}}
```go
_, 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
}
```
{{% /choosable %}}
{{% choosable language csharp %}}
```csharp
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,
},
});
```
{{% /choosable %}}
{{% choosable language java %}}
```java
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());
```
{{% /choosable %}}
{{% choosable language yaml %}}
```yaml
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}
```
{{% /choosable %}}
Note that the `BucketObject` also includes the Pulumi resource _option_ [`dependsOn`](/docs/concepts/options/dependson/). This setting tells Pulumi that the `BucketObject` relies indirectly on the `BucketPublicAccessBlock`, which is responsible for enabling public access to its contents. If you omitted this setting, the attempt to grant `public-read` access to `index.html` would fail, as all S3 buckets and their objects are blocked from public access by default.
Finally, at the end of the program, export the resulting buckets endpoint URL so you can browse to it easily:
{{% choosable language javascript %}}
```javascript
exports.bucketEndpoint = pulumi.interpolate`http://${bucket.websiteEndpoint}`;
```
{{% /choosable %}}
{{% choosable language typescript %}}
```typescript
export const bucketEndpoint = pulumi.interpolate`http://${bucket.websiteEndpoint}`;
```
{{% /choosable %}}
{{% choosable language python %}}
```python
pulumi.export('bucket_endpoint', pulumi.Output.concat('http://', bucket.website_endpoint))
```
{{% /choosable %}}
{{% choosable language go %}}
```go
ctx.Export("bucketEndpoint", bucket.WebsiteEndpoint.ApplyT(func(websiteEndpoint string) (string, error) {
return fmt.Sprintf("http://%v", websiteEndpoint), nil
}).(pulumi.StringOutput))
```
{{% /choosable %}}
{{% choosable language csharp %}}
```csharp
return new Dictionary<string, object?>
{
// ...
["bucketEndpoint"] = bucket.WebsiteEndpoint.Apply(websiteEndpoint => $"http://{websiteEndpoint}"),
};
```
{{% /choosable %}}
{{% choosable language java %}}
```java
// ...
ctx.export("bucketEndpoint", bucket.websiteEndpoint().applyValue(websiteEndpoint -> String.format("http://%s", websiteEndpoint)));
```
{{% /choosable %}}
{{% choosable language yaml %}}
```yaml
outputs:
# ...
bucketEndpoint: http://${my-bucket.websiteEndpoint}
```
{{% /choosable %}}
## Deploy the website
Update your stack to deploy these changes to AWS:
```bash
$ pulumi up
```
Again, you'll see a preview of the changes before they're deployed:
```
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
```
When the deployment completes, you can check out your new website at the URL in the `Outputs` section of your update or make a `curl` request and see the contents of `index.html` in your terminal:
{{% choosable language javascript %}}
```bash
$ curl $(pulumi stack output bucketEndpoint)
```
{{% /choosable %}}
{{% choosable language typescript %}}
```bash
$ curl $(pulumi stack output bucketEndpoint)
```
{{% /choosable %}}
{{% choosable language python %}}
```bash
$ curl $(pulumi stack output bucket_endpoint)
```
{{% /choosable %}}
{{% choosable language go %}}
```bash
$ curl $(pulumi stack output bucketEndpoint)
```
{{% /choosable %}}
{{% choosable language csharp %}}
```bash
$ curl $(pulumi stack output bucketEndpoint)
```
{{% /choosable %}}
{{% choosable language java %}}
```bash
$ curl $(pulumi stack output bucketEndpoint)
```
{{% /choosable %}}
{{% choosable language yaml %}}
```bash
$ curl $(pulumi stack output bucketEndpoint)
```
{{% /choosable %}}
And you should see:
```bash
<html>
<body>
<h1>Hello, Pulumi!</h1>
</body>
</html>
```
Next, you'll destroy the resources.
{{< get-started-stepper >}}