How to pass list of vpcs inside the policy

Hi

Trying to create s3 bucket and restrict to vpc based access. I am using 12.12 version

when I create datasource with aws_vpc (with tag name), I can pass the data value, everything works fine but different accounts have different number of vpcs.

data “aws_vpc” “vpcname” {
filter {
name = “tag:Name”
values = [“vpcname”]
}

when I use aws_vpcs to
data “aws_vpcs” “allvpcs” {
}

Tried diferent ways to list all vpcs in policy
{tolist(data.aws_vpcs.allvpcs.ids)}" ["{tolist(data.aws_vpcs.allvpcs.ids)}”]
{data.aws_vpcs.allvpcs.ids}" ["{data.aws_vpcs.allvpcs.ids}”]

s3 policy :

“Condition”: {
“StringNotEquals”: {
“aws:sourceVpc”: ["${tolist(data.aws_vpcs.allvpcs.ids)}"]
}
}
}

Error :

60:
61: “aws:sourceVpc”: ["${tolist(data.aws_vpcs.allvpcs.ids)}"]
62:
63:
64:
65:
66:
67:
|----------------
| data.aws_vpcs.allvpcs.ids is set of string with 2 elements

Cannot include the given value in a string template: string required.

Here is example code that works fine:

   data "aws_vpcs" "allvpcs" {}
   data "aws_iam_policy_document" "p" {
      statement {
        effect = "Allow"

principals {
  type        = "AWS"
  identifiers = ["*"]
}

actions   = ["s3:*"]
resources = ["*"]

condition {
  test     = "StringEquals"
  variable = "aws:sourceVpc"
  values   = data.aws_vpcs.allvpcs.ids
}
  }
}

output "policy" {
  value = data.aws_iam_policy_document.p.json
}

Thanks for the response…below is my code under POLICY
I tried your suggestion… it throws policy error

aws_s3_bucket.mytestbucket: Refreshing state… [id=mynews3buckettorun3]

Error: “policy” contains an invalid JSON: invalid character ‘d’ looking for beginning of value

on main.tf line 34, in resource “aws_s3_bucket_policy” “b”:

34: resource “aws_s3_bucket_policy” “b” {

Error: “policy” contains an invalid JSON: invalid character ‘d’ looking for beginning of value

on main.tf line 34, in resource “aws_s3_bucket_policy” “b”:

34: resource “aws_s3_bucket_policy” “b” {

Below is my bucket policy resource…

resource “aws_s3_bucket_policy” “b” {
bucket = “${aws_s3_bucket.mytestbucket.id}”

policy = <<POLICY
{
“Version”: “2012-10-17”,
“Id”: “Policy1415115909152”,
“Statement”: [
{
“Sid”: “Access-to-specific-VPCE-only”,
“Principal”: “",
“Action”: “s3:PutObject”,
“Effect”: “Deny”,
“Resource”: ["arn:aws:s3:::{aws_s3_bucket.mytestbucket.id}", "arn:aws:s3:::{aws_s3_bucket.mytestbucket.id}/
”],
“Condition”: {
“StringNotEquals”: {
“aws:sourceVpc”: $data.aws_vpcs.allvpcs.ids
}
}
}
]
}
POLICY
}

Hashicorp has worst documentation i ever seen… its like white board drawing kind of display

I am trying data source for policy and for boolean value under condition, what should i use

i gave something like this…but I got different errors for false or “false”

condition {
test = “Bool”
variable = “aws:SecureTransport”
values = “false”
}

… in data “aws_iam_policy_document” “s3_bucket_policy”:
59: values = false

Inappropriate value for attribute “values”: set of string required.

in data “aws_iam_policy_document” “s3_bucket_policy”:
59: values = “false”

Inappropriate value for attribute “values”: set of string required.

values, being plural, expects a list. That is why both of your tests fail and why terraform says it expects a set of string. Every example, including the previous one in this post uses a set/list for values

Thanks that worked… but i cannot use data source(due to multiple tf files and resources, its conflicting), have to try different method as POLICY > option is not able to get all vpcs from data

but i cannot use data source(due to multiple tf files and resources, its conflicting)

I have no idea what that means. You can use as many tf files as you like. Terraform doesn’t care. If you have conflicting resources, do you have duplicate names or something? What you are trying to do is easily possible and building a policy like I showed you easily includes all VPCs like my example showed.

Also, you may believe that Hashicorp has terrible documentation, but all of your code examples are unreadable because you do not style them as preformatted text. And you use smart quotes. If you post more code, please style it correctly.

thanks for the response…

yes i pasted part of the code and cannot share everything. well its copy paste issue for the format.

Vaules field in your example, can have multiple list?

values = data.aws_vpcs.allvpcs.ids

I tried to add something like this
values = [data.aws_vpcs.allvpcs.ids, “vpc1”, “vpc2”]
or
values = ["${data.aws_vpcs.allvpcs.ids}", “vpc1”, “vpc2”]

both failed with syntax errors

Thanks…
tried that, got invalid function argument
concat(data.aws_vpcs.allvpcs.ids, [“vpc-1”, “vpc-2”, “vpc-3”])

got incorrect attribute value type
concat(["${data.aws_vpcs.allvpcs.ids}"], [“vpc-1”, “vpc-2”, “vpc-3”])

give the actual full error

Error: Invalid function argument

on mytestvpc.tf line 66, in data “aws_iam_policy_document” “mytestvpc-data-policy”:
66: values = concat(data.aws_vpcs.allvpcs.ids, [“vpc-1”, “vpc-2”, “vpc-3”])
|----------------
| data.aws_vpcs.allvpcs.ids is set of string with 10 elements

Invalid value for “seqs” parameter: all arguments must be lists or tuples; got
set of string.

this worked
values = concat(sort(data.aws_vpcs.allvpcs.ids), sort(var.othervpcs))

kept all vpcs under var.othervpcs… no errors for now… something to do with sort…
Thanks for the concat suggestion…