Skip to content

AWS S3 (Object Storage)

S3 Buckets

Stelvio supports creating and managing S3 buckets using the Bucket component.

Create an S3 bucket and link it to an API Gateway handler:

@app.run
def run() -> None:
    bucket = Bucket("todo-bucket")

    api = Api("todo-api")
    api.route("GET", "/write", handler="functions/write.get", links=[bucket])
    api.route("GET", "/read", handler="functions/read.get", links=[bucket])

Using the linking mechanism, you can easily access the S3 bucket in your Lambda functions using the regular boto3 library:

import boto3
from stlv_resources import Resources


def get(event, context):
    s3_client = boto3.client("s3")
    bucket_name = Resources.todo_bucket.bucket_name
    s3_client.put_object(Bucket=bucket_name, Key="hello.txt", Body="Hello, World!")
    return {"statusCode": 200, "body": "Hello, World!"}

Public Access

By default, all public access is blocked for S3 buckets created with the Bucket component.

You can change that behaviour by setting the access argument to 'public':

@app.run
def run() -> None:
    bucket = Bucket("todo-bucket", access="public")
How access is implemented

Internally, access to S3 buckets is handled by the BucketPublicAccessBlock resource.

It is created with the followign parameters:

    block_public_acls=<Value>,
    block_public_policy=<Value>,
    ignore_public_acls=<Value>,
    restrict_public_buckets=<Value>,

<Value> is set to either False for public access or True for private access (default).

Parameter Description
block_public_acls Whether to block public ACLs.
block_public_policy Whether to block public policies.
ignore_public_acls Whether to ignore public ACLs.
restrict_public_buckets Whether to restrict public buckets.

Additionally, a policy for s3:GetObject is created to allow public read access to the objects in the bucket if access is set to 'public'.

See the Pulumi Documentation for more information.

Parameters

Parameter Description
versioning The versioning configuration for the S3 bucket. Boolean. Default is False.
access The access configuration for the S3 bucket. Either None (default) or 'public'.

Resources

Resource Description
bucket The S3 bucket created by the Bucket component.
public_access_block The BucketPublicAccessBlock resource created by the Bucket component.
bucket_policy The BucketPolicy resource created by the Bucket component if access is set to 'public'.

Static Websites

Stelvio can create and manage S3 buckets for static website hosting using the S3StaticWebsite component.

Create a static website from a directory using the S3StaticWebsite component:

@app.run
def run() -> None:
    config = mkdocs.config.load_config("mkdocs.yml")
    mkdocs.commands.build.build(config)

    _ = S3StaticWebsite(
        "s3-static-mkdocs",
        custom_domain="s3-2." + CUSTOM_DOMAIN_NAME,
        directory="site"
    )
  • Creates an S3 bucket for static website hosting
  • Creates a CloudFront distribution for the S3 bucket, so that it is compatible with 3rd party DNS providers
  • Attaching a domain name to a S3 bucket (without CloudFront) only works with AWS Route 53, because you'd need to create a CNAME pointing to the S3 bucket name. This is not possible with other DNS providers as they don't have access to the S3 bucket name in AWS.
  • Creates an S3 object for each file in the static website directory
  • Automatically creates a DNS record for the CloudFront distribution if a DNS provider is configured

Handling files (assets) of a static website

The S3StaticWebsite component automatically uploads all files in the specified directory to the S3 bucket.

The directory parameter is optional, though. If omitted, an empty S3 bucket is created and you are responsible for uploading the files (assets) to the bucket.

The custom_domain parameter is also optional. If omitted, no DNS record is created for the CloudFront distribution and you can access the static website using the CloudFront domain name (<distribution_id>.cloudfront.net).

In the following example, we use the mkdocs library to build a static website from Markdown files and upload the generated files to the S3 bucket:

@app.run
def run() -> None:
    config = mkdocs.config.load_config("mkdocs.yml")
    mkdocs.commands.build.build(config)

    website = S3StaticWebsite(
        "s3-static-mkdocs",
        custom_domain="s3-2." + CUSTOM_DOMAIN_NAME,
    )

    # Upload files to the bucket
    s3_bucket = website.bucket
    boto3_client = boto3.client("s3")
    boto3_client.put_object(
        Bucket=s3_bucket.bucket_name, Key="index.html", Body="<h1>Hello, World!</h1>"
    )

In both cases, the files uploaded to your static website are considered part of your infrastructure. Thus, the files would be automatically deployed whenever you run stlv deploy. However, in the latter case, uploaded files are not part of your (Pulumi) state and thus not tracked.

Using the stlv_resources module, you can access the S3 bucket and manage the files (assets) in your static website, should you decide that part should not be part of your deployment. Note that at the moment, you can get the arn of the bucket via stvl_resources only from within a Lambda function.

Note

If you decide to upload your file assets manually, you must also take care of removing the files from the bucket before running stlv destroy, as the AWS API does not allow deleting a non-empty S3 bucket.

!! note

The S3StaticWebsite component is designed for most use cases of static websites. The error handler for 404 is by default set to `error.html`. This will be exposed to the user as a parameter in the future.

Exposing a bucket along with other resources

If you want to expose a bucket along with other resources, such as an API Gateway, you can use the Router component.

Parameters

Parameter Description
custom_domain The custom domain name for the static website. Optional. If provided, a DNS record will be created for the CloudFront distribution. Optional. A str.
directory The directory containing the static website files to be uploaded to the S3 bucket. Optional. Either a Path like object or a str.

Resources

Resource Description
bucket The S3 bucket created for the static website.
files The files uploaded to the S3 bucket for the static website.
cloudfront_distribution The CloudFront distribution created for the static website.