Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terraform Definition of Cognito Identity Pool Auth/Unauth Roles

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!

like image 863
cyram Avatar asked Jan 25 '18 20:01

cyram


People also ask

What is the difference between user pool and identity pool?

With a user pool, your app users can sign in through the user pool or federate through a third-party identity provider (IdP). Identity pools are for authorization (access control). You can use identity pools to create unique identities for users and give them access to other AWS services.

What is identity pool in Cognito?

Amazon Cognito identity pools provide temporary AWS credentials for users who are guests (unauthenticated) and for users who have been authenticated and received a token. An identity pool is a store of user identity data specific to your account.

How do I authenticate a Cognito user?

In order to successfully authenticate a user, AWS Cognito needs an Identity pool and a token received from an external authentication provider or from AWS Cognito authentication provider itself.


1 Answers

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
 }

Note: Edited for updated terraform language changes that don't require "${...}" around references any more

like image 184
cyram Avatar answered Nov 15 '22 14:11

cyram