How to create a AWS Cognito user with Terraform

In order to automate things, it can be done in terraform using a null_resource and local_exec provisioner to execute your aws cli command

e.g.

resource "aws_cognito_user_pool" "pool" {
  name = "mypool"
}

resource "null_resource" "cognito_user" {

  triggers = {
    user_pool_id = aws_cognito_user_pool.pool.id
  }

  provisioner "local-exec" {
    command = "aws cognito-idp admin-create-user --user-pool-id ${aws_cognito_user_pool.pool.id} --username myuser"
  }
}

As it is not possible to do that directly through Terraform in opposite to matusko solution I would recommend to use CloudFormation template.

In my opinion it is more elegant because:

  • it does not require additional applications installed locally
  • it can be managed by terraform as CF stack can be destroyed by terraform

Simple solution with template could look like below. Have in mind that I skipped not directly related files and resources like provider. Example also contains joining users with groups.

variables.tf

variable "COGITO_USERS_MAIL" {
  type = string
  description = "On this mail passwords for example users will be sent. It is only method I know for receiving password after automatic user creation."
}

cf_template.json

{
  "Resources" : {
    "userFoo": {
      "Type" : "AWS::Cognito::UserPoolUser",
      "Properties" : {
        "UserAttributes" : [
          { "Name": "email", "Value": "${users_mail}"}
        ],
        "Username" : "foo",
        "UserPoolId" : "${user_pool_id}"
      }
    },
    "groupFooAdmin": {
      "Type" : "AWS::Cognito::UserPoolUserToGroupAttachment",
      "Properties" : {
        "GroupName" : "${user_pool_group_admin}",
        "Username" : "foo",
        "UserPoolId" : "${user_pool_id}"
      },
      "DependsOn" : "userFoo"
    }
  }
}

cognito.tf

resource "aws_cognito_user_pool" "user_pool" {
  name = "cogito-user-pool-name"
}

resource "aws_cognito_user_pool_domain" "user_pool_domain" {
  domain       = "somedomain"
  user_pool_id = aws_cognito_user_pool.user_pool.id
}

resource "aws_cognito_user_group" "admin" {
  name         = "admin"
  user_pool_id = aws_cognito_user_pool.user_pool.id
}

user_init.tf

data "template_file" "application_bootstrap" {
  template = file("${path.module}/cf_template.json")

  vars = {
    user_pool_id          = aws_cognito_user_pool.user_pool.id
    users_mail            = var.COGNITO_USERS_MAIL
    user_pool_group_admin = aws_cognito_user_group.admin.name
  }
}

resource "aws_cloudformation_stack" "test_users" {
  name = "${var.TAG_PROJECT}-test-users"

  template_body = data.template_file.application_bootstrap.rendered
}

Sources

  • https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpooluser.html
  • https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudformation_stack

Example Simple project based on:

  • Terraform,
  • Cognito,
  • Elastic Load Balancer,
  • Auto Scaling Group,
  • Spring Boot application
  • PostgreSQL DB.

Security check is made on ELB and Spring Boot. This means that ELB can not pass not authorized users to application. And application can do further security check based on PostgreSQL roleswhich are mapped to Cognito roles.

Terraform Project and simple application:

  • https://github.com/test-aws-cognito Docker image made out of application code:
  • https://hub.docker.com/r/testawscognito/simple-web-app

More information how to run it in terraform git repository's README.MD.


This isn't currently possible directly in Terraform as there isn't a resource that creates users in a user pool.

There is an open issue requesting the feature but no work has yet started on it.