diff --git a/aws-go-s3-folder/.gitignore b/aws-go-s3-folder/.gitignore new file mode 100644 index 000000000..e672b9c1b --- /dev/null +++ b/aws-go-s3-folder/.gitignore @@ -0,0 +1,4 @@ +/bin/ +/node_modules/ +/.pulumi/ +Pulumi.*.yaml diff --git a/aws-go-s3-folder/Pulumi.yaml b/aws-go-s3-folder/Pulumi.yaml new file mode 100644 index 000000000..39247f48e --- /dev/null +++ b/aws-go-s3-folder/Pulumi.yaml @@ -0,0 +1,3 @@ +name: aws-go-s3-folder +runtime: go +description: A static website hosted on AWS S3. diff --git a/aws-go-s3-folder/README.md b/aws-go-s3-folder/README.md new file mode 100644 index 000000000..caffac0f0 --- /dev/null +++ b/aws-go-s3-folder/README.md @@ -0,0 +1,78 @@ +# Static Website Hosted on AWS S3 in Go + +A static website that uses [S3's website support](https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html). +For a detailed walkthrough of this example, see +[Part 2 of the Pulumi quickstart](https://docs.pulumi.com/quickstart/part2.html). + +## Deploying and running the program + +1. Create a new stack: + + ```bash + $ pulumi stack init website-testing + ``` + +2. Set the AWS region: + + ``` + $ pulumi config set aws:region us-west-2 + ``` + +3. Compile the Go program and ensure it's on your path (such as with `$GOPATH`): + + ``` + $ go install . + ``` + +4. Run `pulumi update` to preview and deploy changes. + + ```bash + $ pulumi update + Previewing stack 'website-testing' + Previewing changes: + ... + + Performing changes: + + #: Resource Type Name Status Extra Inf + 1: pulumi:pulumi:Stack aws-js-s3-folder-website-testing + created + 2: aws:s3:Bucket s3-website-bucket + created + 3: aws:s3:BucketPolicy bucketPolicy + created + 4: aws:s3:BucketObject favicon.png + created + 5: aws:s3:BucketObject index.html + created + + info: 5 changes performed: + + 5 resources created + Update duration: 8.827698762s + + Permalink: https://pulumi.com/lindydonna/examples/aws-js-s3-folder/website-testing/updates/1 + ``` + +5. To see the resources that were created, run `pulumi stack output`: + + ```bash + $ pulumi stack output + Current stack outputs (2): + OUTPUT VALUE + bucketName s3-website-bucket-e7c0411 + websiteUrl s3-website-bucket-e7c0411.s3-website-us-west-2.amazonaws.com + ``` + +6. To see that the S3 objects exist, you can either use the AWS Console or the AWS CLI: + + ```bash + $ aws s3 ls $(pulumi stack output bucketName) + 2018-04-17 15:40:47 13731 favicon.png + 2018-04-17 15:40:48 249 index.html + ``` + +7. Open the site URL in a browser to see both the rendered HTML and the favicon: + + ```bash + $ pulumi stack output websiteUrl + s3-website-bucket-8533d8b.s3-website-us-west-2.amazonaws.com + ``` + + ![Hello S3 example](images/part2-website.png) + +8. To clean up resources, run `pulumi destroy` and answer the confirmation question at the prompt. diff --git a/aws-go-s3-folder/images/part2-website.png b/aws-go-s3-folder/images/part2-website.png new file mode 100644 index 000000000..c5c4750cd Binary files /dev/null and b/aws-go-s3-folder/images/part2-website.png differ diff --git a/aws-go-s3-folder/main.go b/aws-go-s3-folder/main.go new file mode 100644 index 000000000..5cfad1694 --- /dev/null +++ b/aws-go-s3-folder/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "mime" + "path/filepath" + + "github.com/pulumi/pulumi-aws/sdk/go/aws/s3" + "github.com/pulumi/pulumi/sdk/go/pulumi" + "github.com/pulumi/pulumi/sdk/go/pulumi/asset" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + // Create a bucket and expose a website index document + siteBucket, err := s3.NewBucket(ctx, "s3-website-bucket", &s3.BucketArgs{ + Website: map[string]interface{}{ + "indexDocument": "index.html", + }, + }) + if err != nil { + return err + } + + siteDir := "www" // directory for content files + + // For each file in the directory, create an S3 object stored in `siteBucket` + files, err := ioutil.ReadDir(siteDir) + if err != nil { + return err + } + for _, item := range files { + name := item.Name() + filePath := filepath.Join(siteDir, name) + if _, err := s3.NewBucketObject(ctx, filePath, &s3.BucketObjectArgs{ + Bucket: siteBucket.ID(), // reference to the s3.Bucket object + Source: asset.NewFileAsset(filePath), // use FileAsset to point to a file + ContentType: mime.TypeByExtension(name), // set the MIME type of the file + }); err != nil { + return err + } + } + + // Set the access policy for the bucket so all objects are readable + if _, err := s3.NewBucketPolicy(ctx, "bucketPolicy", &s3.BucketPolicyArgs{ + Bucket: siteBucket.ID(), // refer to the bucket created earlier + Policy: siteBucket.ID().Apply(publicReadPolicyForBucket), // use output property `siteBucket.bucket` + }); err != nil { + return err + } + + // Stack exports + ctx.Export("bucketName", siteBucket.ID) + ctx.Export("websiteUrl", siteBucket.WebsiteEndpoint) + return nil + }) +} + +// Create an S3 Bucket Policy to allow public read of all objects in bucket. +func publicReadPolicyForBucket(bucketName pulumi.ID) (interface{}, error) { + policy, _ := json.Marshal(map[string]interface{}{ + "Version": "2012-10-17", + "Statement": []map[string]interface{}{ + { + "Effect": "Allow", + "Principal": "*", + "Action": []string{ + "s3:GetObject", + }, + "Resource": []string{ + fmt.Sprintf("arn:aws:s3:::%s/*", bucketName), // policy refers to bucket name explicitly + }, + }, + }, + }) + return string(policy), nil +} diff --git a/aws-go-s3-folder/www/favicon.png b/aws-go-s3-folder/www/favicon.png new file mode 100644 index 000000000..ad4baeb6f Binary files /dev/null and b/aws-go-s3-folder/www/favicon.png differ diff --git a/aws-go-s3-folder/www/index.html b/aws-go-s3-folder/www/index.html new file mode 100644 index 000000000..5d470193e --- /dev/null +++ b/aws-go-s3-folder/www/index.html @@ -0,0 +1,6 @@ + + Hello S3 + + +

Hello, world!

Made with ❤️ with Pulumi

+