0

I am trying to use a file which contains load balancer iam policy for my AWS in terraform. However when i run the terraform script, i get an error stating:

 Error: "policy" contains an invalid JSON policy
│ 
│   with module.iam.aws_iam_policy.test-AWSLoadBalancerControllerIAMPolicy,
│   on ../resources/IAM/main.tf line 77, in resource "aws_iam_policy" "test-AWSLoadBalancerControllerIAMPolicy":
│   77:  policy = jsonencode(var.policy_file)

I am importing the content of the policy file with jsonencode function.

resource "aws_iam_policy" "test-AWSLoadBalancerControllerIAMPolicy" {
 name = var.aws_loadbalancer_controller_policy
 policy = jsonencode(var.policy_file)
}

the value of the policy_file variable above is passed in like file("../resources/IAM/policy.json") and the content of that file is shown below, i have checked to see if this json file parses online as a valid json and it does, however Terraform throws the error as if there it is badly formatted.

policy.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceLinkedRole"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeAccountAttributes",
                "ec2:DescribeAddresses",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeInternetGateways",
                "ec2:DescribeVpcs",
                "ec2:DescribeVpcPeeringConnections",
                "ec2:DescribeSubnets",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeInstances",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DescribeTags",
                "ec2:GetCoipPoolUsage",
                "ec2:DescribeCoipPools",
                "elasticloadbalancing:DescribeLoadBalancers",
                "elasticloadbalancing:DescribeLoadBalancerAttributes",
                "elasticloadbalancing:DescribeListeners",
                "elasticloadbalancing:DescribeListenerCertificates",
                "elasticloadbalancing:DescribeSSLPolicies",
                "elasticloadbalancing:DescribeRules",
                "elasticloadbalancing:DescribeTargetGroups",
                "elasticloadbalancing:DescribeTargetGroupAttributes",
                "elasticloadbalancing:DescribeTargetHealth",
                "elasticloadbalancing:DescribeTags"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cognito-idp:DescribeUserPoolClient",
                "acm:ListCertificates",
                "acm:DescribeCertificate",
                "iam:ListServerCertificates",
                "iam:GetServerCertificate",
                "waf-regional:GetWebACL",
                "waf-regional:GetWebACLForResource",
                "waf-regional:AssociateWebACL",
                "waf-regional:DisassociateWebACL",
                "wafv2:GetWebACL",
                "wafv2:GetWebACLForResource",
                "wafv2:AssociateWebACL",
                "wafv2:DisassociateWebACL",
                "shield:GetSubscriptionState",
                "shield:DescribeProtection",
                "shield:CreateProtection",
                "shield:DeleteProtection"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:RevokeSecurityGroupIngress"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateSecurityGroup"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateTags"
            ],
            "Resource": "arn:aws:ec2:*:*:security-group/*",
            "Condition": {
                "StringEquals": {
                    "ec2:CreateAction": "CreateSecurityGroup"
                },
                "Null": {
                    "aws:RequestTag/elbv2.k8s.aws/cluster": "false"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateTags",
                "ec2:DeleteTags"
            ],
            "Resource": "arn:aws:ec2:*:*:security-group/*",
            "Condition": {
                "Null": {
                    "aws:RequestTag/elbv2.k8s.aws/cluster": "true",
                    "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:RevokeSecurityGroupIngress",
                "ec2:DeleteSecurityGroup"
            ],
            "Resource": "*",
            "Condition": {
                "Null": {
                    "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:CreateLoadBalancer",
                "elasticloadbalancing:CreateTargetGroup"
            ],
            "Resource": "*",
            "Condition": {
                "Null": {
                    "aws:RequestTag/elbv2.k8s.aws/cluster": "false"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:CreateListener",
                "elasticloadbalancing:DeleteListener",
                "elasticloadbalancing:CreateRule",
                "elasticloadbalancing:DeleteRule"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:AddTags",
                "elasticloadbalancing:RemoveTags"
            ],
            "Resource": [
                "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*",
                "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*",
                "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*"
            ],
            "Condition": {
                "Null": {
                    "aws:RequestTag/elbv2.k8s.aws/cluster": "true",
                    "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:AddTags",
                "elasticloadbalancing:RemoveTags"
            ],
            "Resource": [
                "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*",
                "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*",
                "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*",
                "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:ModifyLoadBalancerAttributes",
                "elasticloadbalancing:SetIpAddressType",
                "elasticloadbalancing:SetSecurityGroups",
                "elasticloadbalancing:SetSubnets",
                "elasticloadbalancing:DeleteLoadBalancer",
                "elasticloadbalancing:ModifyTargetGroup",
                "elasticloadbalancing:ModifyTargetGroupAttributes",
                "elasticloadbalancing:DeleteTargetGroup"
            ],
            "Resource": "*",
            "Condition": {
                "Null": {
                    "aws:ResourceTag/elbv2.k8s.aws/cluster": "false"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:RegisterTargets",
                "elasticloadbalancing:DeregisterTargets"
            ],
            "Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:SetWebAcl",
                "elasticloadbalancing:ModifyListener",
                "elasticloadbalancing:AddListenerCertificates",
                "elasticloadbalancing:RemoveListenerCertificates",
                "elasticloadbalancing:ModifyRule"
            ],
            "Resource": "*"
        }
    ]
}

I downloaded this file from the AWS documentation here

UPDATE

I have also tried to make it work by reading in the file from an http response as shown below and i still get the same issue of Invalid JSON

data "http" "policy_json" {
  url = "https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.4/docs/install/iam_policy.json"
}

resource "aws_iam_policy" "test-AWSLoadBalancerControllerIAMPolicy" {
  name = var.aws_loadbalancer_controller_policy
  policy = data.http.policy_json.request_body
}
floormind
  • 1,868
  • 5
  • 31
  • 85
  • [jsonencode encodes a given value to a string using JSON syntax](https://developer.hashicorp.com/terraform/language/functions/jsonencode) . you already have json so you shouldn't json encode it again. – erik258 Oct 25 '22 at 22:45
  • @erik258 if i was to remove the jsonencode function and just have it as var.policy_file, i still get the same error of Error: "policy" contains an invalid JSON policy, that doesnt fix it. can you spot anything else ? – floormind Oct 25 '22 at 22:56

1 Answers1

1

You have to read in the file and you don't need jsonencode:

resource "aws_iam_policy" "test-AWSLoadBalancerControllerIAMPolicy" {
 name = var.aws_loadbalancer_controller_policy
 policy = file(var.policy_file)
}
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • That does not work still. – floormind Oct 26 '22 at 08:21
  • 1
    @floormind Not possible. It means that your code in question is different then your actual code. – Marcin Oct 26 '22 at 09:03
  • If you look at what i have as an update, you'll notice i also have tried using data to fetch the same file from an endpoint and passing the response into the policy. That also says invalid JSON. – floormind Oct 26 '22 at 09:58
  • 1
    @floormind You wrote that you have `policy.json`. You have to read that file from the harddrive. I don't know what any http endpoint has to do with reading the `policy.json` file. – Marcin Oct 26 '22 at 10:16
  • i am saying i have taken the two approaches, reading from hard drive and reading from the web. both return the same error – floormind Oct 26 '22 at 11:11
  • 1
    @floormind I run your code and I tested my answer. It works correctly. My answer, based on what you posted in the question, is correct, and it can't produce the same error. – Marcin Oct 26 '22 at 11:14
  • this section of my question shows how i am passing the file into the var.policy_file ... is this right >>>... the value of the policy_file variable above is passed in like file("../resources/IAM/policy.json") and the content of that file is shown below, i have checked to see if this json file parses online as a valid json and it does, however Terraform throws the error as if there it is badly formatted. – floormind Oct 26 '22 at 11:15
  • 1
    Hey yes, you're right, the issue was with the way the attachment of the role and policy was handled. Sorry, thank you :) – floormind Oct 26 '22 at 12:24