We write a lot of labs here at Skillmix. We need to make sure the labs sessions have only the permissions needed for the student to complete their work.
We used to write lab IAM Policies by hand, starting off with a best guess, and then trial and error our way through it. Suffice to say, this was brutal. Especially when creating labs for tools like Terraform.
Then, one day, the clouds parted and iamlive descended. It took a little bit of time to learn how it works, but now that we have it working, it is a big productivity booster.
Of course, labs aren't the only reason why you'd want this. Overall, it's a security best practice to create least-privilege IAM policies.
How iamlive Works
There are two iamlive
modes. The first is called Client Side Monitoring (CSM) mode. According to the repo, this is the default mode, and "...will use metrics delivered locally via UDP to capture policy statements with the IAM Action key only...". This means you'll only get the "Action": "ec2:RunInstances"
... part of the IAM policy.
The other mode is Proxy Mode. This mode starts up a local web server at http://127.0.0.1:10080
that will intercept and inspect requests sent to AWS endpoints to generate the IAM Policy statements. It includes both the Action
and Resource
parts of the IAM Policy.
We will show you how to use the Proxy Mode.
Step 1 - Setup a Test Terraform Project
Open a terminal window. We will refer to this as Terminal #1. Create a directory somewhere, and create a file named main.tf
, and paste in these contents:
Terminal #1 (contents of main.tf
)
variable "region" {
type = string
default = "us-west-2"
}
provider "aws" {
region = var.region
}
resource "aws_s3_bucket" "app" {}
After the project is created, run the init
command. It's important that you only run this command for now.
Terminal #1
$ terraform init
Step 2 - Install iamlive
There are several ways to install iamlive
. Please review the repo's Installation docs and select the one that suits you best. We used Macs and used the brew
installation method. It worked well.
The rest of these steps assume that you are able to access iamlive
from your terminal or command prompt.
Step 3 - Start iamlive
Open another terminal window, Terminal #2, and start iamlive
. After executing it, nothing will show up in the window yet.
Terminal #2
$ iamlive --mode proxy
Step 4 - Set Environment Variables
Switch over to Terminal #1 (the one where you created the Terraform project) set these environment variables. Change the access key and secret keys to your own IAM User.
Terminal #1
$ export AWS_CA_BUNDLE=~/.iamlive/ca.pem
$ export HTTP_PROXY=http://127.0.0.1:10080
$ export HTTPS_PROXY=http://127.0.0.1:10080
$ export AWS_ACCESS_KEY_ID="Real Key"
$ export AWS_SECRET_ACCESS_KEY="Real Key"
Regarding the access key and secret key permissions, there are a couple options:
- Full Admin Policy: If you wan to move fast, you can give the IAM User full admin rights. If you do this, it's best to be on a non-prod account, and to manage your keys according to best practices
- Limited Policy: You can also start with a limited policy for the IAM User. However, when you run terraform init, it will fail, and you will need to iterate adding permissions to this policy until you get the full policy
Step 5 - Run Terraform Init
We are not at the moment of truth! It's time to run terraform init
from Terminal #1, and watch the the policies generate in Terminal #2.
Terminal #1
$ terraform apply
$ terraform destroy
Terminal #2
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sts:GetCallerIdentity",
"ec2:DescribeAccountAttributes"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:ListBucket",
"s3:DeleteBucket"
],
"Resource": "arn:aws:s3:::terraform-20210916234458844600000001"
},
{
"Effect": "Allow",
"Action": [
"s3:GetBucketAcl",
"s3:GetBucketCORS",
"s3:GetBucketWebsite",
"s3:GetBucketVersioning",
"s3:GetAccelerateConfiguration",
"s3:GetBucketRequestPayment",
"s3:GetBucketLogging",
"s3:GetReplicationConfiguration",
"s3:GetEncryptionConfiguration",
"s3:GetBucketObjectLockConfiguration",
"s3:GetBucketTagging"
],
"Resource": "arn:aws:s3:::terraform-20210916234458844600000001"
},
{
"Effect": "Allow",
"Action": [
"s3:GetLifecycleConfiguration"
],
"Resource": "arn:aws:s3:::terraform-20210916234458844600000001"
}
]
}