Allow ECS task to AssumeRole into another account - amazon-web-services

I've looked at this question and this one but I'm not able to deploy a role into a child account which allows an ECS task running in the parent account to AssumeRole into it.
Terraform code:
data "aws_iam_policy_document" "cross-account-assume-role-child" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "AWS"
identifiers = [
"arn:aws:sts::${var.master_account_ID}:assumed-role/${var.cross_account_role_name}"
]
}
}
}
When I try to run terraform the plan succeeds but the apply fails with such an error:
Error: failed creating IAM Role (ECS-cross-account-child-role):
MalformedPolicyDocument: Invalid principal in policy:
"AWS":"arn:aws:sts::<AWS Account ID>:assumed-role/ECS-cross-account-master-role"
I get the same error if I try to manually update the policy like above in the AWS console so this isn't due to terraform.
What am I doing wrong?

The arn you need to specify in the policy is the one of the IAM role, not of the assumed credentials:
arn:aws:iam::${var.master_account_ID}:role/${var.cross_account_role_name}
Instead of of sts and assumed-role

Related

Create AWS Lambda function using Terraform

I faced with a problem concerning of creation of Lambda function using Terraform. I tried to follow a standard documentation of Terraform to configure it, but in my case it doesn't work. When the Terraform try to create an IAM role for Lambda function I get an error:
"Error: failed creating IAM role ... AccessDenied: User: ... is not authorized to perform: iam:CreateRole on resource: ... because no identity-based policy allows iam:CretaeRole action ..."
Actually, If I correctly understood it requires additional policy for my account or a root privilege, I don't have both and I need to use already existed IAM role. Is there way to configure it in Terraform?
Yes, you can use IAM role with terraform as explaiend in TF docs:
Using AWS AssumeRole with the AWS Terraform Provider

FirehoseDestination - Could not assume IAM role

I am getting following error while Setting up a kinesis data firehose event destination for Amazon SES event publishing using terraform. It seems like the terraform created the IAM role but throwing the error while creating the firehose event destination with IAM role.
Whereas able to attach same IAM role with firehose event destination from AWS console which was created by terraform.
If I manually create the same IAM role using AWS console and then pass the ARN of the role to the terraform it works. However if I try to create the role using terraform and then create the event destination it doesn’t work. Can someone pls help me on this.
Error creating SES configuration set event destination: InvalidFirehoseDestination: Could not assume IAM role <arn:aws:iam::<AWS account name >:role/<AWS IAM ROLE NAME>>.
data "aws_iam_policy_document" "ses_configuration_set_assume_role" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ses.amazonaws.com"]
}
}
}
data "aws_iam_policy_document" "ses_firehose_destination_policy" {
statement {
effect = "Allow"
actions = [
"firehose:PutRecord",
"firehose:PutRecordBatch"
]
resources = [
"<ARN OF AWS FIREHOSE DELIVERY STREAM >"
]
}
}
resource "aws_iam_policy" "ses_firehose_destination_iam_policy" {
name = "SesfirehosedestinationPolicy"
policy = data.aws_iam_policy_document.ses_firehose_destination_policy.json
}
resource "aws_iam_role" "ses_firehose_destination_role" {
name = "SesfirehosedestinationRole"
assume_role_policy = data.aws_iam_policy_document.ses_configuration_set_assume_role.json
}
resource "aws_iam_role_policy_attachment" "ses_firehose_destination_role_att" {
role = aws_iam_role.ses_firehose_destination_role.name
policy_arn = aws_iam_policy.ses_firehose_destination_iam_policy.arn
}
resource "aws_ses_configuration_set" "create_ses_configuration_set" {
name = var.ses_config_set_name
}
resource "aws_ses_event_destination" "ses_firehose_destination" {
name = "event-destination-kinesis"
configuration_set_name = aws_ses_configuration_set.create_ses_configuration_set.name
enabled = true
matching_types = ["send", "reject", "bounce", "complaint", "delivery", "renderingFailure"]
depends_on = [aws_iam_role.ses_firehose_destination_role]
kinesis_destination {
stream_arn = "<ARN OF AWS FIREHOSE DELIVERY STREAM>"
role_arn = aws_iam_role.ses_firehose_destination_role.arn
}
}
You might need to look at your Firehose datasource. If it is a Kinesis Datastream, it will not work. It will only work when using a Direct PUT and other datasource for the Kinesis Firehose. I ran into this issue while setting this up for my Kinesis Firehose to Datadog as well. I hope that this helps.
I found the same issue and was able to resolve it with a slight workaround.
The issue is likely due to the time it takes AWS to propagate the IAM role to all the regions. As an IAM role is global, it will be created first in a 'random' region and then propagated to all regions. So if it is not first created in your region it may take some time to propagate and you will get this error if the SES Event Destination is created before the IAM role has propagated.
It does not help to add a depends_on clause, as terraform (correctly?) thinks the IAM role has been created, it has just not been propagated to your region yet.
The solution that worked for me was to create an IAM role that grants access to the "sts:AssumeRole" action for the SES service and the "firehose:PutRecordBatch" action for the Firehose. When I apply the Terraform, I did a targeted apply first for only this role, waited a minute (to allow the IAM role to propagate) and then do a normal terraform apply to complete.
In your example the command will look something like this:
terraform apply --target aws_iam_role_policy_attachment.ses_firehose_destination_role_att
terraform apply

aws cli fails to return a role policy

I am copying the name of a policy a created (and attached to a role) and running the following command:
▶ aws iam get-role-policy --role-name MyRole --policy-name MyPolicy
however I am getting:
An error occurred (NoSuchEntity) when calling the GetRolePolicy operation: The role policy with name MyPolicy cannot be found.
The policy is right there, I am copying the name from the AWS console.
What is the issue here?
I have also tried the following, that does list the policy
$ aws iam list-attached-role-policies --role-name MyRole
{
"AttachedPolicies": [
{
"PolicyName": "MyPolicy",
"PolicyArn": "arn:aws:iam::123456789:policy/MyPolicy"
}
]
}
(END)
list-attached-role-policies lists all managed policies attached to a role and get-role-policy retrieves an inline policy. In order to retrieve a managed policy you'll want to use get-policy, get the policy version from there and retrieve it using get-policy-version.

How to attach CloudWatchLogsFullAccess to the IAM role of EKS EC2 instance

I use the module, terraform-aws-modules/eks/aws provision EKS. By default, the module provisions three policies to the EKS EC2 IAM role, AmazonEKSWorkerNodePolicy, AmazonEC2ContainerRegistryReadOnly and AmazonEKS_CNI_Policy. I would like to attach an additional policy, CloudWatchLogsFullAccess to the IAM role. I read the doc. I did not find a way to attach it. I had to logon to the AWS console, manually attach CloudWatchLogsFullAccess to the IAM role. Is there a way to use terraform code to attach it when I use this EKS module provisioning EKS?
I added the code below.
resource "aws_iam_role_policy_attachment" "cloudWatch" {
role = module.eks.cluster_iam_role_arn
policy_arn = "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
}
But, it complains "The specified value for roleName is invalid".
Error: Error attaching policy arn:aws:iam::aws:policy/CloudWatchLogsFullAccess to IAM Role arn:aws:iam::678515134618:role/my-eks20210303061731134400000005: ValidationError: The specified value for roleName is invalid. It must contain only alphanumeric characters and/or the following: +=,.#_-
status code: 400, request id: aee57a35-ae72-499e-8653-e61e795818e4
Once you create your eks cluster, you can get cluster_iam_role_arn_from its outputs. Having the ARN you can attach extra policies to it using aws_iam_role_policy_attachment:
resource "aws_iam_role_policy_attachment" "test-attach" {
role = module.myeks.cluster_iam_role_arn
policy_arn = "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
}

Simulate Principal Policy using assumed role

I was wondering how to use simulate-principal-policy using the AWS CLI for an assumed role.
To provide some context, as part of my application's startup, I want to ensure that the application has the necessary permissions to access all the AWS resources it needs. I do this by getting the caller identity using aws sts get-caller-identity and use the returned caller identity as the policy source arn for the simulate-principal-policy request.
When our application runs on EC2, it uses an assumed role. so, get-caller-identity returns an assumed role arn.
If I try to execute simulate-principal-policy using my user arn as the policy source arn, the command works fine.
aws iam simulate-principal-policy --action-names "sqs:Receivemessage" --policy-source-arn "arn:aws:sts::123456789021:user/divesh"
However, trying to execute the command above by using an assumed role reports an error.
aws iam simulate-principal-policy --action-names "sqs:Receivemessage" --policy-source-arn "arn:aws:sts::123456789021:assumed-role/development/development-session"
An error occurred (InvalidInput) when calling the SimulatePrincipalPolicy operation: Invalid Entity Arn: arn:aws:sts::123456789021:assumed-role/development/development-session does not clearly define entity type and name.
Our application runs on a Kubernetes cluster and uses kiam to associate IAM roles to pods.
The problem with your request is that you are using the "Profile ARN" instead of the "Role ARN". To get the Role Arn, you can do the following:
Pull the Role Name from the Instance Profile Arn:
arn:aws:sts::123456789021:assumed-role/development/development-session becomes development/development-session
Get the instance profile based on that name:
aws iam get-instance-profile --instance-profile-name Instance Profile Arn
Find the Role Arn in the resulting document:
{
"InstanceProfile":{
"Roles":[
{
"Arn":"arn:aws:iam::992863558783:role/YourRole"
}
]
}
}
Use this ARN in simulate-principal-policy
aws iam simulate-principal-policy --action-names "sqs:Receivemessage" --policy-source-arn "arn:aws:iam::992863558783:role/YourRole"
In Python, the script would look like this:
import boto3
iam= boto3.client('iam')
profileArn = 'arn:aws:sts::123456789021:assumed-role/development/development-session'
iamProfileName = iamInstanceProfileArn.split(':assumed-role/')[1]
profile = iam.get_instance_profile(InstanceProfileName=iamProfileName)
policySourceArns = []
for role in profile['InstanceProfile']['Roles']:
policySourceArns.append(role['Arn'])
retval = iam.simulate_principal_policy(
PolicySourceArn = policySourceArns[0],
ActionNames = ['sqs:Receivemessage']
)