Attach custom iam policy to iam role - amazon-web-services

I'm trying to deal with some terraform scripts that are held across different git repo's.
One of the repo's is used for provisioning eks infrastructure and the other is to hold generic tf scripts.
In the generic repo, I've created a custom iam policy. I want this to be attached to the iam role when the eks infrastructure repo is created. Is there a way to do this?
resource "aws_iam_role_policy_attachment" "eks-worker-node-data-access" {
policy_arn = "arn:aws:iam::aws:policy/base-data-capture"
role = "${module.eks-control-plane.worker_node_role_name}"
}
The policy arn field is set to the name of the policy that would be created, however this fails as it hasn't been imported...
What I'd like to do is something like
resource "aws_iam_role_policy_attachment" "eks-worker-node-data-access" {
source = "my-git-repo.policy"
policy_arn = "arn:aws:iam::aws:policy/base-data-capture"
role = "${module.eks-control-plane.worker_node_role_name}"
}
I suppose the obvious answer would be to just have the policy created in the same tf folder, but all other policies have been created in the generic repo.

Related

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

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"
}

Terraform-AWS IAM role attach managed policy to role only if it isn't attached already

I am attaching few managed policies (existing) to IAM role (existing). I am attaching the policies to the role by aws_iam_role_policy_attachment.
resource "aws_iam_role_policy_attachment" "role_logscreate" {
role = data.aws_iam_role.qrm_role_ASM_access.name
policy_arn = "arn:aws:iam::${local.account_id}:policy/pB-CloudWatchLogsCreate"
}
I want to add a "guard condition" that attach the policy only if it is not already attached to the Role.
Is it possible in terraform.12?
Update #marcin: we are using a Teamcity pipeline for 1-click deployment of the terraform resources. most or the time we are removing the 'all-resources' and that time we de-attach these policies as well from the role. but some times the cherry-pick approach is used and IAM is not part of that. so, there is a possibility that IAM Role still have those policies and it is difficult for TC to detect these changes. so, I want to add the guard condition in my Terraform code. "Attach only if not already attached to IAMRole". hope, there is complete context and clarity why I want to add these guard conditions.

Attach a single IAM policy to two separate roles in two different regions (same account) using terraform and apex

I have a terraform infrastructure setup, where a module is being used in different environments (same account, different regions). The issue I have is that for each environment I need to attach the policy to a Role in that environment. So every time I try to update the infrastructure using apex infra -e <env> apply, the Role previously attached to the Policy is overwritten by the Role in the new environment.
Terraform v0.12.13
Apex version 1.0.0-rc2
Is there any way to tell terraform, to add the Role to the current list of Roles attached to a policy?
data "aws_iam_policy" "ecsPolicy" {
arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}
resource "aws_iam_policy_attachment" "ecs_task_attach" {
name = "${var.apex_environment}_ecsTaskExec"
roles = [aws_iam_role.ecs_task_executor_role.name]
policy_arn = data.aws_iam_policy.ecsPolicy.arn
}
Creating separate policies to attach to different users would be my last
aws_iam_policy_attachment creates exclusive attachment of IAM Policies and override any existing policy attached to the IAM Role.
If you are looking to attach multiple policies to a Single IAM Role, then try using aws_iam_role_policy_attachment (https://www.terraform.io/docs/providers/aws/r/iam_role_policy_attachment.html). This resource should help you to achieve your goal.
Hope this helps.

Use IAM role instead of credentials to create aws resource from an EC2 instance using terraform

We are working on a requirement where we want terraform apply which runs on AWS EC2 instance to use IAM role instead of using credentials(accesskey/secretkey) as part of aws provider to create route53 in AWS.
NOTE: IAM Role added to instance has been provided with policy which gives the role the route53fullaccess.
When we use below syntax in terraform.tf, it works fine. We are able to create route.
SYNTAX:
*provider "aws" {
access_key = "${var.aws_accesskey}
secret_key = "${var.aws_secretkey}
region = "us-east-1"
}
resource "aws_route53_record {}*
But, we want the terraform script to run with IAM Role and not with credentials. (Do not want to maintain credentials file)
STEPS TRIED:
1. Removed provider block from terraform.tf file and run the build.
SYNTAX:
resource "aws_route53_record {}
2.Getting the below error.
Provider.aws :InvalidClientTokenid.
3. Went through the terraform official documentation to use IAM Role. it says to use metadata api. but there is no working sample. (https://www.terraform.io/docs/providers/aws/index.html)
Am new to Terraforms so pardon me if its a basic question. Can someone help with the code/working sample to achieve this ?
You need to supply the profile arn in the "provider" block, not the role, like so :
provider "aws" {
profile = "arn:aws:iam::<your account>:instance-profile/<your role name>"
}
The 'role_arn' key mentioned in the answer above is actually invalid in the 'provider' context.
Insert the following line for IAM role in your terraform script, in provider:
role_arn = "arn:aws:iam::<your account>:role/SQS-Role-demo"