结合Ansible清单使用Jinja if-else逻辑失效问题排查
问题描述
需要在CloudFormation模板中通过Jinja2的if-else逻辑,根据Ansible清单内lambda_account的值生成对应的IAM Role资源。清单中已将lambda_account设为true,但模板始终仅生成else分支的RoleToBeAssumed资源。尝试过去掉引号、检查变量是否定义等操作均无效,且无法在Ansible playbook中使用when语句,请求排查原因及解决办法。
模板代码
--- AWSTemplateFormatVersion: 2010-09-09 Description: '{{ git_repository.after | truncate(8, end='') }} @ infra-lambda.git : roles/{{ lambda_name }}' Resources: {% if lambda_account == 'true' %} RoleToAssume: Type: AWS::IAM::Role Properties: RoleName: "infra-lambda-{{ lambda_name }}-LambdaRole-{{ shortname }}-{{ dtap }}" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "lambda.amazonaws.com" Action: - "sts:AssumeRole" Path: "/" ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole Policies: - PolicyName: RoleToAssumeLambdaPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: arn:aws:logs:*:*:* - Effect: Allow Action: - "cloudwatch:Get*" - "cloudwatch:List*" - "cloudwatch:Put*" Resource: - "*" - Effect: Allow Action: - "sts:AssumeRole" Resource: - "*" {% else %} RoleToBeAssumed: Type: AWS::IAM::Role Properties: RoleName: RoleToBeAssumed AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Sid: DefaultStatement Effect: "Allow" Principal: AWS: - "arn:aws:iam::{AWS_ACCOUNT}:role/lambda_assume" Action: - "sts:AssumeRole" Path: "/" Policies: - PolicyName: "DeleteCertificates" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - acm:DeleteCertificate - acm:GetCertificate Action: - acm:ListCertificates Resource: '*' {% endif %}
Ansible清单配置
unused_certs: enabled: true lambda_account: true
排查原因及解决办法
核心原因
- 变量层级引用错误:清单中
lambda_account是嵌套在unused_certs字典下的子变量,模板中直接使用lambda_account无法正确获取到值,实际渲染时该变量为未定义状态,导致条件判断不成立。 - 类型不匹配:清单中
lambda_account是布尔类型的true,但模板中判断条件是和字符串'true'做相等比较,布尔值与字符串永远不相等,因此必然进入else分支。
解决步骤
修正模板中的变量引用与判断条件:
将模板中的判断语句修改为:{% if unused_certs.lambda_account %}直接使用布尔变量本身作为判断条件,既解决了层级引用问题,也避免了类型不匹配的问题。
验证变量传递情况(可选):
可以在模板中临时添加调试输出,确认变量是否正确传入:# 调试输出,渲染后可查看实际值 Debug: Value: "{{ unused_certs.lambda_account }} | {{ lambda_account }}"渲染模板后,通过查看Debug部分的输出,确认变量是否被正确解析。
内容的提问来源于stack exchange,提问作者Patryk Petryszen
相关产品推荐
相关产品推荐

