so here what I'm trying to do: is to create inline policies and attach it to an existing user?
aws_iam_user does create but instead, I would want to attach it to an existing user.
thanks
resource "aws_iam_user" "user" {
name = "arthur"
}
#Create Inline Policies for de-test
resource "aws_iam_user_policy" "arthur" {
name = "arthur inline"
user = aws_iam_user.user.name
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "s3inline",
"Effect": "Allow",
"Action": [
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:ListAccessPoints",
"s3:GetBucketLocation"
],
"Resource": "*"
},
{
"Sid": "s3inline",
"Effect": "Allow",
"Action": [
"s3:GetBucketPublicAccessBlock",
"s3:GetBucketPolicyStatus",
"s3:ListBucket",
"s3:GetBucketAcl"
],
"Resource": "arn:aws:s3:::arthur-store"
}
]
}
EOF
}
Change this:
resource "aws_iam_user" "user" {
name = "arthur"
}
To this:
data "aws_iam_user" "user" {
user_name = "arthur"
}
Or, since you only need the name, there isn't much use to looking up the user at all, so you could just do this in the aws_iam_user_policy:
resource "aws_iam_user_policy" "arthur" {
name = "arthur inline"
user = "arthur"
...
Related
I'm trying to create a job in AWS Glue using the Windows AWS Client and I'm receiving that I'm not authorized to perform: iam:PassRole as you can see:
Console>aws glue create-job --name "aws_glue_test" --role "My_Role" --command "Name=glueetlpythonshell,ScriptLocation=s3://mys3bucket/jobs/aws_glue_test.py,PythonVersion=3"
An error occurred (AccessDeniedException) when calling the CreateJob operation: User: arn:aws:iam::1111:user/My_User is not authorized to perform: iam:PassRole on resource: arn:aws:iam::1111:role/My_Role because no identity-based policy allows the iam:PassRole action
The configuration in AWS is set by using Terraform, something like this:
resource "aws_s3_bucket" "mys3bucket" {
bucket = "mys3bucket"
tags = {
Name = "mys3bucket"
ITOwnerEmail = "my#email.com"
}
}
resource "aws_s3_bucket_acl" "mys3bucket_acl" {
bucket = aws_s3_bucket.mys3bucket.id
acl = "private"
}
#=========IAM user======#
resource "aws_iam_user" "My_User" {
name = "My_User "
path = "/"
}
resource "aws_iam_user_policy" "My_User-p" {
name = "My_User-p"
user = "My_User"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::mys3bucket"
},
{
"Action": "glue:*",
"Effect": "Allow",
"Resource": "*"
},
#-- THIS IS THE SOLUTION -- #
{
"Action":[
"iam:GetRole",
"iam:PassRole"
],
"Effect":"Allow",
"Resource": "*"
}
]
}
EOF
}
#===========S3-Bucket-policy=======#
resource "aws_s3_bucket_policy" "mys3bucket-p" {
bucket = aws_s3_bucket.mys3bucket.id
policy = <<POLICY
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1111:user/My_User"
},
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::mys3bucket/*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1111:user/My_User"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::mys3bucket"
}
]
}
POLICY
}
#===========Glue-policy=======#
resource "aws_iam_role" "My_Role" {
name = "My_Role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": [
"ec2.amazonaws.com",
"glue.amazonaws.com"
]
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
### Attach policy to above Role ###
resource "aws_iam_role_policy_attachment" "My_Role_GlueService_attach" {
role = aws_iam_role.My_Role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSGlueServiceRole"
}
#===========IAM-Pass-Role=======#
resource "aws_iam_policy" "My_IAMPass_policy" {
name = "My_IAMPass_policy"
description = "IAM Pass Role Policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:PassRole"
],
"Resource": "arn:aws:iam::1111:role/My_Role"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "My_IAMPass_attach" {
role = aws_iam_role.My_Role.name
policy_arn = aws_iam_policy.My_IAMPass_policy.arn
}
I tried to attach IAM Pass Role but it still failing and I don't know why.
Any help is welcomed. Thank you in advance
SOLUTION: Added in the Code.
You need to add iam:PassRole action to the policy of the IAM user that is being used to create-job. Something like:
{
"Action": [
"iam:PassRole"
],
"Effect": "Allow",
"Resource": [
"arn:aws:iam::1111:role/My_Role"
],
"Condition": {
"StringLike": {
"iam:PassedToService": [
"glue.amazonaws.com"
]
}
}
}
I have a json file bucketPolicy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:DeleteBucket"
],
"Effect": "Deny",
"Resource": "arn:aws:s3:::$${aws_s3_bucket.destination.id}",
"Principal": {
"AWS": ["*"]
}
}
]
}
And I've created a template_file as such
data "template_file" "test" {
template = file("./templates/destinationBucketPolicy.json")
vars = {
(aws_s3_bucket.destination.id) = var.destination_bucket_name
}
}
But when I try to use this for my bucket policy
resource "aws_s3_bucket_policy" "destination" {
bucket = aws_s3_bucket.destination.id
policy = data.template_file.test.rendered
}
The value for var.destination_bucket_name does not not get expanded into the policy, instead it appears literally as "Resource": "arn:aws:s3:::${aws_s3_bucket.destination.id}"
Is there a way to get this to expand so that it picks up the actual value for the variable?
These days its better to use templatefile:
locals {
test = templatefile("${path.module}/destinationBucketPolicy.json",
{
bucket_name = var.destination_bucket_name
})
}
with template of:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:DeleteBucket"
],
"Effect": "Deny",
"Resource": "arn:aws:s3:::${bucket_name}",
"Principal": {
"AWS": ["*"]
}
}
]
}
I have seen several links, but I have to see an example.
I have:
resource "aws_iam_role" "role" {
name = "role"
assume_role_policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1590217939125",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::wwe"
},
{
"Sid": "Stmt1590217939125",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::wwe/*"
},
{
"Sid": "Stmt1577967806846",
"Action": [
"secretsmanager:DescribeSecret",
"secretsmanager:GetRandomPassword",
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:ListSecretVersionIds",
"secretsmanager:ListSecrets"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
tags = {
Name = wwe
Environment = STAGE
}
}
When I am making,
terraform apply
I see this:
# aws_iam_role.role will be created
+ resource "aws_iam_role" "role" {
+ arn = (known after apply)
+ assume_role_policy = jsonencode(
{
+ Statement = [
+ {
+ Action = "s3:*"
+ Effect = "Allow"
+ Resource = "arn:aws:s3:::wwe"
+ Sid = "Stmt1590217939125"
},
+ {
+ Action = "s3:*"
+ Effect = "Allow"
+ Resource = "arn:aws:s3:::wwe/*"
+ Sid = "Stmt1590217939125"
},
+ {
+ Action = [
+ "secretsmanager:DescribeSecret",
+ "secretsmanager:GetRandomPassword",
+ "secretsmanager:GetResourcePolicy",
+ "secretsmanager:GetSecretValue",
+ "secretsmanager:ListSecretVersionIds",
+ "secretsmanager:ListSecrets",
]
+ Effect = "Allow"
+ Resource = "*"
+ Sid = "Stmt1577967806846"
},
]
+ Version = "2012-10-17"
}
)
+ create_date = (known after apply)
+ force_detach_policies = false
+ id = (known after apply)
+ max_session_duration = 3600
+ name = "role"
+ path = "/"
+ tags = {
+ "Environment" = "STAGE"
+ "Name" = "wwe"
}
+ unique_id = (known after apply)
}
After, when I am writing yes, I see:
Error: Error creating IAM Role role: MalformedPolicyDocument: Has prohibited field Resource
status code: 400
Where, I have an error ? Please don't post links, to the same questions. I don't understand, where I have an error, Could You please write an example, where I have an error, If it possible.
Thanks for Your attention.
One issue is that you have two statements with the same Sid: Stmt1590217939125.
Sids must be unique. From the docs:
In IAM, the Sid value must be unique within a JSON policy.
The second issue is that assume_role_policy is for a trust policy. Trust policies do not have Resource. They have different form. For instance:
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
To add your policies to the role, you have to use aws_iam_role_policy_attachment. For example, you could do:
resource "aws_iam_policy" "policy" {
name = "my-role"
description = "My policy"
policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1590217939128",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::wwe"
},
{
"Sid": "Stmt1590217939125",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::wwe/*"
},
{
"Sid": "Stmt1577967806846",
"Action": [
"secretsmanager:DescribeSecret",
"secretsmanager:GetRandomPassword",
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:ListSecretVersionIds",
"secretsmanager:ListSecrets"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "test-attach" {
role = "${aws_iam_role.role.name}"
policy_arn = "${aws_iam_policy.policy.arn}"
}
What's wrong with the existing code?
The assume_role_policy attribute of the aws_iam_role resource, is not for granting permissions to calls APIs other than sts:AssumeRole:
assume_role_policy - (Required) The policy that grants an entity permission to assume the role.
NOTE: This assume_role_policy is very similar but slightly different than just a standard IAM policy and cannot use an aws_iam_policy resource. It can however, use an aws_iam_policy_document data source, see example below for how this could work.
How do I fix it?
So, assuming you want this role to be assumable by EC2, you would use an aws_iam_role to declare the IAM Role and its assume_role_policy:
resource "aws_iam_role" "role" {
name = "role"
assume_role_policy = <<-EOF
EOF
tags = {
Name = wwe
Environment = STAGE
}
}
And then use an aws_iam_role_policy to attach an inline policy with the IAM actions you wish to grant that role (along with resources and possible conditions):
resource "aws_iam_role_policy" "policy" {
name = "policy"
role = aws_iam_role.role.id
policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::wwe"
},
{
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::wwe/*"
},
{
"Action": [
"secretsmanager:DescribeSecret",
"secretsmanager:GetRandomPassword",
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:ListSecretVersionIds",
"secretsmanager:ListSecrets"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
You don't need to tuck your JSON along the margin, it can be indented for improved readability:
Terraform also accepts an indented heredoc string variant that is introduced by the <<- sequence:
block {
value = <<-EOT
hello
world
EOT
}
I recommend using an aws_iam_policy_document data source to build your IAM policies. It's avoids annoying quirks of JSON (like no trailing commas) and better supports scenarios where you need to use variables in building your policies (really difficult to escape them properly in all cases):
resource "aws_iam_role_policy" "policy" {
name = "policy"
policy = data.aws_iam_policy_document.policy_doc.json
}
data "aws_iam_policy_document" "policy_doc" {
statement {
actions = [
"s3:*",
]
resources = [
"arn:aws:s3:::wwe",
]
}
statement {
actions = [
"s3:*",
]
resources = [
"arn:aws:s3:::wwe/*",
]
}
statement {
actions = [
"secretsmanager:DescribeSecret",
"secretsmanager:GetRandomPassword",
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:ListSecretVersionIds",
"secretsmanager:ListSecrets",
]
resources = [
"*",
]
}
}
I'm trying to create a pipeline to deploy on Beanstalk but I constantly get an error in the deploy section of the pipeline:
Insufficient permissions
The provided role does not have sufficient permissions to access
Elastic Beanstalk: Access Denied
What am I missing?
/************************************************
* Code Build
***********************************************/
resource "aws_codebuild_project" "project-name-codebuild" {
name = "${var.project}-codebuild"
build_timeout = "15"
service_role = "${aws_iam_role.project-name-codebuild-role.arn}"
artifacts {
type = "CODEPIPELINE"
}
environment {
compute_type = "BUILD_GENERAL1_SMALL"
type = "LINUX_CONTAINER"
image = "aws/codebuild/java:openjdk-8"
}
source {
type = "CODEPIPELINE"
}
tags {
Name = "${var.project}"
Environment = "${var.environment}"
}
}
resource "aws_ecr_repository" "project-name-ecr-repository" {
name = "${var.project}-ecr-repository"
}
resource "aws_iam_role" "project-name-codebuild-role" {
name = "${var.project}-codebuild-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy" "project-name-codebuild-role-policy" {
role = "${aws_iam_role.project-name-codebuild-role.id}"
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
"*"
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
}
]
}
POLICY
}
resource "aws_iam_role_policy_attachment" "project-name-codebuild-role-policy-bucket" {
policy_arn = "${aws_iam_policy.project-name-code-pipeline-bucket-access.arn}"
role = "${aws_iam_role.project-name-codebuild-role.name}"
}
/************************************************
* Code Pipeline
***********************************************/
resource "aws_codepipeline" "project-name-code-pipeline" {
name = "${var.project}-code-pipeline"
role_arn = "${aws_iam_role.project-name-code-pipeline-role.arn}"
artifact_store {
location = "${aws_s3_bucket.project-name-code-pipeline-bucket.bucket}"
type = "S3"
}
stage {
name = "Source"
action {
name = "Source"
category = "Source"
owner = "ThirdParty"
provider = "GitHub"
version = "1"
output_artifacts = [
"source"]
configuration {
Owner = "Owner"
Repo = "project-name"
Branch = "master"
OAuthToken = "${var.github-token}"
}
}
}
stage {
name = "Build-Everything"
action {
name = "Build"
category = "Build"
owner = "AWS"
provider = "CodeBuild"
input_artifacts = [
"source"]
output_artifacts = [
"build"]
version = "1"
configuration {
ProjectName = "${aws_codebuild_project.project-name-codebuild.name}"
}
}
}
stage {
name = "Deploy"
action {
name = "Deploy"
category = "Deploy"
owner = "AWS"
provider = "ElasticBeanstalk"
input_artifacts = [
"build"]
version = "1"
configuration {
ApplicationName = "${aws_elastic_beanstalk_application.project-name.name}"
EnvironmentName = "${aws_elastic_beanstalk_environment.project-name-environment.name}"
}
}
}
}
resource "aws_s3_bucket" "project-name-code-pipeline-bucket" {
bucket = "${var.project}-code-pipeline-bucket"
acl = "private"
}
resource "aws_iam_policy" "project-name-code-pipeline-bucket-access" {
name = "${var.project}-code-pipeline-bucket-access"
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect":"Allow",
"Resource": [
"${aws_s3_bucket.project-name-code-pipeline-bucket.arn}",
"${aws_s3_bucket.project-name-code-pipeline-bucket.arn}/*"
],
"Action": [
"s3:CreateBucket",
"s3:GetAccelerateConfiguration",
"s3:GetBucketAcl",
"s3:GetBucketCORS",
"s3:GetBucketLocation",
"s3:GetBucketLogging",
"s3:GetBucketNotification",
"s3:GetBucketPolicy",
"s3:GetBucketRequestPayment",
"s3:GetBucketTagging",
"s3:GetBucketVersioning",
"s3:GetBucketWebsite",
"s3:GetLifecycleConfiguration",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:GetObjectTagging",
"s3:GetObjectTorrent",
"s3:GetObjectVersion",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging",
"s3:GetObjectVersionTorrent",
"s3:GetReplicationConfiguration",
"s3:ListAllMyBuckets",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListBucketVersions",
"s3:ListMultipartUploadParts",
"s3:PutObject"
]
}
]
}
POLICY
}
resource "aws_iam_role" "project-name-code-pipeline-role" {
name = "${var.project}-code-pipeline-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codepipeline.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy" "project-name-code-pipeline-role-policy" {
name = "${var.project}-code-pipeline-role-policy"
role = "${aws_iam_role.project-name-code-pipeline-role.id}"
policy = <<EOF
{
"Statement": [
{
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketVersioning"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::codepipeline*",
"arn:aws:s3:::elasticbeanstalk*"
],
"Effect": "Allow"
},
{
"Action": [
"codedeploy:CreateDeployment",
"codedeploy:GetApplicationRevision",
"codedeploy:GetDeployment",
"codedeploy:GetDeploymentConfig",
"codedeploy:RegisterApplicationRevision"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"elasticbeanstalk:CreateApplicationVersion",
"elasticbeanstalk:DescribeApplicationVersions",
"elasticbeanstalk:DescribeEnvironments",
"elasticbeanstalk:DescribeEvents",
"elasticbeanstalk:UpdateEnvironment",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeScalingActivities",
"autoscaling:ResumeProcesses",
"autoscaling:SuspendProcesses",
"cloudformation:GetTemplate",
"cloudformation:DescribeStackResource",
"cloudformation:DescribeStackResources",
"cloudformation:DescribeStackEvents",
"cloudformation:DescribeStacks",
"cloudformation:UpdateStack",
"ec2:DescribeInstances",
"ec2:DescribeImages",
"ec2:DescribeAddresses",
"ec2:DescribeSubnets",
"ec2:DescribeVpcs",
"ec2:DescribeSecurityGroups",
"ec2:DescribeKeyPairs",
"elasticloadbalancing:DescribeLoadBalancers",
"rds:DescribeDBInstances",
"rds:DescribeOrderableDBInstanceOptions",
"sns:ListSubscriptionsByTopic"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"lambda:invokefunction",
"lambda:listfunctions"
],
"Resource": "*",
"Effect": "Allow"
},
{
"Action": [
"s3:ListBucket",
"s3:GetBucketPolicy",
"s3:GetObjectAcl",
"s3:PutObjectAcl",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::elasticbeanstalk*",
"Effect": "Allow"
}
],
"Version": "2012-10-17"
}
EOF
}
resource "aws_iam_role_policy_attachment" "project-name-code-pipeline-role-policy-attachment" {
policy_arn = "${aws_iam_policy.project-name-code-pipeline-bucket-access.arn}"
role = "${aws_iam_role.project-name-code-pipeline-role.name}"
}
Came across the same problem,
the issue is that you need to enable s3 access to "arn:aws:s3:::elasticbeanstalk*"
Agree that error message is kind of obscure
I would suggest checking these things to debug:
Did the template create the resources you were expecting?
Does the pipeline role have the right policy attached to it? You can run aws codepipeline get-pipeline to get the pipeline's ARN, and use the IAM console to check that the policy is what you expect.
Are you missing some elastic beanstalk permissions in the policy? I'm not sure you are, but try to change the policy to "elasticbeanstalk:*".
Try to assume the pipeline's role in the console, and try to deploy the elastic beanstalk instance, see if you get any more detailed information from the elastic beanstalk console.
Goal :
I am trying to create the following things A terraform template to
create KMS keys This template should create the key and two IAM roles.
The roles would be one for admin functions and one that allows
encrypt/decrypt I have written the following code
Am I doing the correct thing to achieve my goal?
provider "aws"
{
access_key = "*****************"
secret_key = "4ZJaLh***********"
region = "us-east-1"
}
resource "aws_kms_key" "test_key" {
description = "KMS Test key"
}
resource "aws_kms_alias" "alias" {
name = "alias/test_key"
target_key_id = "${aws_kms_key.test_key.key_id}"
}
#IAM Role and Policy
resource "aws_iam_policy" "kms_user_policy" {
name = "KMS-User-Policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:Encrypt",
"kms:GenerateDataKey",
"kms:ReEncryptTo",
"kms:DescribeKey",
"kms:ReEncryptFrom"
],
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_role" "kms_user_role" {
name = "kms_user_role"
path = "/"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_policy_attachment" "test-attach" {
name = "test-attachment"
roles = ["${aws_iam_role.kms_user_role.name}"]
policy_arn = "${aws_iam_policy.kms_user_policy.arn}"
}