Amazon web services 使用jq选择的更干净的方法

Amazon web services 使用jq选择的更干净的方法,amazon-web-services,ansible,terraform,jq,Amazon Web Services,Ansible,Terraform,Jq,我的问题的背景是加载的;但我只想关注当前文章中的jq部分(尽管如果您能提供全部帮助,我们将非常欢迎和感谢) 我有一个Terraform规范,我已经成功地应用于在AWS中创建一个自动缩放组(关于:Terraform provisioning,我将问一个单独的问题,如果有比我现在做的更好的方法的话)。我希望在每个生成的实例中运行一些资源调配,因此,我决定将其与ansible命令结合使用 您可能知道,Ansible在库存/主机文件上运行。因此,每次AWS向上或向下扩展时,我都必须更新主机文件,以便成功

我的问题的背景是加载的;但我只想关注当前文章中的
jq
部分(尽管如果您能提供全部帮助,我们将非常欢迎和感谢)

我有一个Terraform规范,我已经成功地应用于在AWS中创建一个自动缩放组(关于:Terraform provisioning,我将问一个单独的问题,如果有比我现在做的更好的方法的话)。我希望在每个生成的实例中运行一些资源调配,因此,我决定将其与
ansible
命令结合使用

您可能知道,Ansible在库存/主机文件上运行。因此,每次AWS向上或向下扩展时,我都必须更新主机文件,以便成功运行以下ansible即席命令
ansible-I./myansible.hostfile myawsinstances-a“resovisioning_命令”
(该命令本身有一组不同的问题,待定)

在创建ansible主机文件的过程中,我使用以下命令获得了所需的内容:

命令示例1

aws ec2 describe-instances | jq .Reservations[].Instances[].PublicIpAddress | sed 's/"//g' | awk '{print "inst"$1 " ansible_ssh_host="$1 " ansible_ssh_user=ubuntu"}' > myansible.hostfile
myansible.hostfile
中输出示例1

inst[ip_no1] ansible_ssh_host=[ip_no1] ansible_ssh_user=ubuntu
inst[ip_no2] ansible_ssh_host=[ip_no2] ansible_ssh_user=ubuntu
inst[ip_no1] ansible_ssh_host=[ip_no1] ansible_ssh_user=ubuntu
inst[ip_no2] ansible_ssh_host=[ip_no2] ansible_ssh_user=ubuntu
inst[ip_no1] ansible_ssh_host=[ip_no1] ansible_ssh_user=ubuntu
inst[ip_no2] ansible_ssh_host=[ip_no2] ansible_ssh_user=ubuntu
在我看来,它似乎相当长,有点复杂

如果我只是单独使用
jq
及其字符串操作工具,例如:

命令示例2

aws ec2 describe-instances | jq '"inst" + .Reservations[].Instances[].PublicIpAddress + " ansible_ssh_hosts=" + .Reservations[].Instances[].PublicIpAddress + " ansible_ssh_user=ubuntu"' > myansible.hostfile
我会收到重复的输出,如下所示:

myansible.hostfile
中输出示例2

inst[ip_no1] ansible_ssh_host=[ip_no1] ansible_ssh_user=ubuntu
inst[ip_no2] ansible_ssh_host=[ip_no2] ansible_ssh_user=ubuntu
inst[ip_no1] ansible_ssh_host=[ip_no1] ansible_ssh_user=ubuntu
inst[ip_no2] ansible_ssh_host=[ip_no2] ansible_ssh_user=ubuntu
inst[ip_no1] ansible_ssh_host=[ip_no1] ansible_ssh_user=ubuntu
inst[ip_no2] ansible_ssh_host=[ip_no2] ansible_ssh_user=ubuntu
大概是因为我在同一个命令中调用了两次对象选择器。 问题是:

a是否有一个更干净的命令表达式,我可以使用它来代替(命令示例1)来实现相同的(输出示例1)?

b在(命令示例2)中严格使用
jq
命令的正确方法是什么,以便生成所需的(输出示例1),而不产生(输出示例2)中的重复


首先,jq的
-r
选项将从JSON字符串输出中删除最外层的引号

其次,以下jq过滤器与前面提到的
-r
选项结合使用,应该足以实现您的目标,尽管由于您没有提供


我不知道为什么要设置一个包含IP地址的Ansible清单名称,因为这对我来说似乎毫无意义,因为它没有给它一个人类可读的名称,也没有添加任何比只使用IP地址有用的内容

如果您对放弃该要求感到满意,那么实际上您可以使用and ditch
jq
和您的格式:

cat <<EOF > hosts-file.ini
[all:vars]
ansible_ssh_user=ubuntu

[all]
EOF
aws ec2 describe-instances --query 'Reservations[*].Instances[*].PublicIpAddress' --output text >> hosts-file.ini
cat>hosts-file.ini

这将在所有级别设置一些内联变量,将SSH用户设置为
ubuntu
,然后将EC2实例的所有公共IP地址转储到
all
块下。

您好,我接受了@peak的回答,因为它特别解决了我的问题。但是你的答案也很好!对于你的问题,我想保留使用顺序inst1..n的ansible主机文件。我还没有完全决定sys的最终配置,所以我想。。。好的,我现在就使用IPs,稍后再考虑下一步。一般来说,我想在主机文件中删除多个组,其中一些组具有不同组的不同ssh用户。建议是什么。最佳实践?最佳实践是使用Ansible配置映像,然后部署映像,而不是尝试针对移动目标运行Ansible。我使用Packer和Ansible创建AMI(目前都在AWS上),然后使用Terraform在自动缩放组中部署这些图像。如果我想更新一些东西,我会创建一个新的映像,Terraform会自动选择并部署新的AMI。很久以前,我曾在EC2实例上使用Ansible,但它的伸缩性不好,而且使用ASG时很糟糕。非常好的提示!你刚刚把我从陷阱中救了出来。你猜到了我要做什么,例如
tf(通用ami)->asg&&ansible->asg实例
。如果我正确理解了您的指南,我应该这样做:
tf(gen.ami)->master.inst&&ansible->mr.inst&&packer(mr.inst)->mr.ami&&tf(mr.ami)->asg实例
,以防止您遇到的伸缩问题?不,只需packer+ansible生成ami,然后Terraform将ami部署为EC2实例,或者更好,一个ASG明白了。
packer(mr.inst)
之前的第一组步骤专门针对我需要的内容,即在将基本实例包装为ami之前“填充”它。然后我又重读了《打包机文档》,果然你说得对,我把它翻了一遍。我可以用一些通用的图像运行packer,按照我需要的方式提供它,然后就可以开始了。再次感谢!另外,我还重新阅读了
ansible
文档,因为我甚至不需要构建我的库存文件。您好,再次感谢您的回答。这就是我要找的。特别是关于:MCVE,我不能明确地这样做,因为它基于AWS实例的存在。因此,我尽可能以一种通用的方式询问它,让流式输入得到其他内容的响应。但“|”和“.”基本上是我寻求的答案。多谢。