Call an SSM document from terraform

Viewed 1664

I was wondering if anyone could help with this issue? I'm trying to call an SSM document using terraform to stop an ec2 instance. But, it doesn't seems to work. I keep having the error:

Automation Step Execution fails when it is changing the state of each instance. Get Exception from StopInstances API of ec2 Service. Exception Message from StopInstances API: [You are not authorized to perform this operation. 

Any suggestion here?

As you could see, there are the right roles. I pass it in parameter.

provider "aws" {
  profile = "profile"
  region  = "eu-west-1"
}


data "aws_ssm_document" "stop_ec2_doc" {
  name            = "AWS-StopEC2Instance"
  document_format = "JSON"
}


data "aws_iam_policy_document" "assume_role" {
  version = "2012-10-17"

  statement {
    sid     = "EC2AssumeRole"
    effect  = "Allow"
    actions = ["sts:AssumeRole"]

    principals {
      identifiers = ["ec2.amazonaws.com"]
      type        = "Service"
    }

    principals {
      identifiers = ["ssm.amazonaws.com"]
      type        = "Service"
    }
  }
}

data "aws_ami" "latest_amazon_2" {
  most_recent = true
  owners      = ["amazon"]
  name_regex = "^amzn2-ami-hvm-.*x86_64-gp2"
}


#
resource "aws_iam_role" "iam_assume_role" {
  name                 = "iam_assume_role"
  assume_role_policy   = data.aws_iam_policy_document.assume_role.json
}

# 
resource "aws_iam_role_policy_attachment" "role_1" {
  role       = aws_iam_role.iam_assume_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

# the instance profile
resource "aws_iam_instance_profile" "iam_instance_profile" {
  name = "iam_instance_profile"
  role = aws_iam_role.iam_assume_role.name
}

# amazon ec2 instances
resource "aws_instance" "ec2_instances" {
  count                = 2
  ami                  = data.aws_ami.latest_amazon_2.id
  instance_type        = "t2.micro"
  subnet_id            = "subnet-12345678901"
  iam_instance_profile = aws_iam_instance_profile.iam_instance_profile.name

  root_block_device {
    volume_size = 8
    volume_type = "gp2"

    delete_on_termination = true
  }
}


resource "aws_ssm_association" "example" {
  name = data.aws_ssm_document.stop_ec2_doc.name
  
  parameters = {
    AutomationAssumeRole = "arn:aws:iam::12345678901:role/aws-service-role/ssm.amazonaws.com/AWSServiceRoleForAmazonSSM"
    InstanceId = aws_instance.ec2_instances[0].id
  }
}

Any suggestion is welcome. I tried to create an easy Terraform code to illustrate what I'm trying to do. And to me it should be straight forward. I create the role. I create the instance profile. I create the association passing the proper role and the instance id.

1 Answers

AWSServiceRoleForAmazonSSM role does not have permissions to stop instances. Instead you should create new role for SSM with such permissions. The simplest way is as follows:

resource "aws_iam_role" "ssm_role" {
  name = "ssm_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Service = "ssm.amazonaws.com"
        }
      },
    ]
  })

}

resource "aws_iam_role_policy_attachment" "ec2-attach" {
  role       = aws_iam_role.ssm_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
}

resource "aws_ssm_association" "example" {
  name = data.aws_ssm_document.stop_ec2_doc.name
  
  parameters = {
    AutomationAssumeRole = aws_iam_role.ssm_role.arn
    InstanceId = aws_instance.ec2_instances[0].id
  }
}

The AmazonEC2FullAccess is too permissive just for stopping instances, but I use it as a working example.

Related