11
votes

I've been trying to create a terraform script for creating a cognito user pool and identity pool with a linked auth and unauth role, but I can't find a good example of doing this. Here is what I have so far:

cognito.tf:

resource "aws_cognito_user_pool" "pool" {
     name = "Sample User Pool"
     admin_create_user_config {
          allow_admin_create_user_only = false
     }

     /* More stuff here, not included*/
 }

 resource "aws_cognito_user_pool_client" "client" {
      name = "client"
      user_pool_id = "${aws_cognito_user_pool.pool.id}"

      generate_secret = true
      explicit_auth_flows = ["ADMIN_NO_SRP_AUTH"]
 }

 resource "aws_cognito_identity_pool" "main" {
      identity_pool_name               = "SampleIdentityPool"
      allow_unauthenticated_identities = false

      cognito_identity_providers {
           client_id               = "${aws_cognito_user_pool_client.id}"
           provider_name           = ""
           server_side_token_check = true
      }
 }

So, I want to tack an auth role and an unauth role to this, but I'm still trying to get my head around how to define and link IAM roles in terraform, but here is what I have so far:

 resource "aws_cognito_identity_pool_roles_attachment" "main" {
      identity_pool_id = "${aws_cognito_identity_pool.main.id}"

      roles {
           "authenticated"   = <<EOF
           {
                actions = ["sts:AssumeRoleWithWebIdentity"]

                principals {
                     type        = "Federated"
                     identifiers = ["cognito-identity.amazonaws.com"]
                }

                condition {
                     test = "StringEquals"
                     variable = "cognito-identity.amazonaws.com:aud"
                     values = ["${aws_cognito_identity_pool.main.id}"]
                }

                condition {
                     test = "ForAnyValue:StringLike"
                     variable = "cognito-identity.amazonaws.com:amr"
                     values = ["authenticated"]
                }
           }
           EOF
           "unauthenticated" = <<EOF
           {
                actions = ["sts:AssumeRoleWithWebIdentity"]

                principals {
                     type        = "Federated"
                     identifiers = ["cognito-identity.amazonaws.com"]
                }

                condition {
                     test = "StringEquals"
                     variable = "cognito-identity.amazonaws.com:aud"
                     values = ["${aws_cognito_identity_pool.main.id}"]
                }
           }
      EOF
     }
 }

This however, doesn't work. It creates the pools and client correctly, but doesn't attach anything to auth/unauth roles. I can't figure out what I'm missing, and I can't find any examples of how to do this correctly other than by using the AWS console. Any help on working this out correctly in terraform would be much appreciated!

1
Does that actually plan properly? The authenticated and unauthenticated schema elements have a validation that checks that they are ARNs because that's what they should be so a plan should fail on that example.ydaetskcoR
Strangely enough it did. It fails on apply, saying that there was an "Error creating cognito identity pool roles association: NotAuthorizedException: Access to role is forbidden" So they need to be ARNs only and defined elsewhere? I'll try that. Thanks.cyram
I've changed this quite a bit since the original post, but don't have enough reputation to edit. I think where I'm struggling is that I'm not sure what the assume_role_policy definition should look like for the attached IAM role for auth/unauth. Any policy I put here gives an error ranging from invalid JSON (even though it passes any validator) to it having a prohibited field Resourcecyram
Pretty sure you can always edit your own question so you should do that. Even without any rep you should be able to edit other questions and answers (although they will go into a review queue until you hit 2k rep).ydaetskcoR

1 Answers

12
votes

After messing around with this for a few days, i finally figured it out. I was merely getting confused with "Assume Role Policy" and "Policy". Once I had that sorted out, it worked. Here is (roughly) what I have now. I'll put it here in hopes that it will save someone trying to figure this out for the first time a lot of grief.

For User Pool:

 resource "aws_cognito_user_pool" "pool" {
      name = "Sample Pool"
      /* ... Lots more attributes */
 }

For User Pool Client:

 resource "aws_cognito_user_pool_client" "client" {
     name = "client"
     user_pool_id = "${aws_cognito_user_pool.pool.id}"
     generate_secret = true
     explicit_auth_flows = ["ADMIN_NO_SRP_AUTH"]
 }

For Identity Pool:

 resource "aws_cognito_identity_pool" "main" {
      identity_pool_name               = "SampleIdentities"
      allow_unauthenticated_identities = false

      cognito_identity_providers {
           client_id               = "${aws_cognito_user_pool_client.client.id}"
           provider_name = "${aws_cognito_user_pool.pool.endpoint}"
           server_side_token_check = true
      }
 }

Attach Roles to Identity Pool:

 resource "aws_cognito_identity_pool_roles_attachment" "main" {
      identity_pool_id = "${aws_cognito_identity_pool.main.id}"

      roles = {
           authenticated   = "${aws_iam_role.auth_iam_role.arn}"
           unauthenticated = "${aws_iam_role.unauth_iam_role.arn}"
      }
 }
 

And, finally, the roles and policies:

 resource "aws_iam_role" "auth_iam_role" {
      name = "auth_iam_role"
      assume_role_policy = <<EOF
 {
      "Version": "2012-10-17",
      "Statement": [
           {
                "Action": "sts:AssumeRole",
                "Principal": {
                     "Federated": "cognito-identity.amazonaws.com"
                },
                "Effect": "Allow",
                "Sid": ""
           }
      ]
 }
 EOF
 }

 resource "aws_iam_role" "unauth_iam_role" {
      name = "unauth_iam_role"
      assume_role_policy = <<EOF
 {
      "Version": "2012-10-17",
      "Statement": [
           {
                "Action": "sts:AssumeRole",
                "Principal": {
                     "Federated": "cognito-identity.amazonaws.com"
                },
                "Effect": "Allow",
                "Sid": ""
           }
      ]
 }
 EOF
 }

 resource "aws_iam_role_policy" "web_iam_unauth_role_policy" {
      name = "web_iam_unauth_role_policy"
      role = "${aws_iam_role.unauth_iam_role.id}"
      policy = <<EOF
 {
      "Version": "2012-10-17",
      "Statement": [
           {
                "Sid": "",
                "Action": "*",
                "Effect": "Deny",
                "Resource": "*"
           }
      ]
 }
 EOF
 }