Git Product home page Git Product logo

terraform-provider-alks's Introduction

ALKS Provider for Terraform

Build Status

This provider is for creating and modifying IAM roles via the ALKS API.

Pre-Requisites

  • An ALKS Admin or IAMAdmin STS assume-role session needed. PowerUser access is not sufficient to create IAM roles.
    • This tool is best suited for users with an Admin role
    • With an IAMAdmin|LabAdmin role, you can create roles and attach policies, but you can't create other infrastructure.
  • Works with Terraform version 0.10.0 or newer.

Building from Source

To build the ALKS provider, install Go (preferably version 1.14.4 or greater).

Clone this repository and cd into the cloned directory. All the necessary dependencies are vendored, so type make build test to build and test the project. If this exits with exit status 0, then everything is working! Check your examples directory for an example Terraform script and the generated binary.

git clone https://github.com/Cox-Automotive/terraform-provider-alks.git
cd terraform-provider-alks
make build test

As stated above, if the tests run, everything is working. What you won't see are any passing tests. To get to an operational testing state:

  1. set the ALKS_URL and TF_ACC environment variables
export TF_ACC=true
export ALKS_URL=https://dev.alks.coxautoinc.com/rest
  1. Copy the environment variables from CoxAT Labs 95 (ALKS Dev) into your terminal
export AWS_ACCESS_KEY_ID=<key_from_alks_web>
export AWS_SECRET_ACCESS_KEY=<key_from_alks_web>
export AWS_SESSION_TOKEN=<token_from_alks_web>
export AWS_DEFAULT_REGION=us-east-1

If an error stating Role already exists with the same name: <role-name> is encountered during testing (errored out tests do not initiate resource tear down), navigate to the AWS console of the Labs account from ALKSWeb and manually delete the IAM role listed in the error.

If you need any additional dependencies while developing, add the dependency by running go get <dependency> and then add it to the vendor folder by running go mod vendor.

Updating The Version of alks-go

If using VSCode, hover over the versioned alks-go import in go.mod and click on the link to go.dev (Go package index). The latest version should have the commit hash at the HEAD of master (you may have to wait for the site to update ~ 20 min). Copy the version number and paste it over the previous version in go.mod. On the command line:

go mod download github.com/Cox-Automotive/alks-go
go mod vendor
go mod tidy

At this point, the dependency should reflect the state of alks-go's master branch

Documentation

Documentation and examples can be found on the Terraform website.

terraform-provider-alks's People

Contributors

aaron-seitz avatar amagana3 avatar americk0 avatar anandhs avatar brianantonelli avatar codezninja avatar codykoelemay avatar devopsdave avatar ed-kozlowski avatar ekozlowski avatar elliottzack429 avatar kerryhatcher avatar kulinski avatar lumac0 avatar markhuber avatar ntangy avatar say25 avatar sbrinkerhoff avatar twang817 avatar webbbarker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-provider-alks's Issues

Validate IAM credentials only when modifying resources

There are use cases where Terraform may be shared between legacy and managed accounts or where PowerUsers need to manage resources in a Terraform project with pre-scaffolded IAM roles/policies. If the IAM functionality enabled check was moved to resource update/create that would enable those use cases while still retaining good user messaging for other Terraform users.

Feature Request: Support import of existing roles into Terraform state

I've had several instances where my Terraform state got out of sync with the roles provisioned by this provider and would have really liked to leverage terraform import and/or terraform refresh to recover. Manual editing of the state would probably have resolved my issue, but it was easier at the time to simply delete and recreate the roles in question.

[Feature Request] Switch between ALKS Accounts

As a user of the TFP, it'd be nice if I could switch between other ALKS accounts I have access to directly in the provider definition. Specifically, if I am authenticated as a user with (STS credentials to an ALKS managed role) I would like to be able to switch to another account and role that I also have access to. This would enable me to more eloquently manage cross account resources manually, for example ACM and Route53.

This can be managed today via manually embedding multiple keys or using a credentials file, but it would be helpful if the TFP could handle this directly.

Perhaps something that looks a bit like:

provider "alks" {
   url     = "https://alks.foo.com/rest"
   version = "~> 1.3.0"
   switch_accounts {
      account_number = "1234567890"
      role = "Admin"
   }
}

Error when using sample code

I am using the same role from the fuel page. I have the provider set using only ALKS_ environment variables. Here is the code.

Provider:

# Create the ALKS Provider
provider "alks" {
  url = "https://alks.coxautoinc.com/rest"
}

Role Creation Code:

resource "alks_iamrole" "test_role" {
  name                     = "aba-test-123456"
  type                     = "Amazon EC2"
  include_default_policies = false
}

Error:

alks_iamrole.test_role: Creating...
  arn:                      "" => "<computed>"
  include_default_policies: "" => "false"
  ip_arn:                   "" => "<computed>"
  name:                     "" => "aba-test-123456"
  role_added_to_ip:         "" => "<computed>"
  type:                     "" => "Amazon EC2"

Error: Error applying plan:

1 error(s) occurred:

* alks_iamrole.test_role: 1 error(s) occurred:

* alks_iamrole.test_role: Error parsing CreateRole response: invalid character '<' looking for beginning of value

Add support for AWS tagging

Would be great if this provider would support pass-through for tags, like the native aws_iam_role resource does.

resource "alks_iamrole" "my_role" {
  name = "my-role"
  type = "AWS CodeBuild"
  tags = {
    app = "my app"
    env = "my env"
  }
}

Update for Cross-Account Role Support

ALKS handles validation of business rules on the server side. Ping me for our blog posts on this subject if needed.

Role type is Cross Account
Need to pass a trustArn as well

incorrect test for max_session_duration_in_seconds?

In

const testAccCheckAlksIamRoleConfigUpdateNoMaxDuration = `
resource "alks_iamrole" "foo" {
name = "bar430"
type = "Amazon EC2"
include_default_policies = false
enable_alks_access = true
max_session_duration_in_seconds = 3600
}

the variable name indicates that perhaps no max_session_duration_in_seconds should be provided. I think the test at

resource.TestCheckResourceAttr(
"alks_iamrole.foo", "max_session_duration_in_seconds", "3600"),
was supposed to check for a default value, but as written, the test is no different from the one at
resource.TestCheckResourceAttr(
"alks_iamrole.foo", "max_session_duration_in_seconds", "3600"),

Add support for "version" in provider config

Like the AWS provider, it would be nice to support a "version" attribute on the provider, so that developers get a reasonable error message when their installed version of the provider is not new enough to support new features.

For example, I have provider version 1.0.0 installed and tried to create a new trust role with enable_alks_access. The following error message was cryptic and misleading:

Error: alks_iamtrustrole.my_trust_role: : invalid or unknown key: enable_alks_access

(The solution was to upgrade my ALKS provider, but there is no way to specify the minimum version required in your Terraform configuration).

Unable to apply service role to elastic beanstalk

in eb, you can specify both an ec2-role and a service role.

Using terraform with alks provider, we are seeing the ec2_role is applied, but ServiceRole is not.

This happens on this a specific account. However when Kevin T. tried this on another account (one of his), it did work there. Just not here. So, this is one is a little odd.

The only other difference i noticed by looking at the state file, is ec2-role computes this: "role_added_to_ip": "true",

where as the service-role computes this:
"role_added_to_ip": "false",

module "beanstalk" {
source = "../../components/beanstalk"
...
beanstalk_service_role = "${alks_iamrole.beanstalk_service.arn}"
beanstalk_ec2_role = "${alks_iamrole.beanstalk_ec2.ip_arn}"
}

resource "alks_iamrole" "beanstalk_service" {
name = "${aws_elastic_beanstalk_application.example.name}-beanstalk-service-role"
type = "AWS Elastic Beanstalk"
include_default_policies = true
}

variable "beanstalk_service_role" {
default = "aws-elasticbeanstalk-service-role"
}

setting {
namespace = "aws:elasticbeanstalk:environment"
name = "ServiceRole"
value = "${var.beanstalk_service_role}"
}

Allow plan/apply/destroy without IAMAdmin role if it's not necessary

Not all of our developers have access to an IAMAdmin role, so it would be nice if IAMAdmin credentials weren't required for:

  • plan (all accounts seem to have read-only access to IAM).
  • apply, if there are no new/changed/destroyed resources.
  • destroy, if there are no resources to destroy.

This would allow us to put our ALKS terraform alongside our application terraform without having to open an IAMAdmin session that doesn't get used.

alks_iamrole does not get recreated when include_default_policies is changed from true to false

Plan

  # alks_iamrole.ec2-role must be replaced
+/- resource "alks_iamrole" "ec2-role" {
      ~ arn                      = "arn:aws:iam::247721768464:role/acct-managed/ec2-widget-tunnel-us-east-1" -> (known after apply)
      ~ id                       = "ec2-widget-tunnel-us-east-1" -> (known after apply)
      ~ include_default_policies = true -> false # forces replacement
      ~ ip_arn                   = "arn:aws:iam::247721768464:instance-profile/acct-managed/ec2-widget-tunnel-us-east-1" -> (known after apply)
        name                     = "ec2-widget-tunnel-us-east-1"
      ~ role_added_to_ip         = true -> (known after apply)
        # (2 unchanged attributes hidden)
    }

Expected Behavior

Role is recreated.

Actual Behavior

╷
│ Error: Error creating role: [zmdd8yjb] Role already exists with the same name: ec2-widget-tunnel-us-east-1
│ 
│   with alks_iamrole.ec2-role,
│   on iam.tf line 3, in resource "alks_iamrole" "ec2-role":
│    3: resource "alks_iamrole" "ec2-role" {

This can be bypassed by manually deleting the role through ALKS and reapplying terraform.

Terraform 0.15.x
ALKS Terraform Provider 1.5.15

local install page instructions have wrong version of plugin

I had an ALKS-related problem while trying to initialize a terraform project after following the plugin installation instructions.
I think the local installation page instructs to download the wrong version:

The curl command in the one-liner in the terraform v0.12 section installs (as of 2022-01-19) v2.0.7, but this is incompatible with terraform 0.12 according to the version matrix.

I changed it from

curl -Ls https://api.github.com/repos/Cox-Automotive/terraform-provider-alks/releases/**latest**

to

curl -Ls https://api.github.com/repos/Cox-Automotive/terraform-provider-alks/releases/**tags/v1.5.15**

to get the correct version. After doing so I was able to successfully terraform init.

(On the other hand, the one-liner in the terraform v0.13+ section could actually use the releases/latest endpoint but has a hardcoded 2.0.5.

Missing provider config error handling

If the ALKS provider is defined and resources are used but no provider config is given there is a very vague error message returned.

│ Error: Missing required argument
│ 
│ The argument "url" is required, but was not set.

While this message makes sense, it is not clear that its being thrown from the ALKS provider. The provider should supply additional information to indicate where the error originated. Currently this is only debuggable by putting Terraform into debug mode which shows the error comes from the ALKS provider:

..... 
2022-11-19T00:16:36.133-0500 [ERROR] vertex "provider[\"registry.terraform.io/cox-automotive/alks\"]" error: Missing required argument
.....
2022-11-19T00:16:39.938-0500 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2022-11-19T00:16:39.940-0500 [DEBUG] provider: plugin process exited: path=.terraform/providers/registry.terraform.io/cox-automotive/alks/2.7.1/darwin_amd64/terraform-provider-alks_v2.7.1 pid=87573

alks_iamrole type change goes unnoticed

We're using version 0.9.11 with Terraform 0.9.11.

Scenario

  1. We create an alks_iamrole of type = "Amazon EC2".
  2. Everything works right; some time passes.
  3. Someone (via a ticket) changes the Trust Policy on this role.
  4. Terraform plan shows no changes

Expected Behavior

Terraform plan shows either a different "type" for the role, or an unknown "type".

I don't know the ALKS API very well, but it feels like this violates the idempotent and authoritative nature of terraform.

Support for assume_role pattern in provider

Background

Now that this provider supports STS based authentication, it can leverage the IAM identity to authorize itself to ALKS APIs. After the completion of #26 we will also be able to use an IAM Role (for example from a Jenkins machine or Codebuild job) as an authenticated identity.

In the same account, this will allow a Jenkins build job to make calls to the ALKS API without need for an active directory service account. The IAM authenticated identity is only authorized to enact changes within its own account. It is a common pattern for dev environment jenkins to assume a role in production accounts to do deployments. In that case, the terraform aws provider assumes a role in production before acting.

Suggestion

terraform-provider-alks provider node should support the same pattern that the aws provider supports. It should allow the user to assume a role just before execution of tf apply so that the call is authorized under a different set of IAM credentials. We assume that the starting credentials have the rights to to the target IAM role for standard aws iam assume-role calls.

Subsequent calls to the ALKS API should be called with the STS credentials provided from the assume-role action.

I believe all contracts and behaviors can be mirrored identical to the aws provider.
Ref: https://www.terraform.io/docs/providers/aws/#assume_role

Needs more than one service for IAM trust policy for lambda edge features.

Issue came up when we need to add "edgelambda.amazonaws.com" to existing lambda role's trust policy ( which already contains "lambda.amazonaws.com" as a principal ) it's required for all lambda edge features.

https://registry.terraform.io/providers/Cox-Automotive/alks/latest/docs/resources/alks_iamrole
per doc Specifying a custom trust policy like this is currently only supported for single-service trust policies trusting an approved AWS service,

New IAM Enabled check breaks code where ALKS use is optional

We have a module that CAN use alks to manage IAM resources if needed, but it's not required (and indeed not possible) in some environments. Since there's no way to declare a provider as optional in the required_providers stanza in the module itself, we always declare the provider in the code using the module so the module has the reference, but the usage of alks_iamrole resources in the module will be conditionally removed when not needed.

Now that the provider checks for the credentials being used to be IAM Enabled, we can no longer do this. Even plans fail with

11:59:20 Error: Looks like you are not using ALKS IAM credentials. This will result in errors when creating roles. 
11:59:20  Note: If using ALKS CLI to get credentials, be sure to use the '-i' flag. 
11:59:20  Please see https://coxautoinc.sharepoint.com/sites/service-internal-tools-team/SitePages/ALKS-Terraform-Provider---Troubleshooting.aspx for more information.
11:59:20 
11:59:20   on main.tf line 23, in provider "alks":
11:59:20   23: provider "alks" {
11:59:20 
11:59:20 

Is there any way to not do this check until the provider is actually trying to create an alks_iamrole resource rather than provider initialization time?

Pull Credentials from Container for ECS and CodeBuild environments

To better match the default AWS TF Provider's capability the credentials from containers should be pulled in automagically like the default AWS TF Provider.

I spoke to @webbbarker about this already and he helped compile some of this information.

This is the implementation of this on the default AWS TF Provider
https://github.com/hashicorp/aws-sdk-go-base/blob/master/awsauth.go#L197

Here are some additional links
This is the 5th in line to be used as a credential source
https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html#config-settings-and-precedence

Additional AWS Documentation
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html

Terraform doc on the subject
https://www.terraform.io/docs/providers/aws/index.html#ecs-and-codebuild-task-roles

Fix Public TF Registry Setup

TIL: The ALKS Terraform provider is in the public TF Registry, but you can't use it there because it's setup incorrectly (and hence why you have to do the 'ole cURL install procedure)

Seperate `iamtrustrole` from `iamrole`

Summary

Currently the alks_iamrole and alks_iamtrustrole are contained together within resource_alks_iamrole.go and should be separated into separate files, such as resource_alks_iamtrustrole.go.

Specifying account without role silently ignores account

If you add a secondary provider like this:

provider "alks" {
  url = "https://alks.coxautoinc.com/rest"
  account = "you can put literally anything here including the word 'bogus'.  Putting a real account number does nothing useful"
# no role
  alias = "prod"
}

that provider will basically be a duplicate of your "primary" provider and associated resources will go into your "primary" account. You will not get any kind of error.

Password Prompt

Is there a way to mask the password when the provider prompts for it?

Export ip_name attribute

When configuring an aws_instance resource, the iam_instance_profile attribute requires the instance profile name, not its ARN. Can you also export ip_name along with ip_arn?

Idea: support the name_prefix argument for alks_iamrole

Recent implementation of aws_iam_role in Terraform support specifying a name_prefix argument in lieu of name.

This allows for easy creation of unique role names in scenarios where, for example, we might want to stand up several instances of a stack within the same environment.

Attempting to use the name_prefix argument with alks_iamrole results in errors:

Error: alks_iamrole.autoscaling: "name": required field is not set
Error: alks_iamrole.autoscaling: : invalid or unknown key: name_prefix

For now, I am appending my own unique strings, but it would be nice to have this natively supported in the provider!

References: https://www.terraform.io/docs/providers/aws/r/iam_role.html#name_prefix

Remove references to IAM keys

Since ALKS no longer produces federated access keys, it'd help reduce confusion to remove references to things like the -i flag on the ALKS CLI. Perhaps the message could more clearly indicate that the current credentials aren't eligible to manage IAM resources via the ALKS API?

Include client name and version in User-Agent header

We'd like each ALKS client application to return information about its name and version to the ALKS API when executing requests. This information will be used to gather user information and gather insight to aid in troubleshooting. To standardize across technologies, we'd like this client to use the standard User-Agent header to specify its name and version (plus any additional useful information specific to the tool). See the RFC for more details on this
https://tools.ietf.org/html/rfc2616?spm=5176.doc32013.2.3.Aimyd7#section-3.8

Pull credentials from environment if none are specified

Now that ALKS has released machine identities as a way to authenticate against ALKS, the terraform provider could be improved to pull credentials from the same places that the AWS terraform provider pulls from. For example, the alks terraform provider could look for credentials in this order

  1. Static credentials provided in the provider block
  2. Environment variables
  3. Shared credentials file
  4. The EC2 Role that the code is running in (which could be fetched by querying the instance metadata)

Unable To Resolve to Valid Alks Account

Hi Team,

I am trying to use your terraform provider. Following is the environment.

  • I have the AWS creds in my environment vars from a session established through ALKS. I do this with the following command.
    eval $(alks sessions open -d)

The provider and test role are defined as follows in the terraform script.

provider "alks" {
  url     = "${var.ALKS_SERVER}"
}

resource "alks_iamrole" "test_role" {
    name                     = "My_Test_Role"
    type                     = "Amazon EC2"
    include_default_policies = false
}

I am trying to create the test role from your example. This results in the following error message.
alks_iamrole.test_role: Error creating role: Could not resolve [AWSACCOUNT]/ALKS[MYUSERNAME] to a valid ALKS account

When I attempt to use the AWS provider with the generated AWS creds in my environment everything works as expected.

Thanks!

Check if STS is Admin

Users who don't open an admin iam session (-i) are encountering errors:

* alks_iamrole.optimizely_lambda_service_role: Error creating role: Could not resolve 409336414461/ALKScdclose to a valid ALKS account

Let's add functionality to check if the session is an iam session like we do with t7t. Here's the code we use to validate admin, we'll need to do IAMAdmin as well..

  local role=`aws sts get-caller-identity --query '[Arn]' --region "$REGION" --output text`
  if [[ $role != *"assumed-role/Admin/"* ]]; then
    return 0
  else
    return 1
  fi

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.