So far each name has had one record set. Give several sets the same name and type, each with its own SetIdentifier, and a routing policy decides which one answers each query.
Weighted: a canary
The API runs at 192.0.2.10, and its new version at 192.0.2.20. Send the new one one answer in ten:
{ "Changes": [
{ "Action": "UPSERT", "ResourceRecordSet": { "Name": "api.monstermarket.example",
"Type": "A", "TTL": 60, "SetIdentifier": "blue", "Weight": 90,
"ResourceRecords": [ { "Value": "192.0.2.10" } ] } },
{ "Action": "UPSERT", "ResourceRecordSet": { "Name": "api.monstermarket.example",
"Type": "A", "TTL": 60, "SetIdentifier": "green", "Weight": 10,
"ResourceRecords": [ { "Value": "192.0.2.20" } ] } } ] }aws route53 change-resource-record-sets --hosted-zone-id $ZONE --change-batch file://weighted.jsonEach set's share is its weight over the total (0 to 255 each; 0 sends nothing while another set has weight). Ask the zone's name server five or six times; most answers are blue's:
dig @$NS1 +short api.monstermarket.exampleaws route53 list-resource-record-sets --hosted-zone-id $ZONE --query "ResourceRecordSets[?Name=='api.monstermarket.example.'].[SetIdentifier,Weight]" --output textA resolver caches the one answer it got for the TTL, so the split is between resolvers, not visitors. A short TTL (60) keeps it fine-grained.
Choosing a policy
| The requirement | Policy |
|---|---|
| one resource, or a few addresses the client picks from | simple |
| a share of traffic: canaries, gradual moves | weighted |
| each visitor to the fastest region | latency |
| a standby that takes over when the primary fails | failover |
| by the visitor's continent or country (laws, languages), with a default | geolocation |
| by distance, with a bias that grows or shrinks a region's share of the map | geoproximity |
| up to eight healthy addresses, the unhealthy left out | multivalue answer |
| by the visitor's IP range (an ISP, an office) | IP-based |
Every policy but simple can skip unhealthy sets, which takes a health check: next lesson.