简体   繁体   中英

How to allow aws programatic user to create resources using assume role

I have created a policy X with ec2 and vpc full access and attached to userA. userA has console access. So, using switch role userA can create instance from console.

Now, userB has programatic access with policy Y with ec2 and vpc full access. But when I tried to create instance using Terraform got error. Error: creating Security Group (allow-80-22): UnauthorizedOperation: You are not authorized to perform this operation. Encoded authorization failure message:

Even - aws ec2 describe-instances gives error - An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.

Anyone can help me on this. Thanks in advance.

To be honest there are a couple of mistakes in the question itself but I have ignored them and provided a solution to

  • Create Resources using IAM user with only programmatic access having direct policies attached to it

In general, if you have an AWS IAM user who has programmatic access and already has the required policies attached to it then it's pretty straightforward to create any resources within the permissions. Like any normal use case.

  • Create Resources using IAM user with only programmatic access with assuming a role that has required policies attached to it(role only)

providers.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}
## If you hardcoded the role_arn then it is not required to have two provider configs(one with hardcoded value is enough without any alias).

provider "aws" {
  region = "eu-central-1"
}

provider "aws" {

  alias  = "ec2_and_vpc_full_access"
  region = "eu-central-1"

  assume_role {
    role_arn = data.aws_iam_role.stackoverflow.arn
  }
}

resources.tf

/*
!! Important !!
* Currently the AWS secrets(AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY) used for authentication to terraform is 
* from the user which has direct AWS managed policy [IAMFullAccess]  attached to it to read role arn.
*/

# If you have hardcoded role_arn in the provider config this can be ignored and no usage of alias provider config is required 
## using default provider to read the role.
data "aws_iam_role" "stackoverflow" {
  name = "stackoverflow-ec2-vpc-full-access-role"
}

# Using provider with the role having aws managed policies [ec2 and vpc full access] attached
data "aws_vpc" "default" {
  provider = aws.ec2_and_vpc_full_access

  default = true

}

# Using provider with the role having AWS managed policies [ec2 and vpc full access] attached
resource "aws_key_pair" "eks_jump_host" {
  provider = aws.ec2_and_vpc_full_access

  key_name   = "ec2keypair"
  public_key = file("${path.module}/../../ec2keypair.pub")

}

# Example from https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance
# Using provider with the role having aws managed policies [ec2 and vpc full access] attached
data "aws_ami" "ubuntu" {
  provider = aws.ec2_and_vpc_full_access

  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
  owners = ["099720109477"] # Canonical

}

# Using provider with the role having aws managed policies [ec2 and vpc full access] attached
resource "aws_instance" "terraform-ec2" {
  provider = aws.ec2_and_vpc_full_access

  ami             = data.aws_ami.ubuntu.id
  instance_type   = "t2.micro"
  key_name        = "ec2keypair"
  security_groups = [aws_security_group.t-allow_tls.name]

}

# Using provider with the role having aws managed policies [ec2 and vpc full access] attached
resource "aws_security_group" "t-allow_tls" {
  provider = aws.ec2_and_vpc_full_access

  name        = "allow-80-22"
  description = "Allow TLS inbound traffic"
  vpc_id      = data.aws_vpc.default.id
  ingress {
    description      = "http"
    from_port        = 80
    to_port          = 80
    protocol         = "tcp"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }
}

For a full solution refer to Github Repo , I hope this is something you were looking and helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM