Make google_service_account resource importable (#606)

* Make google_service_account resource importable

* Add google_service_account testcase with default project

* Mark google_service_account.project as computed to ensure the project id is always stored in the state, defined in configuration or not. Add corresponding test cases

* Inline variables with single usage

* Replace tabs with spaces in configuration strings

* Ensure service account is not recreated when the default project is explicitely added to the configuration

* camelcase
This commit is contained in:
Patrick Decat 2017-10-25 21:33:21 +02:00 committed by Dana Hoffman
parent edc9df91d0
commit 3d1e11023d
4 changed files with 119 additions and 0 deletions

View File

@ -0,0 +1,68 @@
package google
import (
"fmt"
"testing"
"os"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccGoogleServiceAccount_importBasic(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccGoogleServiceAccount_import("terraform-" + acctest.RandString(10)),
},
resource.TestStep{
ResourceName: "google_service_account.acceptance",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccGoogleServiceAccount_import(saName string) string {
return fmt.Sprintf(`
resource "google_service_account" "acceptance" {
account_id = "%s"
display_name = "%s"
}`, saName, saName)
}
func TestAccGoogleServiceAccount_importWithProject(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccGoogleServiceAccount_importWithProject(os.Getenv("GOOGLE_PROJECT"), "terraform-"+acctest.RandString(10)),
},
resource.TestStep{
ResourceName: "google_service_account.acceptance",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccGoogleServiceAccount_importWithProject(project, saName string) string {
return fmt.Sprintf(`
resource "google_service_account" "acceptance" {
project = "%s"
account_id = "%s"
display_name = "%s"
}`, project, saName, saName)
}

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"log"
"strings"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/iam/v1"
@ -15,6 +16,9 @@ func resourceGoogleServiceAccount() *schema.Resource {
Read: resourceGoogleServiceAccountRead,
Delete: resourceGoogleServiceAccountDelete,
Update: resourceGoogleServiceAccountUpdate,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"email": &schema.Schema{
Type: schema.TypeString,
@ -39,6 +43,7 @@ func resourceGoogleServiceAccount() *schema.Resource {
},
"project": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Optional: true,
ForceNew: true,
},
@ -119,6 +124,8 @@ func resourceGoogleServiceAccountRead(d *schema.ResourceData, meta interface{})
d.Set("email", sa.Email)
d.Set("unique_id", sa.UniqueId)
d.Set("project", sa.ProjectId)
d.Set("account_id", strings.Split(sa.Email, "@")[0])
d.Set("name", sa.Name)
d.Set("display_name", sa.DisplayName)
return nil

View File

@ -7,6 +7,7 @@ import (
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"os"
)
// Test that a service account resource can be created, updated, and destroyed
@ -14,8 +15,10 @@ func TestAccGoogleServiceAccount_basic(t *testing.T) {
t.Parallel()
accountId := "a" + acctest.RandString(10)
uniqueId := ""
displayName := "Terraform Test"
displayName2 := "Terraform Test Update"
project := os.Getenv("GOOGLE_PROJECT")
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
@ -25,6 +28,8 @@ func TestAccGoogleServiceAccount_basic(t *testing.T) {
Config: testAccGoogleServiceAccountBasic(accountId, displayName),
Check: resource.ComposeTestCheckFunc(
testAccCheckGoogleServiceAccountExists("google_service_account.acceptance"),
resource.TestCheckResourceAttr(
"google_service_account.acceptance", "project", project),
),
},
// The second step updates the service account
@ -32,6 +37,21 @@ func TestAccGoogleServiceAccount_basic(t *testing.T) {
Config: testAccGoogleServiceAccountBasic(accountId, displayName2),
Check: resource.ComposeTestCheckFunc(
testAccCheckGoogleServiceAccountNameModified("google_service_account.acceptance", displayName2),
resource.TestCheckResourceAttr(
"google_service_account.acceptance", "project", project),
testAccStoreServiceAccountUniqueId(&uniqueId),
),
},
// The third step explicitely adds the same default project to the service account configuration
// and ensure the service account is not recreated by comparing the value of its unique_id with the one from the previous step
resource.TestStep{
Config: testAccGoogleServiceAccountWithProject(project, accountId, displayName2),
Check: resource.ComposeTestCheckFunc(
testAccCheckGoogleServiceAccountNameModified("google_service_account.acceptance", displayName2),
resource.TestCheckResourceAttr(
"google_service_account.acceptance", "project", project),
resource.TestCheckResourceAttrPtr(
"google_service_account.acceptance", "unique_id", &uniqueId),
),
},
},
@ -74,6 +94,13 @@ func TestAccGoogleServiceAccount_createPolicy(t *testing.T) {
})
}
func testAccStoreServiceAccountUniqueId(uniqueId *string) resource.TestCheckFunc {
return func(s *terraform.State) error {
*uniqueId = s.RootModule().Resources["google_service_account.acceptance"].Primary.Attributes["unique_id"]
return nil
}
}
func testAccCheckGoogleServiceAccountPolicyCount(r string, n int) resource.TestCheckFunc {
return func(s *terraform.State) error {
c := testAccProvider.Meta().(*Config)
@ -126,6 +153,15 @@ func testAccGoogleServiceAccountBasic(account, name string) string {
return fmt.Sprintf(t, account, name)
}
func testAccGoogleServiceAccountWithProject(project, account, name string) string {
t := `resource "google_service_account" "acceptance" {
project = "%v"
account_id = "%v"
display_name = "%v"
}`
return fmt.Sprintf(t, project, account, name)
}
func testAccGoogleServiceAccountPolicy(account, name string) string {
t := `resource "google_service_account" "acceptance" {

View File

@ -73,3 +73,11 @@ exported:
* `name` - The fully-qualified name of the service account.
* `unique_id` - The unique id of the service account.
## Import
Service accounts can be imported using their URI, e.g.
```
$ terraform import google_service_account.my_sa projects/my-project/serviceAccounts/my-sa@my-project.iam.gserviceaccount.com
```