{"id":731,"date":"2018-11-03T08:51:43","date_gmt":"2018-11-03T08:51:43","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=731"},"modified":"2018-11-03T08:51:43","modified_gmt":"2018-11-03T08:51:43","slug":"setup-google-provider-backend-terraform","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=731","title":{"rendered":"How To Setup Google Provider and Backend For Terraform"},"content":{"rendered":"<p>As part of getting started, you should have a valid Google Service account which has required permissions to resources that you are trying to manage using Terraform. You can get this service account from the <a href=\"https:\/\/console.cloud.google.com\/iam-admin\/serviceaccounts?ref=devopscube.com\" rel=\"noopener noreferrer\">Google Cloud IAM console<\/a>.<\/p>\n<p>This guide covers the following two main setups.<\/p>\n<ol>\n<li>Google Provider Setup<\/li>\n<li>GCS backend Setup with multiple ways of initialization.<\/li>\n<\/ol>\n<h3 id=\"terraform-google-provider-configuration\">Terraform Google Provider Configuration<\/h3>\n<p>Terraform <a href=\"https:\/\/devopscube.com\/category\/google-cloud\/\" rel=\"noopener noreferrer\">google cloud<\/a> provider configuration is a series for key-value pairs and contains four pairs.<\/p>\n<ol>\n<li><strong>Credentials:<\/strong> Google service account file path.<\/li>\n<li><strong>Project<\/strong>: The Google Project which Terraform wants to manage.<\/li>\n<li><strong>Region<\/strong>: Google cloud region<\/li>\n<li><strong>Zone<\/strong>: Google cloud zone.<\/li>\n<\/ol>\n<p>An example configuration is given below. With this configuration, you can connect to Google account in the central region on the devopscube-demo project. <\/p>\n<pre><code>provider \"google\" {\n  credentials = \"${file(\"service-account.json\")}\"\n  project     = \"devopscube-demo\"\n  region      = \"us-central1\"\n  zone        = \"us-central1-c\"\n}<\/code><\/pre>\n<blockquote><p><strong>Note:<\/strong> <code>${file(\"service-account.json\")}<\/code> looks for the service account key in the current folder where you are running the terraform command.<\/p><\/blockquote>\n<h3 id=\"managing-service-account\">Managing Service Account<\/h3>\n<p>You can manage the service account in the following ways.<\/p>\n<ol>\n<li>Enter the path of the service account file with the credentials key. For example,<\/li>\n<\/ol>\n<pre><code>credentials = \"${file(\"\/opt\/terraform\/service-account.json\")}\"<\/code><\/pre>\n<p><!--kg-card-begin: html--><\/p>\n<ol start=\"2\">\n<li>Set a credential environment variable GOOGLE_CLOUD_KEYFILE_JSON. In this case, we don&#8217;t have to use credentials key in the provider definition. Terraform will automatically pick up the credential location from the environment variable. Example,<\/li>\n<\/ol>\n<p><!--kg-card-end: html--><\/p>\n<pre><code>export GOOGLE_CLOUD_KEYFILE_JSON=\"\/opt\/terraform\/service-account.json\"<\/code><\/pre>\n<blockquote><p><strong>Note:<\/strong> export will only set the environment variable in the current terminal. To set a permanent environment variable, you need to add it to the user\/system profile.<\/p><\/blockquote>\n<h3 id=\"example-terraform-code-with-google-provider\">Example Terraform Code With Google Provider<\/h3>\n<pre><code>provider \"google\" {\n  credentials = \"${file(\"\/opt\/creds\/service-account.json\")}\"\n  project     = \"devopscube-demo\"\n  region      = \"us-central1\"\n}\nresource \"google_compute_instance\" \"ubuntu-xenial\" {\n   name = \"devopscube-demo-instance\"\n   machine_type = \"f1-micro\"\n   zone = \"us-west1-a\"\n   boot_disk {\n       auto_delete = false\n      initialize_params {\n      image = \"ubuntu-1604-xenial-v20181023\"\n      size = \"30\"     \n   }\n}\nnetwork_interface {\n   network = \"default\"\n   access_config {}\n}\n\nmetadata {\n    foo = \"bar\"\n}\n\nmetadata_startup_script = \"echo demo &gt; \/demo.txt\"\n\nscheduling {\n    preemptible       = true\n  }\n\nservice_account {\n   scopes = [\"cloud-platform\"]\n   }\n}<\/code><\/pre>\n<p>Once you execute the init command, terraform will automatically download the Google backend plugin.<\/p>\n<h3 id=\"google-cloud-storage-gcs-terraform-backend-setup\">Google Cloud Storage (GCS) Terraform Backend Setup<\/h3>\n<p>During every terraform run, terraform creates a state file for the executed plan. By default, it creates the state in the local file system. You can store this state in remote GCS backend.<\/p>\n<p>Before getting started, you need to have the following.<\/p>\n<ol>\n<li><strong>GCS Bucket<\/strong>: A google storage bucket where you want to save the terraform state. You can create one <a href=\"https:\/\/console.cloud.google.com\/storage\/?ref=devopscube.com\" rel=\"noopener noreferrer\">from here<\/a>.<\/li>\n<li><strong>Valid Google Service Account<\/strong>: Google service account with permissions to write to the storage bucket used by Terraform to save the states.<\/li>\n<\/ol>\n<p>GCS backend configuration has the following key-value pairs.<\/p>\n<ol>\n<li><strong>Bucket:<\/strong> Google storage bucket name.<\/li>\n<li><strong>Prefix<\/strong>: Folders inside the bucket.<\/li>\n<li><strong>Credentials<\/strong>: Path to google service account file.<\/li>\n<\/ol>\n<p>Backend configuration will look like this. You should have this backend configuration in your root terraform file.<\/p>\n<pre><code>terraform {\n  backend \"gcs\" {\n    bucket = \"devopscube-states\"\n    prefix = \"demo\"\n    credentials = \"service-account.json\"\n  }\n}<\/code><\/pre>\n<h3 id=\"initializing-gcs-backend\">Initializing GCS Backend<\/h3>\n<p>You need to initialize the GCS backend for the first time using the init command. This would read all the backend configuration from the terraform block and initialize a state file in the bucket path. <\/p>\n<pre><code>terraform init<\/code><\/pre>\n<p>You can also pass the backend configuration in the runtime using a partial configuration.<\/p>\n<p>The terraform block would have an empty declaration as shown below.<\/p>\n<pre><code>terraform {\n  backend \"gcs\" {}  \n}<\/code><\/pre>\n<p>Now, you can pass the backend configurations with the init command as shown below.<\/p>\n<pre><code>terraform init \\\n    -backend-config=\"bucket=devopscube-states\" \\\n    -backend-config=\"prefix=demo\" \\\n    -backend-config=\"credentials=service-account.json\"<\/code><\/pre>\n<p>You can also pass the backend configuration as a file during runtime.<\/p>\n<blockquote><p><em><strong>Note:<\/strong> This is a perfect use case of using secrets with vault. You can store your backend <\/em><a href=\"https:\/\/devopscube.com\/setup-hashicorp-vault-beginners-guide\/\" rel=\"noopener noreferrer\"><em>configs in <\/em><\/a>vault<em> and retrieve it during terraform initialization. Covering vault integration in out of <\/em>t<em>he scope of this article.<\/em><\/p><\/blockquote>\n<p>For example, create a file named backend.config and enter all the backend details as key-value pairs as shown below.<\/p>\n<pre><code>bucket = \"devopscube-states\"\nprefix = \"demo\"\ncredentials = \"service-account.json\"<\/code><\/pre>\n<p>You can pass this file with the init command as follows.<\/p>\n<pre><code>terraform init -backend-config=backend.config\n<\/code><\/pre>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/setup-google-provider-backend-terraform\/\" target=\"_blank\" rel=\"noopener noreferrer\">How To Setup Google Provider and Backend For Terraform \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/setup-google-provider-backend-terraform\/<\/p>\n","protected":false},"author":1,"featured_media":732,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-731","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/731","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=731"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/731\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/732"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=731"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=731"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=731"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}