Использовать файл шаблона в политике Terraform на AWS, которая использует переменные политики IAM

Я пытаюсь построить облачную инфраструктуру в AWS с помощью Terraform. Я хочу добавить политику для корзины S3, которая использует авторизацию на основе атрибутов (ABAC) черезtemplatefileфункция терраформирования. Моя проблема в том, что синтаксис переменных, используемый terraform и AWS, одинаков (${...}).

Вот шаблон политики:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowReadRole1",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::${bucketName}/*",
            "Effect": "Allow",
            "Principal": "*",
            "Condition": {
                "s3:ExistingObjectTag/myid": "${aws:PrincipalTag/myid}"
            }
        }
    ]
}

Соответствующая часть файла terrafrom:

resource "aws_s3_bucket_policy" "mybuckets-policy" {
  bucket = aws_s3_bucket.mybuckets[count.index].bucket
  policy = templatefile("${path.module}/bucket-policy.json", {
    bucketName = aws_s3_bucket.mybuckets[count.index].bucket
  })
  count = 2
}

Я хочу, чтобы ${bucketName} часть шаблона заменяется терраформом с сохранением выражения AWS ${aws:PrincipalTag/user-id}на месте. Но запуск terraform в конфигурации выше вызывает сообщение об ошибке

Не удалось вызвать функцию "templatefile": ./bucket-policy.json:14,49-50: лишние символы после интерполяционного выражения; Ожидается, что закрывающая фигурная скобка завершит выражение интерполяции, но обнаружены лишние символы.

Если я поставлю другой предмет ${foobar} в моем шаблоне без указания значения для него сообщение об ошибке

Недопустимое значение параметра "vars": карта vars не содержит ключа "foobar", ссылка на который находится в./bucket-policy.json:11,30-36.

Как я могу заставить terraform выполнять частичную оценку файла шаблона, оставляя все остальные элементы нетронутыми?

1 ответ

Решение

В приведенном выше примере синтаксис ${} заставит Terraform попытаться оценить поле как функцию интерполяции. Поскольку вы хотите использовать это значение буквально, а не в качестве функции интерполяции, вам нужно будет дважды экранировать его, используя два символа $.

$${aws:PrincipalTag/user-id}