Git Product home page Git Product logo

Swift Cloud

The fastest way to build and deploy server side Swift applications.

Swift Cloud is based on the premise that infrastructure should be defined along side your application, in the same language as your application. In our case, Swift. Define a new target, describe your infrastructure, and deploy it with a single command. There's no Dockerfiles, no Terrafrom configurations, no Node.js packages. Everything is defined in Swift and the complex configuration is handled behind the scenes, using modern architecture best practices.

AWS.WebServer(
    "my-vapor-app",
    targetName: "App",
    concurrency: 1,
    autoScaling: .init(
        maximumConcurrency: 10,
        metrics: [.cpu(50), .memory(50)]
    )
)

How it works

The Swift Cloud package is powered by Pulumi. Specifically, the SDK vends Swift components that are compiled into Pulumi YAML files, and then the Pulumi CLI is used to deploy your application. You do not need a Pulumi account to use Swift Cloud, nor do you need to install Pulumi CLI on your machine. Everything is managed by the SDK and written to a .cloud directory in your project.

Get Started

Prepare your environment

Setup Docker

In order to use Swift Cloud you need to have Docker installed on your machine. This is a short term limitation until Swift 6 where we will be able to natively cross-compile to Linux and other SDKs.

If you're on a Mac the easiest way to install Docker is OrbStack. Simply download OrbStack and run the installer.

Setup AWS

Today, Swift Cloud only supports AWS. You will need to have an AWS account and AWS credentials loaded on your machine or in the typical environment variables.

export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...

If you're on a Mac the easiest way to manage your AWS credentials is Leapp.

You can also use the AWS CLI to configure your credentials:

aws configure

Add to your project

dependencies: [
    .package(url: "https://github.com/swift-cloud/swift-cloud.git", branch: "main")
]

Define your infrastructure

Swift Cloud works by declaring your infrastructure as Swift code. To do this you must create a new executable target in the same package as your application.

Start by defining a new executable target in your Package.swift file:

targets: [
    ...
    .executableTarget(
        name: "Infra",
        dependencies: [
            .product(name: "Cloud", package: "swift-cloud")
        ]
    )
]

Next, inside your Sources directory create a new folder called Infra.

Finally, add a new Swift file called Project.swift:

import Cloud

@main
struct SwiftCloudDemo: Project {
    func build() async throws -> Outputs {
        let server = AWS.WebServer(
            "my-vapor-web-server",
            targetName: "App",
            concurrency: 1,
            autoScaling: .init(
                maximumConcurrency: 10,
                metrics: [.cpu(50), .memory(50)]
            )
        )

        return Outputs([
            "url": server.url,
        ])
    }
}

Deploy your project

swift run Infra deploy --stage production

Commands

Swift Cloud is invoked directly from your Swift package. You can run the following commands:

Deploy

Deploy your infrastructure:

swift run Infra deploy --stage production

Remove

Remove all resources:

swift run Infra remove --stage development

Preview

Preview changes before deploying:

swift run Infra preview --stage development

Outputs

Show the outputs of your deployment:

swift run Infra outputs --stage development

Cancel

Cancel a deployment:

swift run Infra cancel --stage development

Home

Swift Cloud allows you to deploy infrastructure across multiple cloud providers. In order to handle incremental changes to your infrastructure, Swift Cloud must store your underlying configuration in a durable location so it can be referenced anytime you run a deploy, whether from your local machine or a CI/CD pipeline.

We abstracted this concept into a HomeProvider protocol, and allow you to decide where your configuration is stored. By default, Swift Cloud uses the AWS S3 service to store your configuration, but you can easily swap this out for any other provider that supports the HomeProvider protocol.

For quick prototyping, you can use the Home.Local provider, which stores your configuration in a local file. This is great for testing and development, but it's not recommended for production use.

import Cloud

@main
struct SwiftCloudDemo: Project {

    // Override the default home provider with a local provider
    let home = Home.Local()

    func build() async throws -> Outputs {...}
}

Components

AWS

WebServer

This component creates a high performance web server using an application load balancer, auto-scaling group, and Fargate. Everything is fully managed and scales automatically based on your configuration.

let server = AWS.WebServer(
    "my-vapor-web-server",
    targetName: "App",
    concurrency: 1,
    autoScaling: .init(
        maximumConcurrency: 10,
        metrics: [.cpu(50), .memory(50)]
    )
)

Function

let lambda = AWS.Function(
    "my-lambda-function",
    targetName: "App",
    url: .enabled(cors: true),
    memory: 512,
    timeout: .seconds(10)
)

CDN

This component creates a CDN that sits in front of your application. It can be used to cache your application assets, or to serve your application from a custom domain.

let cdn = AWS.CDN(
    "my-cdn",
    origins: .webServer(server)
)

You can also route traffic on different paths to different resoruces:

let cdn = AWS.CDN(
    "my-cdn",
    origins: [
        .function(function, path: "/api/*"),
        .webServer(server, path: "*")
    ]
)

And of course you can use a custom domain:

let cdn = AWS.CDN(
    "my-cdn",
    origins: .function(function),
    domainName: .init("www.example.com")
)

Bucket

let bucket = AWS.Bucket("my-s3-bucket")

Queue

let queue = AWS.Queue("my-sqs-queue")

// Subscribe a lambda function to the queue to process messages
queue.subscribe(
    AWS.Function("my-lambda-function", targetName: "App")
)

Topic

let topic = AWS.Topic("my-sns-topic")

// Subscribe a lambda function to the topic to process events
topic.subscribe(
    AWS.Function("my-lambda-function", targetName: "App")
)

Cron

let cron = AWS.Cron(
    "my-cron-job",
    schedule: .rate(.minutes(5))
)

// Invoke the function when the cron job runs
cron.invoke(
    AWS.Function("my-lambda-function", targetName: "App")
)

Domain Name

The DomainName construct manages a TLS certificate and the necessary validation, and can be linked to a WebServer to provide a fully managed domain name.

Important: You must host your domain in a Route53 hosted zone in your AWS account to use this construct. In the future we will add support for domains hosted on other providers.

// Optionally pass a `zoneName` if the domain is not simply inferred from the `domainName`
let domainName = AWS.DomainName("www.example.com")

let server = AWS.WebServer(
    "my-vapor-web-server",
    targetName: "App",
    domainName: domainName
)

return Outputs([
    // Now server url will be `https://www.example.com`
    "url": server.url
])

Linking

You can link resources together to provide the necessary permissions to access each other. This is more secure than sharing access key ids and secrets in environment variables.

For example you can link an S3 bucket to a Lambda function:

myFunction.link(bucket)

This allows the lambda function to access the bucket without needing to share access keys.

Using linked resources

You can use linked resources in your server or function via environment variables in your application:

let bucketUrl = ProcessInfo.processInfo.environment["bucket:my-bucket:url"]

Here is a list of all the linked resources:

Resource Environment Variable
AWS S3 Bucket BUCKET_<NAME>_URL
AWS S3 Bucket BUCKET_<NAME>_HOSTNAME
AWS S3 Bucket BUCKET_<NAME>_NAME
AWS SQS Queue QUEUE_<NAME>_URL
AWS SQS Queue QUEUE_<NAME>_NAME
AWS Lambda Function FUNCTION_<NAME>_URL
AWS Lambda Function FUNCTION_<NAME>_NAME

Swift Cloud's Projects

awsv4 icon awsv4

AWS v4 signing library compatible with Swift Cloud and Fastly Compute@Edge

build icon build

Official build pipeline for swift.cloud

cgd icon cgd

A small Swift package exposing libgd to Swift.

community icon community

Learn, leave feedback, request features, show and tell and more

compute icon compute

Swift runtime for Fastly Compute@Edge

computeui icon computeui

Write SwiftUI / Tokamak apps on Fastly Compute@Edge

crypto icon crypto

CryptoSwift is a growing collection of standard and secure cryptographic algorithms implemented in Swift

docs icon docs

Swift Cloud Platform Documentation

mongodb icon mongodb

A MongoDB client compatible with Swift Cloud and Fastly Compute@Edge

og-image icon og-image

Open Graph Image as a Service - generate cards for Twitter, Facebook, Slack, etc

planetscale icon planetscale

Planetscale library compatible with Swift Cloud & Fastly Compute@Edge

plot icon plot

A DSL for writing type-safe HTML, XML and RSS in Swift.

swift-crypto icon swift-crypto

Open-source implementation of a substantial portion of the API of Apple CryptoKit suitable for use on Linux platforms.

swiftyjson icon swiftyjson

The better way to deal with JSON data in Swift.

tokamak icon tokamak

SwiftUI-compatible framework for building browser apps with WebAssembly and native apps for other platforms

upstash icon upstash

A Upstash client compatible with Swift Cloud and Fastly Compute@Edge

vercel icon vercel

Swift runtime for Vercel Serverless Functions

vercelui icon vercelui

Build server side rendered webpages in SwiftUI

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.