Как исправить недействительную политику JSON terraform
Я пытаюсь использовать файл, содержащий политику IAM балансировки нагрузки для моего AWS в terraform. Однако когда я запускаю скрипт terraform, я получаю сообщение об ошибке:
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)
Я импортирую содержимое файла политики с помощью функции jsonencode.
resource "aws_iam_policy" "test-AWSLoadBalancerControllerIAMPolicy" {
name = var.aws_loadbalancer_controller_policy
policy = jsonencode(var.policy_file)
}
значение переменной iam_policy_file, указанной выше, передается следующим образом:file("../resources/IAM/policy.json")
и содержимое этого файла показано ниже. Я проверил, анализируется ли этот json-файл онлайн как действительный json, и это так, однако Terraform выдает ошибку, как будто он плохо отформатирован.
политика.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": "*"
}
]
}
Я скачал этот файл из документации AWS здесь.
Я также попытался заставить его работать, прочитав файл из ответа http, как показано ниже, и я все еще получаю ту же проблему с неверным 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
}
1 ответ
Вы должны убедиться, что назначаете строку, содержащую представление объекта в формате JSON.
По описанию сложно понять, как именно вы это настроили, но вот некоторые потенциальные проблемы, на которые вам следует обратить внимание:
- Если содержит имя файла, то кодирование этого имени файла в формате JSON создаст строку JSON, содержащую имя файла. Например, если
../resources/IAM/policy.json
затем кодировка JSON, которая будет производить буквально"../resources/IAM/policy.json"
, что не является допустимой политикой IAM. - Если
var.policy_file
содержит прямой результатfile("../resources/IAM/policy.json")
затем вы просите Terraform создать кодировку JSON для строки, которая уже содержит контент JSON. Например, если ваш файл содержит{"Version": "2012-10-17"}
тогда это приведет к кодировке JSON"{\"Version\": \"2012-10-17\"}"
-- строка JSON, которая содержит больше JSON, что также не является допустимой политикой IAM.
В обеих вышеописанных ситуациях вам вообще не нужно будет его использовать, поскольку этот файл предположительно уже содержит контент JSON.
Для случая 1 вы можете сказатьpolicy = file(var.policy_file)
чтобы напрямую назначить содержимое файла.
Для случая 2 вы можете сказатьpolicy = var.policy_file
чтобы напрямую назначить строку JSON, находящуюся в этой переменной.
Вам нужно использовать его только в том случае, если вы собираетесь присвоить значение объекта Terraform, которое еще не было закодировано в формате JSON, например:
policy = jsonencode({
"Version" = "2012-10-17"
# ...
})
В таком случае,jsonencode
необходим для преобразования нестрокового значения объекта Terraform в строку JSON, которуюpolicy
аргумент ожидается.