Reputation: 591
So I have this ansible task:
- name: google._domainkey.ludoistic.com. - TXT
route53:
overwrite: true
command: "create"
zone: "ludoistic.com"
record: "google._domainkey.ludoistic.com."
type: "TXT"
ttl: "300"
value: '"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAup2hbfv7PQuI+z8j634065jEtT",
"eW4km3D7Vnt+tVQt+76mBp18mAb5C+xl70KS6LUEtYmrBe3fo6QbElQ96BZ4KnNJTo62NBfEkO2i/AuIO91ksKaL01En5wrH",
"B6oo9JYhJ231eDZ01af6eBkrI9dy5wYSlU1wYwpIvk/DDA9HvmTMMGv87VOQYiEfEDfdWJq8ZRxUj+sKCDQAono7dmC/vHFG",
"GkQ7/pFa+EqO4e2MFn22SmnXhLW1aGShJ3PSGvplyxZ3JHQiUO6bBi4ZoUtUZc1MOLRZjKMch/cXbkB+f/XUVNH9r0uOaZHt",
"LXH+zwikjUVFStCdgtzyqOF2tVSwIDAQAB"'
aws_access_key: '{{istic_aws_key}}'
aws_secret_key: '{{istic_aws_secret}}'
tags:
- ludoistic
But when this task is executed, it's always a change. Is there a way to reformat this so ansible doesn't think it's changed when it hasn't?
Upvotes: 1
Views: 440
Reputation: 591
Okay, I solved this, with credit going to β.εηοιτ.βε below who got me towards the right answer
The text record was being created as an array, so was coming back with four separate non-ordered answers when it went into DNS. It does have to be four seperate pieces because DNS can only cope with 255 characters per record - https://aws.amazon.com/premiumsupport/knowledge-center/route53-resolve-dkim-text-record-error/
The solution to this turns out to be to use space-separated double-quoted DNS records within a large single-quoted ansible value, thus:
- name: google._domainkey.ludoistic.com. - TXT
route53:
overwrite: true
command: "create"
zone: "ludoistic.com"
record: "google._domainkey.ludoistic.com."
type: "TXT"
ttl: "300"
value: '"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAup2hbfv7PQuI+z8j634065jEtT" "eW4km3D7Vnt+tVQt+76mBp18mAb5C+xl70KS6LUEtYmrBe3fo6QbElQ96BZ4KnNJTo62NBfEkO2i/AuIO91ksKaL01En5wrH" "B6oo9JYhJ231eDZ01af6eBkrI9dy5wYSlU1wYwpIvk/DDA9HvmTMMGv87VOQYiEfEDfdWJq8ZRxUj+sKCDQAono7dmC/vHFG" "GkQ7/pFa+EqO4e2MFn22SmnXhLW1aGShJ3PSGvplyxZ3JHQiUO6bBi4ZoUtUZc1MOLRZjKMch/cXbkB+f/XUVNH9r0uOaZHt" "LXH+zwikjUVFStCdgtzyqOF2tVSwIDAQAB"'
aws_access_key: '{{istic_aws_key}}'
aws_secret_key: '{{istic_aws_secret}}'
tags:
- ludoistic
Upvotes: 1
Reputation: 39294
In your case, mind that your DKIM record is all wrong.
Look at the result of you DNS record, while setting it with your actual playbook:
dig google._domainkey.ludoistic.com TXT
; <<>> DiG 9.10.6 <<>> google._domainkey.ludoistic.com TXT ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31974 ;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 4, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;google._domainkey.ludoistic.com. IN TXT ;; ANSWER SECTION: google._domainkey.ludoistic.com. 300 IN TXT "B6oo9JYhJ231eDZ01af6eBkrI9dy5wYSlU1wYwpIvk/DDA9HvmTMMGv87VOQYiEfEDfdWJq8ZRxUj+sKCDQAono7dmC/vHFG" google._domainkey.ludoistic.com. 300 IN TXT "GkQ7/pFa+EqO4e2MFn22SmnXhLW1aGShJ3PSGvplyxZ3JHQiUO6bBi4ZoUtUZc1MOLRZjKMch/cXbkB+f/XUVNH9r0uOaZHt" google._domainkey.ludoistic.com. 300 IN TXT "LXH+zwikjUVFStCdgtzyqOF2tVSwIDAQAB" google._domainkey.ludoistic.com. 300 IN TXT "eW4km3D7Vnt+tVQt+76mBp18mAb5C+xl70KS6LUEtYmrBe3fo6QbElQ96BZ4KnNJTo62NBfEkO2i/AuIO91ksKaL01En5wrH" google._domainkey.ludoistic.com. 300 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAup2hbfv7PQuI+z8j634065jEtT" ;; AUTHORITY SECTION: ludoistic.com. 172800 IN NS ns-1058.awsdns-04.org. ludoistic.com. 172800 IN NS ns-1761.awsdns-28.co.uk. ludoistic.com. 172800 IN NS ns-333.awsdns-41.com. ludoistic.com. 172800 IN NS ns-957.awsdns-55.net. ;; Query time: 49 msec ;; SERVER: 192.168.1.1#53(192.168.1.1) ;; WHEN: Sat Jun 20 10:06:36 CEST 2020 ;; MSG SIZE rcvd: 672
See the multiples lines in the authoritative ANSWER SECTION
?
Now compare this to SO's DKIM:
dig google._domainkey.stackoverflow.com TXT
; <<>> DiG 9.10.6 <<>> google._domainkey.stackoverflow.com TXT ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33678 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;google._domainkey.stackoverflow.com. IN TXT ;; ANSWER SECTION: google._domainkey.stackoverflow.com. 300 IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbf2b+8IwDGfgu5u/9kY4d3Corv9C2UtQyLWqHer1vNmWprWnjHDNWwE7nL943WOdDSGGhwKrprrFbCJrHsZ8Yz+UR52zeySiwJi7eIoVl6SDa6DXSlh2bYKwgJUuCF5blhY8weRwpf0wAKK8i9TmZbx+5vBZ2tAGAa1MW6VkFDwIDAQAB" ;; AUTHORITY SECTION: stackoverflow.com. 99395 IN NS ns-1033.awsdns-01.org. stackoverflow.com. 99395 IN NS ns-358.awsdns-44.com. stackoverflow.com. 99395 IN NS ns-cloud-e1.googledomains.com. stackoverflow.com. 99395 IN NS ns-cloud-e2.googledomains.com. ;; Query time: 105 msec ;; SERVER: 192.168.1.1#53(192.168.1.1) ;; WHEN: Sat Jun 20 10:05:47 CEST 2020 ;; MSG SIZE rcvd: 443
See how this DKIM is a single line and not multiple ones compared to yours?
Now this happens because, as pointed in road53
module documentation, value will be considered as array, and so create multiple records either if you pass an actual YAML array or if you have a comma separated list of value, as you have currently.
The new value when creating a DNS record. YAML lists or multiple comma-spaced values are allowed for non-alias records.
When deleting a record all values for the record must be specified or Route53 will not delete it.
Source: https://docs.ansible.com/ansible/latest/modules/route53_module.html#parameter-value
The actual correct playbook task for your use case should be:
- name: google._domainkey.ludoistic.com. - TXT
route53:
overwrite: true
command: "create"
zone: "ludoistic.com"
record: "google._domainkey.ludoistic.com."
type: "TXT"
ttl: "300"
value: '"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAup2hbfv7PQuI+z8j634065jEtTeW4km3D7Vnt+tVQt+76mBp18mAb5C+xl70KS6LUEtYmrBe3fo6QbElQ96BZ4KnNJTo62NBfEkO2i/AuIO91ksKaL01En5wrHB6oo9JYhJ231eDZ01af6eBkrI9dy5wYSlU1wYwpIvk/DDA9HvmTMMGv87VOQYiEfEDfdWJq8ZRxUj+sKCDQAono7dmC/vHFGGkQ7/pFa+EqO4e2MFn22SmnXhLW1aGShJ3PSGvplyxZ3JHQiUO6bBi4ZoUtUZc1MOLRZjKMch/cXbkB+f/XUVNH9r0uOaZHtLXH+zwikjUVFStCdgtzyqOF2tVSwIDAQAB"'
aws_access_key: '{{istic_aws_key}}'
aws_secret_key: '{{istic_aws_secret}}'
tags:
- ludoistic
This will create you a unique DKIM TXT
record, and eventually also fix your changed
state issue because now, you will have a unique TXT
and the matching mechanism of the route53
module will work.
Generally speaking, from what I understand reading both the documentation and the source code of the module, this seems to be happening because you are setting your TXT
record in multiple separated tasks, when the module would consider and compare the existing TXT
to your desired change in a whole.
So what I understand you are doing right now is:
- name: foo.example.org. - TXT
route53:
overwrite: true
command: "create"
zone: "example.org"
record: "foo.example.org."
type: "TXT"
ttl: "300"
value: 'bar'
aws_access_key: '{{istic_aws_key}}'
aws_secret_key: '{{istic_aws_secret}}'
- name: foo.example.org. - TXT
route53:
overwrite: true
command: "create"
zone: "example.org"
record: "foo.example.org."
type: "TXT"
ttl: "300"
value: 'bar bar'
aws_access_key: '{{istic_aws_key}}'
aws_secret_key: '{{istic_aws_secret}}'
And this will always be a change because the whole TXT
record for foo.ludoistic.com.
won't never match only a part of it.
What you should do instead, that should make the matching mechanism of the module work is to pass your value as an array in a single task.
So the two tasks above would become:
- name: foo.example.org. - TXT
route53:
overwrite: true
command: "create"
zone: "example.org"
record: "foo.example.org."
type: "TXT"
ttl: "300"
value:
- 'bar'
- 'bar bar'
aws_access_key: '{{istic_aws_key}}'
aws_secret_key: '{{istic_aws_secret}}'
Upvotes: 1
Reputation: 418
I assume this is happening since you have overwrite
set to true
. This will probably execute every time and will therefore always give you a changed result.
A possible way to fix this is to execute only if the record does not exist or use changed_when
. route53_info can be used to look up a record.
- name: grab zone id
route53_zone:
zone: "ludoistic.com"
register: AWSINFO
- name: grab Route53 record information
route53_info:
type: TXT
query: record_sets
hosted_zone_id: "{{ AWSINFO.zone_id }}"
start_record_name: "google._domainkey.ludoistic.com."
register: RECORDS
- name: add Route 53 record if it does not exist
route53:
overwrite: false
# ...
when: RECORDS.value != other_value_goes_here
Upvotes: 1