Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jamesdavidson/2003e7ad4b396e7d0111c91f3896fe6f to your computer and use it in GitHub Desktop.
Save jamesdavidson/2003e7ad4b396e7d0111c91f3896fe6f to your computer and use it in GitHub Desktop.
Terraform code to set up a convenient and secure way to get temporary credentials for AWS.
// ## Goal
//
// A convenient and secure way to get temporary credentials for AWS which I can use
// with Terraform or the Python CLI. Sort of like `saml2aws` but in the browser.
//
// ## Implementation
//
// A client-side JS app which uses Cognito and IAM resources as the backend.
//
// 1) Open the app
// 2) Click the 'login' button
// 3) Log in (or sign up) with Cognito
// 5) Find the id_token on the redirect back to the app
// 6) Get some credentials from AWS STS
// 7) Copy those credentials to your clipboard
// 8) Paste them into your shell / command prompt
//
//
// (defn id_token []
// (.get (new js/URLSearchParams (.replace js/location.hash "#" "")) "id_token"))
//
// (defonce credentials
// (new js/AWS.CognitoIdentityCredentials
// #js{"IdentityPoolId" "<identity-pool-id>",
// "Logins" #js{"cognito-idp.ap-southeast-2.amazonaws.com/<user-pool-id>" (id_token)}}
// #js{"region" "ap-southeast-2"}))
//
// https://<name>.auth.ap-southeast-2.amazoncognito.com/login?client_id=<app-client-id>&response_type=token&redirect_uri=https%3A%2F%2Flocalhost%2F"}
//
provider "aws" {
region = "${var.region}"
}
variable "region" {
default = "ap-southeast-2"
}
variable "name" {
description = "What to call the user pool, also used in domain name."
}
resource "aws_cognito_user_pool" "pool" {
name = "${var.name}"
admin_create_user_config {
allow_admin_create_user_only = true
}
}
resource "aws_cognito_user_pool_domain" "main" {
domain = "${var.name}"
user_pool_id = "${aws_cognito_user_pool.pool.id}"
}
resource "aws_cognito_user_pool_client" "client" {
name = "${var.name}"
user_pool_id = "${aws_cognito_user_pool.pool.id}"
allowed_oauth_flows_user_pool_client = true
supported_identity_providers = [
"COGNITO",
]
allowed_oauth_flows = [
"implicit",
]
allowed_oauth_scopes = [
"email",
"openid",
]
callback_urls = [
"https://localhost",
]
logout_urls = [
"https://localhost",
]
default_redirect_uri = "https://localhost"
}
resource "aws_cognito_identity_pool" "main" {
identity_pool_name = "${var.name}"
allow_unauthenticated_identities = false
cognito_identity_providers {
client_id = "${aws_cognito_user_pool_client.client.id}"
provider_name = "cognito-idp.${var.region}.amazonaws.com/${aws_cognito_user_pool.pool.id}"
server_side_token_check = false
}
}
resource "aws_cognito_identity_pool_roles_attachment" "main" {
identity_pool_id = "${aws_cognito_identity_pool.main.id}"
roles {
"authenticated" = "${aws_iam_role.authenticated.arn}"
"unauthenticated" = "${aws_iam_role.unauthenticated.arn}"
}
}
resource "aws_iam_role" "unauthenticated" {
name = "Cognito_${var.name}Unauth_Role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "${aws_cognito_identity_pool.main.id}"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "unauthenticated"
}
}
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "unauthenticated" {
role = "${aws_iam_role.unauthenticated.name}"
policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
resource "aws_iam_role" "authenticated" {
name = "Cognito_${var.name}Auth_Role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "${aws_cognito_identity_pool.main.id}"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "authenticated" {
role = "${aws_iam_role.authenticated.name}"
policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment