department-of-veterans-affairs / va.gov-team

Public resources for building on and in support of VA.gov. Visit complete Knowledge Hub:
https://depo-platform-documentation.scrollhelp.site/index.html
282 stars 203 forks source link

[Discovery] improve internal process to add developers to AWS #186

Closed wyattwalter closed 5 years ago

wyattwalter commented 5 years ago

Description

Right now our internal processes for adding users into AWS is pretty cumbersome. Terraform initially didn't support our needs for getting users temporary credentials by itself, so we had a script that does this, then the user has to be imported into Terraform for long-term management. We need to come up with a better process and document it. This might be made better by Terraform 12, I'm not sure. Or there could be a better way with another tool.

AC

b00klegger commented 5 years ago

Various components:

I propose that we move away from the existing Python user script and adopt a Terraform first approach to managing users. Terraform via the AWS API can provide the temporary credentials users need to login. This temporary password can then be provided back to the user. The user is prompted to reset the password at first login after which they setup an MFA device.

Proposed workflow:

User name(s) are communicated to the devops team with group membership Group membership is adhoc-devs, devops, bah-developers etc A PR is opened in the devops repo, adding the user name(s) to the appropriate group TF user HCL file Group TF user file is namespaced such as iam_users_adhoc_developers.tf, iam_users_bah_developers.tf
The PR is reviewed, approved then merged into master The HCL is then applied by a devops engineer. The temporary password is stored in the TF state and retrieved by the operator via shell pipelines. The encrypted value is decrypted via a script using credstash and GPG.

The temporary login credential is communicated to the user via a 'safe' channel (Slack DM, Keybase)

Items needed:

Code: aws_user.tf

provider "aws" {
  version = "~> 2.0"
  region  = "us-gov-west-1"
}

variable "pgp-file-name" { }

variable "agile_users" {
  type = list(string)
  default = [
  "Ryan.Watson.Agile",
  "Ryan.Watson.Agile2",
  ]
}

locals {
  iam_users = concat(var.oddball_users, var.agile_users)
}

resource "aws_iam_user" "rmw-users" {
  count = length(local.iam_users)
  name = local.iam_users[count.index]
  path = "/"
}

resource "aws_iam_user_login_profile" "rmw-user-profiles" {
  count = length(local.iam_users)
  user    = local.iam_users[count.index]
  pgp_key = filebase64(var.pgp-file-name)
  password_reset_required = true
  depends_on = [aws_iam_user.rmw-users]
}

output "password" {
  value = zipmap(local.iam_users, aws_iam_user_login_profile.rmw-user-profiles.*.encrypted_password)
}

iam_users_oddball.tf

variable "oddball_users" {
    type = list(string)
    default = [
    "Ryan.Watson.Test",
    "Ryan.Watson.Test2",
    ]
}

This is a basic PoC for creating users in this fashion. In my example I use a GPG public key which is stored in the file system rather than imported via Credstash. We can use a similar process to how we manage SSL certificates by passing in values via shell environment variables to import the public key.

A shell script could be written to perform all the functions -- apply the terraform HCL, parse the output of the apply, decrypt it and display in the console.

b00klegger commented 5 years ago

AWS Console access

This is similar to and follows the ssh procedure outlined above. Do not initiate this process until PIV background check is underway.

1. Manager request to create account

2. When your account has been setup, an engineer will DM the engineer a temporary password and login URL.

3. You are required to login and change the temporary password immediately.

ricetj commented 5 years ago

Done