#amazon-web-services #ansible #yaml
#amazon-веб-сервисы #ансибль #ямл #ansible #yaml
Вопрос:
Я хотел бы объединить два объекта JSON из двух приведенных ниже команд, чтобы заменить существующие уведомления S3 на более новые, используя put-bucket-notification-configuration
. combine
Фильтр, который я использую, в настоящее время выдает мне сообщение об ошибке, в котором говорится, что он ожидает словари.
---
- name: Get existing S3 notifications
command: >
aws s3api get-bucket-notification-configuration
--bucket "{{ s3_notification.bucket }}"
--region "{{ aws_region }}"
register: existing_s3_notifications
environment:
AWS_ACCESS_KEY_ID: "{{ assumed_role.sts_creds.access_key }}"
AWS_SECRET_ACCESS_KEY: "{{ assumed_role.sts_creds.secret_key }}"
AWS_SECURITY_TOKEN: "{{ assumed_role.sts_creds.session_token }}"
- name: Combine existing S3 notifications with new notifications
command: >
aws s3api put-bucket-notification-configuration
--bucket "{{ s3_notification.bucket }}"
--notification-configuration '{{ s3_notification.configuration | to_json | combine(existing_s3_notifications) }}'
--region "{{ aws_region }}"
environment:
AWS_ACCESS_KEY_ID: "{{ assumed_role.sts_creds.access_key }}"
AWS_SECRET_ACCESS_KEY: "{{ assumed_role.sts_creds.secret_key }}"
AWS_SECURITY_TOKEN: "{{ assumed_role.sts_creds.session_token }}"
Объекты JSON выглядят следующим образом:
{
"LambdaFunctionConfigurations": [
{
"Id": "dev-datamining-wwang-new_product_list",
"LambdaFunctionArn": "arn:aws:lambda:us-west-2:434815900134:function:dev-datamining-wwang-lambda-update_product_corpus",
"Events": [
"s3:ObjectCreated:*"
],
"Filter": {
"Key": {
"FilterRules": [
{
"Name": "Prefix",
"Value": "wwang/product_list/"
}
]
}
}
}
]
}
С другим подобным:
{
"LambdaFunctionConfigurations": [
{
"Id": "dev-datamining-alee-new_product_list",
"LambdaFunctionArn": "arn:aws:lambda:us-west-2:434815900135:function:dev-datamining-alee-lambda-update_product_corpus",
"Events": [
"s3:ObjectCreated:*"
],
"Filter": {
"Key": {
"FilterRules": [
{
"Name": "Prefix",
"Value": "alee/product_list/"
}
]
}
}
}
],
"TopicConfigurations": [
<other stuff>
]
}
Я бы хотел, чтобы результат был:
{
"LambdaFunctionConfigurations": [
{
"Id": "dev-datamining-wwang-new_product_list",
"LambdaFunctionArn": "arn:aws:lambda:us-west-2:434815900134:function:dev-datamining-wwang-lambda-update_product_corpus",
"Events": [
"s3:ObjectCreated:*"
],
"Filter": {
"Key": {
"FilterRules": [
{
"Name": "Prefix",
"Value": "wwang/product_list/"
}
]
}
}
},
{
"Id": "dev-datamining-alee-new_product_list",
"LambdaFunctionArn": "arn:aws:lambda:us-west-2:434815900135:function:dev-datamining-alee-lambda-update_product_corpus",
"Events": [
"s3:ObjectCreated:*"
],
"Filter": {
"Key": {
"FilterRules": [
{
"Name": "Prefix",
"Value": "alee/product_list/"
}
]
}
}
}
],
"TopicConfigurations": [
<other stuff>
]
}
Как мне объединить эти два объекта, чтобы массивы внутри объектов были объединены вместе?
Ответ №1:
Вам необходимо изучить дополнительный параметр, который combine
предлагает вам фильтр:
Фильтр также принимает необязательный
recursive=True
параметр не только для переопределения ключей в первом хэше, но и для рекурсии во вложенные хэши и объединения их ключей{{ {'a':{'foo':1, 'bar':2}, 'b':2} | combine({'a':{'bar':3, 'baz':4}}, recursive=True) }}
Это приведет к:
{'a':{'foo':1, 'bar':3, 'baz':4}, 'b':2}
Смотрите: https://docs.ansible.com/ansible/2.9/user_guide/playbooks_filters.html#combining-hashes-dictionaries
Итак, в вашем случае вам действительно нужно сначала объединить два словаря, а затем преобразовать их в JSON:
- name: Combine existing S3 notifications with new notifications
command: >
aws s3api put-bucket-notification-configuration
--bucket "{{ s3_notification.bucket }}"
--notification-configuration '{{ s3_notification.configuration | combine(existing_s3_notifications, recursive=True) | to_json }}'
--region "{{ aws_region }}"
environment:
AWS_ACCESS_KEY_ID: "{{ assumed_role.sts_creds.access_key }}"
AWS_SECRET_ACCESS_KEY: "{{ assumed_role.sts_creds.secret_key }}"
AWS_SECURITY_TOKEN: "{{ assumed_role.sts_creds.session_token }}"
Также имейте в виду, что, если вы уже используете версию 2.10, у вас даже есть еще один дополнительный параметр:
list_merge: является строкой, ее возможными значениями являются
replace
(по умолчанию),keep
,append
,prepend
,append_rp
илиprepend_rp
. Это изменяет поведениеcombine
, когда хэши для объединения содержат массивы / списки.
Смотрите: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-hashes-dictionaries , содержащий хорошие примеры для каждого значения
Комментарии:
1. К сожалению, мы находимся на 2.8. Есть ли эквивалент list_merge в этой версии?