Terraform创建EC2实例时如何将AWS profile传递给Ansible获取凭证
问题描述
使用Terraform创建EC2实例时,配置了local-exec provisioner,在实例创建完成后先调用AWS CLI等待实例状态正常,再执行Ansible playbook,具体资源配置如下:
resource "aws_instance" "jenkins-master" { depends_on = [aws_main_route_table_association.set-master-default-rt-assoc, aws_kms_alias.master_ebs_cmk] provider = aws.region-master ami = data.aws_ssm_parameter.linuxAmi.value instance_type = var.instance-type key_name = aws_key_pair.master-key.key_name associate_public_ip_address = true vpc_security_group_ids = [aws_security_group.jenkins-sg.id] subnet_id = aws_subnet.master_subnet_1.id ipv6_address_count = 1 root_block_device { encrypted = false volume_size = 30 } provisioner "local-exec" { command = <<EOF aws --profile myprofile ec2 wait instance-status-ok --region us-east-1 --instance-ids ${self.id} \ && ansible-playbook --extra-vars 'passed_in_hosts=tag_Name_${self.tags.Name}' ansible_templates/install_jenkins.yaml EOF } }
故障表现:提前将AWS配置文件中myprofile对应的AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY导出为环境变量时,Terraform可正常跑完整套流程;不导出这两个环境变量时执行报错,Ansible的AWS EC2动态库存插件提示找不到足够的boto凭证,无法解析库存,报错日志如下:
.... aws_instance.jenkins-master (local-exec): Executing: ["/bin/sh" "-c" "aws --profile myprofile ec2 wait instance-status-ok --region us-east-1 --instance-ids i-04db214244937ed60 \\\n&& ansible-playbook --extra-vars 'passed_in_hosts=tag_Name_jenkins_master_tf' ansible_templates/install_jenkins.yaml\n"] .... aws_instance.jenkins-master (local-exec): [WARNING]: * Failed to parse /home/pcooke/workspace/learn- aws_instance.jenkins-master (local-exec): terraform/modules/ansible_templates/inventory_aws/tf_aws_ec2.yml with auto aws_instance.jenkins-master (local-exec): plugin: Insufficient boto credentials found. Please provide them in your aws_instance.jenkins-master (local-exec): inventory configuration file or set them as environment variables. aws_instance.jenkins-master (local-exec): [WARNING]: * Failed to parse /home/pcooke/workspace/learn- aws_instance.jenkins-master (local-exec): terraform/modules/ansible_templates/inventory_aws/tf_aws_ec2.yml with yaml aws_instance.jenkins-master (local-exec): plugin: Plugin configuration YAML file, not YAML inventory aws_instance.jenkins-master (local-exec): [WARNING]: * Failed to parse /home/pcooke/workspace/learn- aws_instance.jenkins-master (local-exec): terraform/modules/ansible_templates/inventory_aws/tf_aws_ec2.yml with ini aws_instance.jenkins-master (local-exec): plugin: Invalid host pattern '---' supplied, '---' is normally a sign this is a aws_instance.jenkins-master (local-exec): YAML file. aws_instance.jenkins-master (local-exec): [WARNING]: Unable to parse /home/pcooke/workspace/learn- aws_instance.jenkins-master (local-exec): terraform/modules/ansible_templates/inventory_aws/tf_aws_ec2.yml as an aws_instance.jenkins-master (local-exec): inventory source aws_instance.jenkins-master (local-exec): [WARNING]: No inventory was parsed, only implicit localhost is available aws_instance.jenkins-master (local-exec): [WARNING]: provided hosts list is empty, only localhost is available. Note that aws_instance.jenkins-master (local-exec): the implicit localhost does not match 'all' aws_instance.jenkins-master (local-exec): [WARNING]: Could not match supplied host pattern, ignoring: aws_instance.jenkins-master (local-exec): tag_Name_jenkins_master_tf
故障原因:AWS CLI调用时指定了--profile myprofile可以正常读取凭证,但local-exec的shell上下文没有将profile配置传递给后续的Ansible进程,Ansible依赖的Boto SDK默认不会继承AWS CLI的--profile参数,因此无法找到对应凭证。
解决方案
方案1:直接在local-exec命令传递环境变量(最便捷,无需修改其他配置)
Boto SDK默认支持识别AWS_PROFILE、AWS_REGION环境变量,只需要在执行ansible-playbook前注入这两个变量即可,修改后的provisioner配置如下:
provisioner "local-exec" { command = <<EOF aws --profile myprofile ec2 wait instance-status-ok --region us-east-1 --instance-ids ${self.id} \ && AWS_PROFILE=myprofile AWS_REGION=us-east-1 ansible-playbook --extra-vars 'passed_in_hosts=tag_Name_${self.tags.Name}' ansible_templates/install_jenkins.yaml EOF }
方案2:修改Ansible动态库存配置(永久生效,复用性更高)
直接在Ansible AWS动态库存配置文件tf_aws_ec2.yml中添加profile和区域配置,无需每次执行命令传参,配置示例:
plugin: aws_ec2 regions: - us-east-1 profile: myprofile # 保留其他原有配置不变
配置后Ansible加载动态库存时会自动读取对应profile的凭证。
内容的提问来源于stack exchange,提问作者peter cooke
相关产品推荐
相关产品推荐

