I am trying to set multiple principals (IAM roles) on an S3 bucket's IAM policy, using terraform. The plan looks like this:
Terraform will perform the following actions:
# module.log_bucket.aws_s3_bucket_policy.policy will be updated in-place
~ resource "aws_s3_bucket_policy" "policy" {
id = "log_bucket"
~ policy = jsonencode(
~ {
~ Statement = [
+ {
+ Action = [
+ "s3:PutObject",
+ "s3:PutObjectAcl",
]
+ Effect = "Allow"
+ Principal = {
+ AWS = [
+ "arn:aws:iam::<account1-id>:role/my_log_role",
+ "arn:aws:iam::<account2-id>:role/my_log_role",
+ "arn:aws:iam::<account3-id>:role/my_log_role",
+ "arn:aws:iam::<account4-id>:role/my_log_role",
]
}
+ Resource = [
+ "arn:aws:s3:::log_bucket/*",
+ "arn:aws:s3:::log_bucket",
]
+ Sid = "DelegateS3Access"
},
]
# (1 unchanged element hidden)
}
)
# (1 unchanged attribute hidden)
}
but when I apply I get the following error:
│ Error: Error putting S3 policy: MalformedPolicy: Invalid principal in policy
│ status code: 400
│ with module.log_bucket.aws_s3_bucket_policy.policy,
│ on .terraform/mypath/main.tf line 63, in resource "aws_s3_bucket_policy" "policy":
│ 63: resource "aws_s3_bucket_policy" "policy" {
│
It seems correct to me, why is it throwing an error?
As per the comments, this is because the roles you specified have to exist at the time of policy creation.
Relevant documentation
Related
I am trying to create a container registry and add the service account with the OWNER role by changing the google_storage_bucket_acl.
According to the docs, the name of that bucket can be accessed via google_container_registry.<name>.id.
resource "google_container_registry" "registry" {
project = var.project_id
location = "EU"
}
resource "google_storage_bucket_acl" "image_store_acl" {
depends_on = [google_container_registry.registry]
bucket = google_container_registry.registry.id
role_entity = [
"OWNER:${local.terraform_service_account}",
]
}
$terraform plan
..
Terraform will perform the following actions:
# google_storage_bucket_acl.image_store_acl will be created
+ resource "google_storage_bucket_acl" "image_store_acl" {
+ bucket = "eu.artifacts.dev-00-ebcd.appspot.com"
+ id = (known after apply)
+ role_entity = [
+ "OWNER:terraform-service-account#dev-00-ebcd.iam.gserviceaccount.com",
]
}
Plan: 1 to add, 0 to change, 0 to destroy.
However, if I run terraform apply, the following error is what I get:
google_storage_bucket_acl.image_store_acl: Creating...
╷
│ Error: Error updating ACL for bucket eu.artifacts.dev-00-ebcd.appspot.com: googleapi: Error 400: Invalid argument., invalid
│
│ with google_storage_bucket_acl.image_store_acl,
│ on docker.tf line 6, in resource "google_storage_bucket_acl" "image_store_acl":
│ 6: resource "google_storage_bucket_acl" "image_store_acl" {
│
╵
I'm trying to do an AWS-Terraform-GitHub pipeline for a serverless app. In terraform i define a lambda function and on push i want to update the lambda function code and create a new lambda function version (to be used with an alias at a later date).
This is my code
data "archive_file" "zip" {
type = "zip"
source_file = "${path.module}/lambda/hello.js"
output_path = "${path.module}/lambda/hello.zip"
}
resource "aws_lambda_function" "hello_terraform" {
filename = data.archive_file.zip.output_path
source_code_hash = filebase64sha256(data.archive_file.zip.output_path)
function_name = var.project_name
role = aws_iam_role.lambda_role.arn
handler = "hello.handler"
runtime = "nodejs12.x"
timeout = 10
publish = true
}
data "aws_iam_policy_document" "lambda_assume_role_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
resource "aws_iam_role" "lambda_role" {
name = "${var.project_name}-lambda-role"
assume_role_policy = data.aws_iam_policy_document.lambda_assume_role_policy.json
}
When i do the initial push , or a a change that does not involve the code in lambda function everything works. However when i do a code modification i get this error on github workflow (on terraform apply)
│ Error: Error publishing Lambda Function (lambda-terraform-github-actions) version: ResourceConflictException: The operation cannot be performed at this time. An update is in progress for resource: arn:aws:lambda:us-east-1:961736190498:function:lambda-terraform-github-actions
│ {
│ RespMetadata: {
│ StatusCode: 409,
│ RequestID: "d8c86252-a471-46be-9662-751fc935083c"
│ },
│ Message_: "The operation cannot be performed at this time. An update is in progress for resource: arn:aws:lambda:us-east-1:961736190498:function:lambda-terraform-github-actions",
│ Type: "User"
│ }
│
│ with aws_lambda_function.hello_terraform,
│ on lambda.tf line 9, in resource "aws_lambda_function" "hello_terraform":
│ 9: resource "aws_lambda_function" "hello_terraform" {
│
╵
Operation failed: failed running terraform apply (exit 1)
I try adding depends_on but i still have the same problem .
I also try the same thing on a local environment , doing terraform apply on the same code without the pipeline but the same thing happens.
If i remove the "publish" the terraform apply works, the function gets updates but of course there is no new function version.
I'm using aws sts assume-role-with-web-identity to run terraform from gitlab. I'm getting an error I can't find the missing IAM action for:
╷
│ Error: Error fetching Availability Zones: UnauthorizedOperation: You are not authorized to perform this operation.
│ status code: 403, request id: 43a2032d-1bdd-4957-add9-070d3c270343
│
│ with module.vpc.data.aws_availability_zones.available,
│ on modules/terraform-aws-vpc/private.tf line 1, in data "aws_availability_zones" "available":
│ 1: data "aws_availability_zones" "available" {
data source:
data "aws_availability_zones" "available" {
state = "available"
}
I've tried multiple variations of ec2 actions, even: "ec2:*" but the issue remains.
Solutions found online usually recommend admin privileges, but I'm hoping for a better solution
Iam policy:
statement {
actions = [
"ec2:CreateVpc",
"ec2:CreateSubnet",
"ec2:DescribeAvailabilityZones",
"ec2:CreateRouteTable",
"ec2:CreateRoute",
"ec2:CreateInternetGateway",
"ec2:AttachInternetGateway",
"ec2:AssociateRouteTable",
"ec2:ModifyVpcAttribute",
"ec2:DescribeAvailabilityZones"
]
effect = "Allow"
resources = [
"arn:aws:ec2:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*",
"arn:aws:ec2::${data.aws_caller_identity.current.account_id}:ipam-pool/*",
"arn:aws:ec2:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:ipv6pool-ec2/*",
"arn:aws:ec2:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:subnet/*",
"arn:aws:ec2:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:vpc/*"
]
}
replacing resources with: "*" so this is causing the issue
I've successfully applied and deployed this script a week ago. I made 0 changes since then, to the script or to other factors used within this. Running it this morning throws this -
Terraform v1.0.8
on linux_amd64
Configuring remote state backend...
Initializing Terraform configuration...
aws_iam_role.iam_for_lambda: Refreshing state... [id=iam_for_lambda]
aws_lambda_function.lambda: Refreshing state... [id=MissingPostedTransactions]
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_iam_role_policy_attachment.tf_vpc_execution_policy will be created
+ resource "aws_iam_role_policy_attachment" "tf_vpc_execution_policy" {
+ id = (known after apply)
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
+ role = "arn:aws:iam::<arn no>:role/iam_for_lambda"
}
Then I type "yes" to apply the supposed "change", and I get this -
aws_iam_role_policy_attachment.tf_vpc_execution_policy: Creating...
╷
│ Error: Error attaching policy arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole to IAM Role arn:aws:iam::<arn no>:role/iam_for_lambda: ValidationError: The specified value for roleName is invalid. It must contain only alphanumeric characters and/or the following: +=,.#_-
│ status code: 400, request id: 8d354476-df67-4c2d-b3b8-c7aa7efce060
│
│ with aws_iam_role_policy_attachment.tf_vpc_execution_policy,
│ on main.tf line 55, in resource "aws_iam_role_policy_attachment" "tf_vpc_execution_policy":
│ 55: resource "aws_iam_role_policy_attachment" "tf_vpc_execution_policy" {
What am I missing here?
Everything is ok in your resources except you should specify role_name and not role_arn. Please refer to documentation from Terraform for more info:
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment
+ id = (known after apply)
+ policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
+ role = "<ROLE_NAME>"
}
I am trying to create bucket policy to grants a CloudFront origin access identity (OAI) permission to get (read) all objects in your Amazon S3 bucket.
But I am facing this error as "An error occurred:
Error: error creating IAM policy example_policy: MalformedPolicyDocument: Policy document should not specify a principal.
│ status code: 400, request id: 95044f55-e4bf-403e-8233-95964ffe09d1
│
│ with module.iam.aws_iam_policy.s3Frontend,
│ on ..\modules\iam\resources.tf line 65, in resource "aws_iam_policy" "s3Frontend":
│ 65: resource "aws_iam_policy" "s3Frontend" {
data "aws_iam_policy_document" "s3Frontend" {
version = "2012-10-17"
statement {
effect = "Allow"
actions = [
"s3:GetObject",
"s3:ListBucket"
]
principals {
type = "AWS"
identifiers = ["arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity $MYID"] #
}
resources = [ "arn:aws:s3:::WebSitefrontend/*" ]
}
}
resource "aws_iam_policy" "s3Frontend" {
name = "example_policy"
path = "/"
policy = data.aws_iam_policy_document.s3Frontend.json
}
output "s3FrontendId" {
description = "IDs of frontend deploy artifect on s3"
value = aws_iam_policy.s3-Frontend.id
}
Thanks for helping.
Error MalformedPolicyDocument: Policy document should not specify a principal refers to IAM identity-based policy created in resource "aws_iam_policy", which cannot contain principal.
You are trying to create S3 Bucket resource-based policy, which can be used in the aws_s3_bucket_policy Terraform resource. Example usage:
resource "aws_s3_bucket_policy" "s3Frontend" {
bucket = aws_s3_bucket.WebSitefrontend.id
policy = data.aws_iam_policy_document.s3Frontend.json
}