Skip to content

Commit

Permalink
Merge pull request #151 from Cox-Automotive/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
amagana3 authored Sep 14, 2021
2 parents db6ca3e + 40a5c3b commit 0b1fd4f
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 168 deletions.
10 changes: 5 additions & 5 deletions docs/guides/local_installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ mkdir -p ~/.terraform.d/plugins &&
**One-liner download for macOS / Linux:**

```sh
mkdir -p ~/.terraform.d/plugins/Cox-Automotive/engineering-enablement/alks/2.0.4/darwin_amd64 &&
curl -Ls https://api.github.com/repos/Cox-Automotive/terraform-provider-alks/releases | jq -r --arg release "v2.0.4" --arg arch "$(uname -s | tr A-Z a-z)" '.[] | select(.tag_name | contains($release)) | .assets[]| select(.browser_download_url | contains($arch)) | select(.browser_download_url | contains("amd64")) | .browser_download_url' |
xargs -n 1 curl -Lo ~/.terraform.d/plugins/Cox-Automotive/engineering-enablement/alks/2.0.4/darwin_amd64/terraform-provider-alks.zip &&
pushd ~/.terraform.d/plugins/Cox-Automotive/engineering-enablement/alks/2.0.4/darwin_amd64 &&
unzip ~/.terraform.d/plugins/Cox-Automotive/engineering-enablement/alks/2.0.4/darwin_amd64/terraform-provider-alks.zip -d terraform-provider-alks-tmp &&
mkdir -p ~/.terraform.d/plugins/Cox-Automotive/engineering-enablement/alks/2.0.5/darwin_amd64 &&
curl -Ls https://api.github.com/repos/Cox-Automotive/terraform-provider-alks/releases | jq -r --arg release "v2.0.5" --arg arch "$(uname -s | tr A-Z a-z)" '.[] | select(.tag_name | contains($release)) | .assets[]| select(.browser_download_url | contains($arch)) | select(.browser_download_url | contains("amd64")) | .browser_download_url' |
xargs -n 1 curl -Lo ~/.terraform.d/plugins/Cox-Automotive/engineering-enablement/alks/2.0.5/darwin_amd64/terraform-provider-alks.zip &&
pushd ~/.terraform.d/plugins/Cox-Automotive/engineering-enablement/alks/2.0.5/darwin_amd64 &&
unzip ~/.terraform.d/plugins/Cox-Automotive/engineering-enablement/alks/2.0.5/darwin_amd64/terraform-provider-alks.zip -d terraform-provider-alks-tmp &&
mv terraform-provider-alks-tmp/terraform-provider-alks* . &&
chmod +x terraform-provider-alks* &&
rm -rf terraform-provider-alks-tmp &&
Expand Down
1 change: 1 addition & 0 deletions docs/resources/alks_iamtrustrole.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The following arguments are supported:
* `name` - (Required) The name of the IAM role to create. This parameter allows a string of characters consisting of upper and lowercase alphanumeric characters with no spaces. You can also include any of the following characters: =,.@-. Role names are not distinguished by case.
* `type` - (Required) The role type to use `Cross Account` or `Inner Account`.
* `trust_arn` - (Required) Account role ARN to trust.
* _Note: This only allows **ONE** account role ARN. This is an intended security control by CAI._
* `role_added_to_ip` - (Computed) Indicates whether or not an instance profile role was created.
* `arn` - (Computed) Provides the ARN of the role that was created.
* `ip_arn` - (Computed) If `role_added_to_ip` was `true` this will provide the ARN of the instance profile role.
Expand Down
2 changes: 1 addition & 1 deletion examples/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ terraform {
required_providers {
alks = {
source = "Cox-Automotive/alks"
version = "2.0.4"
version = "2.0.5"
}
aws = {
source = "hashicorp/aws"
Expand Down
102 changes: 4 additions & 98 deletions resource_alks_iamrole.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ package main
import (
"context"
"fmt"
"log"

"github.com/Cox-Automotive/alks-go"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"log"
"strings"
"time"
)

func resourceAlksIamRole() *schema.Resource {
Expand All @@ -23,7 +21,7 @@ func resourceAlksIamRole() *schema.Resource {
StateContext: schema.ImportStatePassthroughContext,
},
SchemaVersion: 1,
MigrateState: migrateState,
MigrateState: migrateState,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Expand Down Expand Up @@ -67,54 +65,6 @@ func resourceAlksIamRole() *schema.Resource {
}
}

func resourceAlksIamTrustRole() *schema.Resource {
return &schema.Resource{
CreateContext: resourceAlksIamTrustRoleCreate,
ReadContext: resourceAlksIamRoleRead,
UpdateContext: resourceAlksIamRoleUpdate,
DeleteContext: resourceAlksIamRoleDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
SchemaVersion: 1,
MigrateState: migrateState,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"trust_arn": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"role_added_to_ip": {
Type: schema.TypeBool,
Computed: true,
},
"arn": {
Type: schema.TypeString,
Computed: true,
},
"ip_arn": {
Type: schema.TypeString,
Computed: true,
},
"enable_alks_access": {
Type: schema.TypeBool,
Default: false,
Optional: true,
},
},
}
}

func resourceAlksIamRoleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
log.Printf("[INFO] ALKS IAM Role Create")

Expand Down Expand Up @@ -147,50 +97,6 @@ func resourceAlksIamRoleCreate(ctx context.Context, d *schema.ResourceData, meta
return resourceAlksIamRoleRead(ctx, d, meta)
}

func resourceAlksIamTrustRoleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
log.Printf("[INFO] ALKS IAM Trust Role Create")

var roleName = d.Get("name").(string)
var roleType = d.Get("type").(string)
var trustArn = d.Get("trust_arn").(string)
var enableAlksAccess = d.Get("enable_alks_access").(bool)

client := meta.(*alks.Client)
if err := validateIAMEnabled(client); err != nil {
return diag.FromErr(err)
}

var resp *alks.IamRoleResponse
err := resource.Retry(2*time.Minute, func() *resource.RetryError {
var err error
resp, err = client.CreateIamTrustRole(roleName, roleType, trustArn, enableAlksAccess)
if err != nil {
if strings.Contains(err.Error(), "Role already exists") || strings.Contains(err.Error(), "Instance profile exists") {
return resource.NonRetryableError(err)
}

// Due to IAM eventual consistency, you might've just created a role that you need to link to a trust
// We'll keep checking every 15 seconds for up to 2 minutes to see if the role appears
time.Sleep(15 * time.Second)
return resource.RetryableError(err)
}
return nil
})

if err != nil {
return diag.FromErr(err)
}

response := *resp

d.SetId(response.RoleName)
_ = d.Set("role_added_to_ip", resp.RoleAddedToIP)

log.Printf("[INFO] alks_iamtrustrole.id: %v", d.Id())

return resourceAlksIamRoleRead(ctx, d, meta)
}

func resourceAlksIamRoleDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
log.Printf("[INFO] ALKS IAM Role Delete")

Expand Down Expand Up @@ -302,4 +208,4 @@ func migrateV0toV1(state *terraform.InstanceState) (*terraform.InstanceState, er
}

return state, nil
}
}
67 changes: 3 additions & 64 deletions resource_alks_iamrole_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package main

import (
"fmt"
"log"
"testing"

"github.com/Cox-Automotive/alks-go"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"log"
"testing"
)

func TestAccAlksIamRole_Basic(t *testing.T) {
Expand Down Expand Up @@ -46,39 +47,6 @@ func TestAccAlksIamRole_Basic(t *testing.T) {
})
}

func TestAccAlksIamTrustRole_Basic(t *testing.T) {
var resp alks.IamRoleResponse

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAlksIamRoleDestroy(&resp),
Steps: []resource.TestStep{
{
Config: testAccCheckAlksIamTrustRoleConfigBasic,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"alks_iamtrustrole.bar", "name", "bar"),
resource.TestCheckResourceAttr(
"alks_iamtrustrole.bar", "type", "Inner Account"),
),
},
{
// update the resource
Config: testAccCheckAlksIamTrustRoleConfigUpdateBasic,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"alks_iamtrustrole.bar", "name", "bar"),
resource.TestCheckResourceAttr(
"alks_iamtrustrole.bar", "type", "Inner Account"),
resource.TestCheckResourceAttr(
"alks_iamtrustrole.bar", "enable_alks_access", "true"),
),
},
},
})
}

func testAccCheckAlksIamRoleDestroy(role *alks.IamRoleResponse) resource.TestCheckFunc {
return func(s *terraform.State) error {
client := testAccProvider.Meta().(*alks.Client)
Expand Down Expand Up @@ -128,32 +96,3 @@ const testAccCheckAlksIamRoleConfigUpdateBasic = `
enable_alks_access = true
}
`

const testAccCheckAlksIamTrustRoleConfigBasic = `
resource "alks_iamrole" "foo" {
name = "foo"
type = "Amazon EC2"
include_default_policies = false
}
resource "alks_iamtrustrole" "bar" {
name = "bar"
type = "Inner Account"
trust_arn = "${alks_iamrole.foo.arn}"
}
`

const testAccCheckAlksIamTrustRoleConfigUpdateBasic = `
resource "alks_iamrole" "foo" {
name = "foo"
type = "Amazon EC2"
include_default_policies = false
}
resource "alks_iamtrustrole" "bar" {
name = "bar"
type = "Inner Account"
trust_arn = "${alks_iamrole.foo.arn}"
enable_alks_access = true
}
`
110 changes: 110 additions & 0 deletions resource_alks_iamtrustrole.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package main

import (
"context"
"log"
"strings"
"time"

"github.com/Cox-Automotive/alks-go"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourceAlksIamTrustRole() *schema.Resource {
return &schema.Resource{
CreateContext: resourceAlksIamTrustRoleCreate,
ReadContext: resourceAlksIamRoleRead,
UpdateContext: resourceAlksIamRoleUpdate,
DeleteContext: resourceAlksIamRoleDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
SchemaVersion: 1,
MigrateState: migrateState,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"trust_arn": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"role_added_to_ip": {
Type: schema.TypeBool,
Computed: true,
},
"arn": {
Type: schema.TypeString,
Computed: true,
},
"ip_arn": {
Type: schema.TypeString,
Computed: true,
},
"enable_alks_access": {
Type: schema.TypeBool,
Default: false,
Optional: true,
},
},
}
}

func resourceAlksIamTrustRoleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
log.Printf("[INFO] ALKS IAM Trust Role Create")

var roleName = d.Get("name").(string)
var roleType = d.Get("type").(string)
var trustArn = d.Get("trust_arn").(string)
var enableAlksAccess = d.Get("enable_alks_access").(bool)

client := meta.(*alks.Client)
if err := validateIAMEnabled(client); err != nil {
return diag.FromErr(err)
}

var resp *alks.IamRoleResponse
err := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError {
var err error
resp, err = client.CreateIamTrustRole(roleName, roleType, trustArn, enableAlksAccess)
if err != nil {
if strings.Contains(err.Error(), "Role already exists") || strings.Contains(err.Error(), "Instance profile exists") {
return resource.NonRetryableError(err)
}

// Amazon IAM utilizes an eventual consistency model:
// https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_eventual-consistency
//
// The newly created IAM role may not exist immediately and could result in dependent
// resources failing non-deterministically. Loop for 15 second increments up to 2
// minutes checking to ensure the resouce was successfully created and is visible.

time.Sleep(15 * time.Second)
return resource.RetryableError(err)
}
return nil
})

if err != nil {
return diag.FromErr(err)
}

response := *resp

d.SetId(response.RoleName)
_ = d.Set("role_added_to_ip", resp.RoleAddedToIP)

log.Printf("[INFO] alks_iamtrustrole.id: %v", d.Id())

return resourceAlksIamRoleRead(ctx, d, meta)
}
Loading

0 comments on commit 0b1fd4f

Please sign in to comment.