Build your first app with the Azure SDK for Go on Azure

Go is a programming language that is created by Google. It is sometimes referred to as 'Golang' and it's completely open source. It is statically typed and compiled and in that sense, it is kind of like C# and C. Go is very popular and it is used in big implementations, like in Docker and in parts of Netflix.

And now, just like with almost any programming language, you can use Go in Azure! You can do that with the Azure SDKs for Go. There are several SDKs:

Manage Azure Blobs with Go

Let's build our first app in Go and use the Azure Blob Storage SDK. We'll build something simple that can interact with Azure Blob Storage. To get started, we'll first do some initial setup of things.

Initial setup

First things first:

  1. If you haven't already, install Go 1.8 or later
  2. Create an Azure Storage account. We'll use this in the application. From the Azure portal, you can create a general Storage Account by leaving things to their default settings as they are in the image below:

(Creating a general purpose Azure Storage Account in the Azure portal)

  1. Go to the Azure Storage Account and click on the Access keys menu. Now copy the Storage account name and the Key (either Key1 or Key2)

(Azure Storage Access keys in the Azure portal)

  1. In the Go application, we'll use the Storage account name and the Access key from environment variables. In Windows, you can set these variables from the command window, like in the image below. If you are running Linux, you can see the command here.

(Setting Azure Storage credentials as environment variables)

Creating the Go application

Now that we have everything setup, we can create our Go application. If you want, you can use Go with VSCode. Just install this VSCode extension to make it work and get features like IntelliSense and debugging.

  1. Let's start at the beginning. First, we create a Go file that will contain our code. Just create a file that has the .go extension, like AzureBlobTest.go. VSCode even let's you save files as Go files.
  2. Now, in the AzureBlobTest.go file, write:
package main

import (
	"bufio"
	"bytes"
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"net/url"
	"os"
	"strconv"
	"time"

	"github.com/Azure/azure-storage-blob-go/azblob"
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

If you are using VSCode, you can don't have to type all of the things in the import statement, except for the Azure Blob Storage SDK one. VSCode will automatically detect which packages you need and put them in the import statement. The github.com/Azure/azure-storage-blob-go/azblob is the Azure Storage Blobs SDK.

  1. To make sure that the Azure Blob Storage SDK can be found and that the application always imports it, I will also create a go.mod file. In here, I write:
module main

require github.com/Azure/azure-storage-blob-go v0.0.0-20181022225951-5152f14ace1c
1
2
3

This makes sure that the application actually downloads the SDK onto the machine. There are other methods to do this as well, but this one works for me.

  1. Next, we create a new function, like this:
func main(){
    
}
1
2
3
  1. And in the main function, we'll start creating the code that talks to blob storage. I'll start with getting the Azure Storage account and Key from the environment variables
	// From the Azure portal, get your storage account name and key and set environment variables.
	accountName, accountKey := os.Getenv("AZURE_STORAGE_ACCOUNT"), os.Getenv("AZURE_STORAGE_ACCESS_KEY")
1
2
  1. Next, we use the credentials to create an Azure Storage pipeline and create a new Azure Blob Container. For the container name, we use a random string so that we minimize the chance that the container already exists. I don't show the code for getting the random string here. Don't worry, that is included in the finalized code sample. You can find a link to that in the conclusion of this post
	// Create a default request pipeline using your storage account name and account key.
	credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
	if err != nil {
		log.Fatal("Invalid credentials with error: " + err.Error())
	}
	pipeline := azblob.NewPipeline(credential, azblob.PipelineOptions{})

	// Create a random string for the quick start container
	containerName := fmt.Sprintf("quickstart-%s", randomString())

	// From the Azure portal, get your storage account blob service URL endpoint.
	URL, _ := url.Parse(
		fmt.Sprintf("https://%s.blob.core.windows.net/%s", accountName, containerName))

	// Create a ContainerURL object that wraps the container URL and a request
	// pipeline to make requests.
	containerURL := azblob.NewContainerURL(*URL, pipeline)

	// Create the container
	fmt.Printf("Creating a container named %s\n", containerName)
	ctx := context.Background() // This example uses a never-expiring context
	_, err = containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessNone)
	handleErrors(err)    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  1. Now that we have a container, we can put blobs in it. The code below creates a file and uploads it as a Blob to the container.
	// Create a file to test the upload and download.
	fmt.Printf("Creating a dummy file to test the upload and download\n")
	data := []byte("hello world this is a blob\n")
	fileName := randomString()
	err = ioutil.WriteFile(fileName, data, 0700)
	handleErrors(err)

	// Here's how to upload a blob.
	blobURL := containerURL.NewBlockBlobURL(fileName)
	file, err := os.Open(fileName)
	handleErrors(err)

	// The high-level API UploadFileToBlockBlob function uploads blocks in parallel for optimal performance, and can handle large files as well.
	// This function calls PutBlock/PutBlockList for files larger 256 MBs, and calls PutBlob for any file smaller
	fmt.Printf("Uploading the file with blob name: %s\n", fileName)
	_, err = azblob.UploadFileToBlockBlob(ctx, file, blobURL, azblob.UploadToBlockBlobOptions{
		BlockSize:   4 * 1024 * 1024,
		Parallelism: 16})
	handleErrors(err)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  1. And next, we loop through all of the files in the container and print them out on the screen.
	// List the container that we have created above
	fmt.Println("Listing the blobs in the container:")
	for marker := (azblob.Marker{}); marker.NotDone(); {
		// Get a result segment starting with the blob indicated by the current Marker.
		listBlob, err := containerURL.ListBlobsFlatSegment(ctx, marker, azblob.ListBlobsSegmentOptions{})
		handleErrors(err)

		// ListBlobs returns the start of the next segment; you MUST use this to get
		// the next segment (after processing the current result segment).
		marker = listBlob.NextMarker

		// Process the blobs returned in this result segment (if the segment is empty, the loop body won't execute)
		for _, blobInfo := range listBlob.Segment.BlobItems {
			fmt.Print("	Blob name: " + blobInfo.Name + "\n")
		}
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  1. And the final piece of code waits for the user to press ENTER and cleans everything up
	// Cleaning up the quick start by deleting the container and the file created locally
	fmt.Printf("Press enter key to delete the sample files, example container, and exit the application.\n")
	bufio.NewReader(os.Stdin).ReadBytes('\n')
	fmt.Printf("Cleaning up.\n")
	containerURL.Delete(ctx, azblob.ContainerAccessConditions{})
	file.Close()
	os.Remove(fileName)
1
2
3
4
5
6
7

That's it. Now we can test it out. You can run the code from VSCode, but also from the command line. To run it, you use:

go run AzureBlobTest.go
1

And the output looks like this:

(Running the Go application)

If you don't press ENTER, you can now see the results of the application in Azure.

  1. Go to the Azure portal and navigate to the Azure Storage Account
  2. Click on Blobs
  3. Now you'll see the container. Click on it and click on the blob within it. When you now click Edit Blob, you can see the content of the Blob.

(Azure Storage Blob in the Azure portal)

  1. You can now go back to the command prompt and press ENTER. This wil delete the Azure Storage container and the blob in it.
Conclusion and where to find the source code

That's it! As you can see, it is relatively easy to use Azure with Go. You can really use almost any language to work with Azure and to create apps for Azure, now including Go.

Besides working with Azure services, you can also create Go applications that run in Azure. You can for instance compile a Go application by executing the Go build filename.go command to get an executable file that contains everything it needs to run. And you can deploy that executable to run in a container, in App Service, in Azure Service Fabric or wherever you like.

And you can find the complete source code of the application that we've built, in this GitHub repository.