| # Portable Cloud Programming with Go Cloud | |
| 24 Jul 2018 | |
| Summary: Announcing Go Cloud, for portable cloud programming with Go. | |
| Eno Compton | |
| Cassandra Salisbury | |
| ## Introduction | |
| Today, the Go team at Google is releasing a new open source project, | |
| [Go Cloud](https://github.com/google/go-cloud), | |
| a library and tools for developing on the [open cloud](https://cloud.google.com/open-cloud/). | |
| With this project, we aim to make Go the language of choice for developers | |
| building portable cloud applications. | |
| This post explains why we started this project, the details of how Go Cloud works, and how to get involved. | |
| ## Why portable cloud programming? Why now? | |
| We estimate there are now [over one million](https://research.swtch.com/gophercount) | |
| Go developers worldwide. | |
| Go powers many of the most critical cloud infrastructure projects, | |
| including Kubernetes, Istio, and Docker. | |
| Companies like Lyft, Capital One, Netflix and [many more](https://github.com/golang/go/wiki/GoUsers) | |
| are depending on Go in production. | |
| Over the years, we've found that developers love Go for cloud development | |
| because of its efficiency, | |
| productivity, built-in concurrency, and low latency. | |
| As part of our work to support Go's rapid growth, | |
| we have been interviewing teams who work with Go to understand how they | |
| use the language and how the Go ecosystem can improve further. | |
| One common theme with many organizations is the need for portability across cloud providers. | |
| These teams want to deploy robust applications in [multi-cloud](https://en.wikipedia.org/wiki/Cloud_computing#Multicloud) | |
| and [hybrid-cloud](https://en.wikipedia.org/wiki/Cloud_computing#Hybrid_cloud) environments, | |
| and migrate their workloads between cloud providers without significant | |
| changes to their code. | |
| To achieve this, some teams attempt to decouple their applications from | |
| provider-specific APIs in order to produce simpler and more portable code. | |
| However the short-term pressure to ship features means teams often sacrifice | |
| longer-term efforts toward portability. | |
| As a result, most Go applications running in the cloud are tightly coupled | |
| to their initial cloud provider. | |
| As an alternative, teams can use Go Cloud, | |
| a set of open generic cloud APIs, to write simpler and more portable cloud applications. | |
| Go Cloud also sets the foundation for an ecosystem of portable cloud libraries | |
| to be built on top of these generic APIs. | |
| Go Cloud makes it possible for teams to meet their feature development goals | |
| while also preserving the long-term flexibility for multi-cloud and hybrid-cloud architectures. | |
| Go Cloud applications can also migrate to the cloud providers that best meet their needs. | |
| ## What is Go Cloud? | |
| We have identified common services used by cloud applications and have created | |
| generic APIs to work across cloud providers. | |
| Today, Go Cloud is launching with blob storage, | |
| MySQL database access, runtime configuration, | |
| and an HTTP server configured with request logging, | |
| tracing, and health checking. | |
| Go Cloud offers support for Google Cloud Platform (GCP) and Amazon Web Services (AWS). | |
| We plan to work with cloud industry partners and the Go community to add | |
| support for additional cloud providers very soon. | |
| Go Cloud aims to develop vendor-neutral generic APIs for the most-used services | |
| across cloud providers such that deploying a Go application on another cloud is simple and easy. | |
| Go Cloud also lays the foundation for other open source projects to write | |
| cloud libraries that work across providers. | |
| Community feedback, from all types of developers at all levels, | |
| will inform the priority of future APIs in Go Cloud. | |
| ## How does it work? | |
| At the core of Go Cloud is a collection of generic APIs for portable cloud programming. | |
| Let's look at an example of using blob storage. | |
| You can use the generic type [`*blob.Bucket`](https://godoc.org/github.com/google/go-cloud/blob#Bucket) | |
| to copy a file from a local disk to a cloud provider. | |
| Let's start by opening an S3 bucket using the included [s3blob package](https://godoc.org/github.com/google/go-cloud/blob/s3blob): | |
| // setupBucket opens an AWS bucket. | |
| func setupBucket(ctx context.Context) (*blob.Bucket, error) { | |
| // Obtain AWS credentials. | |
| sess, err := session.NewSession(&aws.Config{ | |
| Region: aws.String("us-east-2"), | |
| }) | |
| if err != nil { | |
| return nil, err | |
| } | |
| // Open a handle to s3://go-cloud-bucket. | |
| return s3blob.OpenBucket(ctx, sess, "go-cloud-bucket") | |
| } | |
| Once a program has a `*blob.Bucket`, it can create a `*blob.Writer`, | |
| which implements `io.Writer`. | |
| From there, the program can use the `*blob.Writer` to write data to the bucket, | |
| checking that `Close` does not report an error. | |
| ctx := context.Background() | |
| b, err := setupBucket(ctx) | |
| if err != nil { | |
| log.Fatalf("Failed to open bucket: %v", err) | |
| } | |
| data, err := ioutil.ReadFile("gopher.png") | |
| if err != nil { | |
| log.Fatalf("Failed to read file: %v", err) | |
| } | |
| w, err := b.NewWriter(ctx, "gopher.png", nil) | |
| if err != nil { | |
| log.Fatalf("Failed to obtain writer: %v", err) | |
| } | |
| _, err = w.Write(data) | |
| if err != nil { | |
| log.Fatalf("Failed to write to bucket: %v", err) | |
| } | |
| if err := w.Close(); err != nil { | |
| log.Fatalf("Failed to close: %v", err) | |
| } | |
| Notice how the logic of using the bucket does not refer to AWS S3. | |
| Go Cloud makes swapping out cloud storage a matter of changing the function | |
| used to open the `*blob.Bucket`. | |
| The application could instead use Google Cloud Storage by constructing a | |
| `*blob.Bucket` using [`gcsblob.OpenBucket`](https://godoc.org/github.com/google/go-cloud/blob/gcsblob#OpenBucket) | |
| without changing the code that copies the file: | |
| // setupBucket opens a GCS bucket. | |
| func setupBucket(ctx context.Context) (*blob.Bucket, error) { | |
| // Open GCS bucket. | |
| creds, err := gcp.DefaultCredentials(ctx) | |
| if err != nil { | |
| return nil, err | |
| } | |
| c, err := gcp.NewHTTPClient(gcp.DefaultTransport(), gcp.CredentialsTokenSource(creds)) | |
| if err != nil { | |
| return nil, err | |
| } | |
| // Open a handle to gs://go-cloud-bucket. | |
| return gcsblob.OpenBucket(ctx, "go-cloud-bucket", c) | |
| } | |
| While different steps are needed to access buckets on different cloud providers, | |
| the resulting type used by your application is the same: `*blob.Bucket`. | |
| This isolates application code from cloud-specific code. | |
| To increase interoperability with existing Go libraries, | |
| Go Cloud leverages established interfaces like `io.Writer`, | |
| `io.Reader`, and `*sql.DB`. | |
| The setup code needed to access cloud services tends to follow a pattern: | |
| higher abstractions are constructed from more basic abstractions. | |
| While you could write this code by hand, Go Cloud automates this with **Wire**, | |
| a tool that generates cloud-specific setup code for you. | |
| The [Wire documentation](https://github.com/google/go-cloud/tree/master/wire) | |
| explains how to install and use the tool and the [Guestbook sample](https://github.com/google/go-cloud/tree/master/samples/guestbook) | |
| shows Wire in action. | |
| ## How can I get involved and learn more? | |
| To get started, we recommend following [the tutorial](https://github.com/google/go-cloud/tree/master/samples/tutorial) | |
| and then trying to build an application yourself. | |
| If you're already using AWS or GCP, you can try migrating parts of your | |
| existing application to use Go Cloud. | |
| If you're using a different cloud provider or an on-premise service, | |
| you can extend Go Cloud to support it by implementing the driver interfaces | |
| (like [`driver.Bucket`](https://godoc.org/github.com/google/go-cloud/blob/driver#Bucket)). | |
| We appreciate any and all input you have about your experience. | |
| [Go Cloud's](https://github.com/google/go-cloud) development is conducted on GitHub. | |
| We are looking forward to contributions, including pull requests. | |
| [File an issue](https://github.com/google/go-cloud/issues/new) to tell | |
| us what could be better or what future APIs the project should support. | |
| For updates and discussion about the project, | |
| join [the project's mailing list](https://groups.google.com/forum/#!forum/go-cloud). | |
| The project requires contributors to sign the same Contributor License Agreement | |
| as that of the Go project. | |
| Read the [contribution guidelines](https://github.com/google/go-cloud/blob/master/CONTRIBUTING.md) for more details. | |
| Please note, Go Cloud is covered by the Go [Code of Conduct](https://github.com/google/go-cloud/blob/master/CODE_OF_CONDUCT.md). | |
| Thank you for taking the time to learn about Go Cloud. | |
| We are excited to work with you to make Go the language of choice for developers | |
| building portable cloud applications. |