В вашем примере $ {project} был задуман как заполнитель, представляющий конкретное имя стека CloudFormation, которое вам нужно будет предоставить либо путем жесткого кодирования статического имени стека, либо путем жесткого кодирования имени стека с подстановочным знаком.
"Resource": "arn:aws:cloudformation:*:*:stack/foo"
"Resource": "arn:aws:cloudformation:*:*:stack/foo*"
Первый пример - это просто статическое имя стека с именем foo , и оно будет предоставлять только ваши права доступа Lambda для стека CloudFormation с таким точным именем .
Второй пример представляет любое имя стека, которое начинается с foo и может дополнительно заканчиваться чем-то другим, например, foo-05 , foobar , foo-tastic или просто foo . Подстановочные знаки дают вашей лямбде больше гибкости благодаря тому, для чего стеки Cloudformation имеют разрешения.
Политики IAM поддерживают предопределенные переменные, такие как $ {aws: имя пользователя} , $ {aws: CurrentTime} и $ {aws: SourceIp} , но они не являются пользовательскими переменными, такими как $ (project} . Кто бы ни писал, этот пример политики должен был представлять имя стека как или что-то подобное, чтобы избежать путаницы, подобной этой.
Немного дополнительной информации:
Если вы хотите погрузиться глубже, на самом деле существуют способы параметризации политик IAM с помощью пользовательских переменных, но для этого необходимо развернуть политики IAM с помощью AWS CloudFormation или сторонних инструментов, таких как Ansible. Эти методы намного сложнее и необходимы, если вы хотите автоматизировать развертывание.
Ссылка: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#policy-vars-infotouse