问题
We have many IAM users, all creating self-serve infrastructure on EC2 using Terraform. Users don't necessarily set the key for their instances, so it's hard to tie an instance to a particular user. I realize we could dig through CloudTrail to find out which users are creating instances, but it seems like it would be simpler to tag the instances with the current IAM username.
The problem is Terraform doesn't appear to expose this - I can use aws_caller_identity
or aws_canonical_user_id
, but they both appear to return the organization account, not the specific IAM username. Is there a data source in Terraform that will return the IAM user creating the instances?
回答1:
It looks like aws_caller_identity doesn't actually call the STS GetCallerId endpoint which would be able to provide the information you need - specifically the UserId and the Arn of the user running the command.
Instead it takes the simpler option and simply uses the accountid
that the AWS client has already defined and simply returns that.
So you have a couple of options here. You could raise a pull request to have the aws_caller_identity
data source actually call the STS GetCallerId endpoint or you could shell out using a local provisioner and use that to tag your resources.
Obviously if people are writing Terraform to directly use the raw resources that Terraform provides then you can't really enforce this other than having something kill anything that's not tagged but that still leaves the issue of people tagging things using someone else's UserId or Arn.
If instead you have a bunch of modules that people then source to use those instead then you could do something ugly like this in the modules that create the EC2 instances:
resource "aws_instance" "instance" {
ami = "ami-123456"
instance_type = "t2.micro"
tags {
Name = "HelloWorld"
}
lifecycle {
ignore_changes = [ "tags.Owner" ]
}
provisioner "local-exec" {
command = <<EOF
owner=`aws sts get-caller-identity --output text --query 'Arn' | cut -d"/" -f2`
aws ec2 create-tags --resources ${self.id} --tags Key=Owner,Value=$${owner}
EOF
}
}
The above Terraform will create an EC2 instance as normal but then ignore the "Owner" tag. After creating the instance it will run a local shell script that fetches the IAM account name/role for the user and then create an "Owner" tag for the instance using that value.
回答2:
To handle multiple instances (using count), you can refer the below code:
resource "aws_instance" "instance" {
count = "${var.instance_number}"
ami = "ami-xxxxxx"
instance_type = "${var.instance_type}"
security_groups = "${concat(list("sg-xxxxxx"),var.security_groups)}"
disable_api_termination = "${var.termination_protection}"
subnet_id = "${var.subnet_id}"
iam_instance_profile = "test_role"
tags {
Name = "prod-${var.cluster_name}-${var.service_name}-${count.index+1}"
Environment = "prod"
Product = "${var.cluster_name}"
}
lifecycle {
ignore_changes = [ "tags.LaunchedBy" ]
}
provisioner "local-exec" {
command = <<EOF
launched_by=`aws iam get-user --profile prod | python -mjson.tool | grep UserName | awk '{print $2;exit; }'`
aws ec2 create-tags --resources ${self.id} --tags Key=LaunchedBy,Value=$${launched_by}
EOF
}
}
来源:https://stackoverflow.com/questions/42310893/getting-iam-username-in-terraform