github.com/goreleaser/goreleaser@v1.25.1/www/docs/blog/posts/2022-02-05-cloud-native-storage.md (about) 1 --- 2 date: 2022-02-05 3 slug: cloud-native-storage 4 categories: 5 - tutorials 6 authors: 7 - dirien 8 --- 9 10 # How to use GoReleaser with Cloud Native Storage 11 12 In this tutorial, I want to describe, how quickly we can deploy our release 13 artefacts to a cloud native storage when using GoReleaser. 14 It’s just a few additional lines in your `.goreleaser.yaml`. 15 16 <!-- more --> 17 18 To better show this, I created a little demo and use the storage services of the 19 big three cloud providers: Azure Blob Storage, AWS S3 and Google Cloud Storage. 20 21  22 23 You can use any S3 compatible storage provider too. 24 **GoReleaser** support this too! The most prominent (self-hosted) solution is 25 **MinIO**. 26 27  28 29 ## The infrastructure code 30 31 I created a very simple **Terraform** deployment to provision on all three cloud 32 provider their appropriate cloud storage service. 33 It’s a demo, why not? 34 35 You don’t need to use **Terraform** for this, you could use any other means like 36 **Pulumi**, **CLI** or even the **UI**. 37 38 ###### `main.tf` 39 40 ```terraform 41 terraform { 42 required_providers { 43 google = { 44 source = "hashicorp/google" 45 version = "4.9.0" 46 } 47 azurerm = { 48 source = "hashicorp/azurerm" 49 version = "2.94.0" 50 } 51 aws = { 52 source = "hashicorp/aws" 53 version = "3.74.0" 54 } 55 } 56 } 57 58 provider "azurerm" { 59 features {} 60 } 61 62 provider "google" { 63 credentials = file(var.gcp_auth_file) 64 project = var.gcp_project 65 region = var.gcp_region 66 } 67 68 provider "aws" { 69 region = var.aws_region 70 } 71 ``` 72 73 ###### `variables.tf` 74 75 ```terraform 76 variable "gcp_project" { 77 type = string 78 } 79 80 variable "gcp_region" { 81 default = "europe-west6" 82 } 83 84 variable "gcp_zone" { 85 default = "europe-west6-a" 86 } 87 88 variable "gcp_bucket_location" { 89 default = "EU" 90 } 91 92 variable "gcp_auth_file" { 93 default = "./auth.json" 94 description = "Path to the GCP auth file" 95 } 96 97 variable "aws_region" { 98 default = "eu-central-1" 99 } 100 101 variable "azure_location" { 102 default = "West Europe" 103 } 104 105 variable "name" { 106 default = "gorleaser-quickbites" 107 } 108 ``` 109 110 ###### `blob.tf` 111 112 ```terraform 113 resource "google_storage_bucket" "goreleaser-gcp-storage-bucket" { 114 name = var.name 115 location = var.gcp_bucket_location 116 force_destroy = true 117 uniform_bucket_level_access = false 118 } 119 resource "google_storage_bucket_access_control" "goreleaser-gcp-storage-bucket-access-control" { 120 bucket = google_storage_bucket.goreleaser-gcp-storage-bucket.name 121 role = "READER" 122 entity = "allUsers" 123 } 124 125 resource "azurerm_resource_group" "goreleaser-azure-resource-group" { 126 name = var.name 127 location = var.azure_location 128 } 129 130 resource "azurerm_storage_account" "goreleaser-azure-storage-account" { 131 name = "gorleaserquickbites" 132 resource_group_name = azurerm_resource_group.goreleaser-azure-resource-group.name 133 location = azurerm_resource_group.goreleaser-azure-resource-group.location 134 account_tier = "Standard" 135 account_replication_type = "LRS" 136 allow_blob_public_access = true 137 network_rules { 138 default_action = "Allow" 139 } 140 } 141 142 resource "azurerm_storage_container" "goreleaser-storage-container" { 143 name = var.name 144 storage_account_name = azurerm_storage_account.goreleaser-azure-storage-account.name 145 container_access_type = "container" 146 } 147 148 resource "aws_s3_bucket" "goreleaser-s3-bucket" { 149 bucket = var.name 150 acl = "public-read" 151 } 152 ``` 153 154 ###### Apply the Terraform script: 155 156 ```bash 157 terraform apply -var "gcp_project=xxx" 158 ``` 159 160 ``` 161 ... 162 azurerm_storage_container.goreleaser-storage-container: Creation complete after 0s [id=https://gorleaserquickbites.blob.core.windows.net/gorleaser-quickbites] 163 164 Apply complete! Resources: 6 added, 0 changed, 0 destroyed. 165 166 Outputs: 167 168 aws-s3-bucket-name = "gorleaser-quickbites" 169 azure-storage-account-key = <sensitive> 170 azure-storage-account-name = "export AZURE_STORAGE_ACCOUNT=gorleaserquickbites" 171 gcp-bucket-url = "gs://gorleaser-quickbites" 172 ``` 173 174 ###### Run this command 175 176 ```bash 177 terraform output azure-storage-account-key 178 ``` 179 180 to get the Azure Storage Account Key, as it is a output field with sensitive data in it. 181 182 ```bash 183 export AZURE_STORAGE_KEY=xxxx 184 ``` 185 186 Now we can add in our `.goreleaser.yaml` the new **blobs** field. 187 Important is here to set the right provider: **gs** (for Google Cloud Storage), 188 **azblob** (for Azure Blob) and **s3** (for AWS S3 or compatible provider)! 189 190 ```yaml 191 # This is an example .goreleaser.yml file with some sensible defaults. 192 # Make sure to check the documentation at https://goreleaser.com 193 before: 194 hooks: 195 - go mod tidy 196 builds: 197 - env: 198 - CGO_ENABLED=0 199 goos: 200 - linux 201 - darwin 202 203 release: 204 disable: true 205 --- 206 blobs: 207 - provider: gs 208 bucket: gorleaser-quickbites 209 - provider: azblob 210 bucket: gorleaser-quickbites 211 - provider: s3 212 bucket: gorleaser-quickbites 213 region: eu-central-1 214 ``` 215 216 In this demo, I disabled the **release **section, as I don’t want to upload to 217 GitHub. 218 219 ## Authentication 220 221 In terms of authentication the GoReleaser’s blob pipe authentication varies depending upon the blob provider as mentioned below: 222 223 ### S3 Provider 224 225 S3 provider support AWS [default credential 226 provider](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials) 227 chain in the following order: 228 229 - Environment variables. 230 - Shared credentials file. 231 - If your application is running on an Amazon EC2 instance, IAM role for Amazon EC2. 232 233 ### Azure Blob Provider Currently it supports authentication only 234 235 with [environment variables](https://docs.microsoft.com/en-us/azure/storage/common/storage-azure-cli#set-default-azure-storage-account-environment-variables): 236 237 - AZURE_STORAGE_ACCOUNT 238 - AZURE_STORAGE_KEY or AZURE_STORAGE_SAS_TOKEN 239 240 ### GCS 241 242 Provider GCS provider uses [Application Default 243 Credentials](https://cloud.google.com/docs/authentication/production) in the 244 following order: 245 246 - Environment Variable (GOOGLE_APPLICATION_CREDENTIALS) 247 - Default Service Account from the compute instance (Compute Engine, Kubernetes 248 Engine, Cloud function etc). 249 250 ## Run GoReleaser 251 252 After configuring we can finally execute **GoReleaser**, in your pipeline code 253 via the command: 254 255 ```bash 256 goreleaser release --rm-dist 257 ``` 258 259 If everything went smooth, you should see a similar output, showing the upload of your artefacts. 260 261 ``` 262 ... 263 • publishing 264 • blobs 265 • uploading path=quick-bites/0.1/quick-bites_0.1_checksums.txt 266 • uploading path=quick-bites/0.1/quick-bites_0.1_darwin_amd64.tar.gz 267 • uploading path=quick-bites/0.1/quick-bites_0.1_linux_arm64.tar.gz 268 • uploading path=quick-bites/0.1/quick-bites_0.1_darwin_arm64.tar.gz 269 • uploading path=quick-bites/0.1/quick-bites_0.1_linux_amd64.tar.gz 270 • uploading path=quick-bites/0.1/quick-bites_0.1_linux_386.tar.gz 271 • uploading path=quick-bites/0.1/quick-bites_0.1_checksums.txt 272 • uploading path=quick-bites/0.1/quick-bites_0.1_checksums.txt 273 • uploading path=quick-bites/0.1/quick-bites_0.1_linux_386.tar.gz 274 • uploading path=quick-bites/0.1/quick-bites_0.1_linux_amd64.tar.gz 275 • uploading path=quick-bites/0.1/quick-bites_0.1_linux_arm64.tar.gz 276 • uploading path=quick-bites/0.1/quick-bites_0.1_linux_amd64.tar.gz 277 • uploading path=quick-bites/0.1/quick-bites_0.1_darwin_amd64.tar.gz 278 • uploading path=quick-bites/0.1/quick-bites_0.1_darwin_arm64.tar.gz 279 • uploading path=quick-bites/0.1/quick-bites_0.1_linux_386.tar.gz 280 • uploading path=quick-bites/0.1/quick-bites_0.1_linux_arm64.tar.gz 281 • uploading path=quick-bites/0.1/quick-bites_0.1_darwin_arm64.tar.gz 282 • uploading path=quick-bites/0.1/quick-bites_0.1_darwin_amd64.tar.gz 283 • release succeeded after 22.63s 284 ... 285 ``` 286 287 > One note: The provider fails silently, if your credentials are wrong. You 288 > would still see uploading and release succeeded. Keep this in mind, if the 289 > files are not appearing in the UI. I wasted some time on this. The culprit is 290 > the underlying library GoReleaser is using. 291 292 Let’s check in the consoles of the cloud provider too, If the files are present. 293 294 ###### Google Cloud Storage: 295 296  297 298 ###### Azure Blob Storage 299 300  301 302 ###### AWS S3 303 304  305 306 Looks very good! Now you can share the URLs of the files for further use! 307 308 ## Want more Informations? 309 310 If you want to know more about some advanced options, feel free to check out the 311 [official documentation about the blob support in 312 GoReleaser](https://goreleaser.com/customization/blob/) 313 314 And here is the example code: [dirien/quick-bytes](https://github.com/dirien/quick-bites/tree/main/goreleaser-blob) 315 316 