{"id":1458,"date":"2024-03-04T11:51:02","date_gmt":"2024-03-04T11:51:02","guid":{"rendered":"https:\/\/radzishevsky.info\/blog\/?p=1458"},"modified":"2024-03-04T11:51:02","modified_gmt":"2024-03-04T11:51:02","slug":"avoid-charges-for-aws-elastic-ips-how-to-automatically-update-the-ip-address-of-a-dns-record-of-a-domain-defined-in-amazon-route53-from-an-ec2-instance","status":"publish","type":"post","link":"https:\/\/radzishevsky.com\/blog\/avoid-charges-for-aws-elastic-ips-how-to-automatically-update-the-ip-address-of-a-dns-record-of-a-domain-defined-in-amazon-route53-from-an-ec2-instance\/","title":{"rendered":"Avoid charges for AWS Elastic IP\u2019s &#8212; How to automatically update the IP address of a DNS record of a domain defined in Amazon Route53 from an EC2 instance"},"content":{"rendered":"\n<p>Your EC2 instance is assigned a fixed public IP from a list of Elastic IPs. But Amazon charges a considerable amount of money for the Elastic IP. Is there a way to automatically update the IP address of a DNS record defined in Amazon Route53 from the EC2 instance? Yes, there is, and it\u2019s not hard. You can write a \u201cbootstrap\u201d script that is executed when the instance is started. The script will update the public DNS record according to the public IP of the instance.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">1. Allow EC2 changing Route53 records<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Detailed instructions for creating an IAM role<\/h2>\n\n\n\n<p>Log into your AWS management console.<\/p>\n\n\n\n<p>Proceed to <strong>AIM<\/strong> (\u201cIdentity and Access Management\u201d). Click on <strong>Roles<\/strong>. Click on <strong>Create role<\/strong>.<\/p>\n\n\n\n<p>Select <strong>AWS service<\/strong> as the trusted entity type.<\/p>\n\n\n\n<p>Select <strong>EC2<\/strong> for the <strong>Use Case<\/strong>, then select <strong>EC2<\/strong> (\u201cAllows EC2 instances to call AWS services on your behalf\u201d)<\/p>\n\n\n\n<p>In the <strong>Permission policies<\/strong>, select <strong>AmazonRoute53FullAccess<\/strong>.<\/p>\n\n\n\n<p>Click on <strong>Next: Tags<\/strong> (optional step, you can add tags to organize and manage your role).<\/p>\n\n\n\n<p>Click on <strong>Next: Review<\/strong>.<\/p>\n\n\n\n<p>Name your role. Choose a name that makes sense for its purpose, like <strong>EC2Route53UpdateRole<\/strong>.<\/p>\n\n\n\n<p>(Optional) Add a description that explains the role&#8217;s purpose, like &#8220;Allows EC2 instances to update Route 53 DNS records.&#8221;<\/p>\n\n\n\n<p>Review your choices and click on <strong>Create role<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Finalize and use the Role<\/h2>\n\n\n\n<p>After creating the role, you need to attach it to your EC2 instance:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Go back to the <strong>EC2 dashboard<\/strong>.<\/li>\n\n\n\n<li>Select your instance.<\/li>\n\n\n\n<li>Choose <strong>Actions<\/strong>, navigate to <strong>Security<\/strong>, and select <strong>Modify IAM role<\/strong>.<\/li>\n\n\n\n<li>Choose the IAM role you created (EC2Route53UpdateRole) from the drop-down menu and save your changes.<\/li>\n<\/ul>\n\n\n\n<p>By assigning this role to your EC2 instance, you have given it permission to make changes to the DNS records of Route53. This is important so that the bootstrap script works as intended and your instance automatically updates the associated DNS entry on restart.\u00a0<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">2. Create a bootstrap script<\/h1>\n\n\n\n<p>Place the following script in your EC2 instance:<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code>#!\/bin\/bash\n\n# =====================================================================================\n# This script performs update of Route53 DNS record with current IP of an EC2 instance.\n# Alex Radzishevsky, http:\/\/radzishevsky.info\n# 2024-03-03\n# =====================================================================================\n# \n# - Read and understand this script\n# - Edit it according to your needs\n# - Make it a bootstrap script: * in Amazon Linux, place it inside \n#                                 \/var\/lib\/cloud\/scripts\/per-boot \n#                               * in Ubuntu, create a systemd service file\n\n\n# Get current public IP of the instance\nIP=$(curl http:\/\/169.254.169.254\/latest\/meta-data\/public-ipv4)\n\n# A function to update a single \"A\" record within DNS, \n# A domain name and the an ID of the hosting EC2 instance are conveyed via function \n# arguments (see below).\n# 1st argument: ID of the EC2 instance hosting the domain. Use this command in the \n#               EC2 instanc to list all zones using (requires AWS CLI): \n#                     aws route53 list-hosted-zones\n#               Find the right record in the list related to the domain you need.\n# 2nd argument: Your domain for which you'd like to change the IP\nupdate_single_record() {\n\n    HOSTED_ZONE_ID=$1                           \n    RECORD_SET_NAME=\"$2.\" # domain name must end with a dot\n    TTL=60\n\t\n    # Form JSON structure to update DNS record\n    JSON_STR=\"{\\\"Changes\\\":&#91;{\\\"Action\\\":\\\"UPSERT\\\",\\\"ResourceRecordSet\\\":{\\\"Name\\\":\\\"$RECORD_SET_NAME\\\",\\\"Type\\\":\\\"A\\\",\\\"TTL\\\":$TTL,\\\"ResourceRecords\\\":&#91;{\\\"Value\\\":\\\"$IP\\\"}]}}]}\"\n\t\n    # Update the Route53 record\n    aws route53 change-resource-record-sets --hosted-zone-id $HOSTED_ZONE_ID --change-batch \"$JSON_STR\"\n\t\n}\n\n\n# updating multiple domain records one after another\nupdate_single_record \"Z29472984792374983FF\" \"mydomain.com\" \nupdate_single_record \"Z29472984792374983FF\" \"another.mydomain.com\" \n\n<\/code><\/pre>\n\n\n\n<p>Save it as <strong>route53-update.sh<\/strong>.<\/p>\n\n\n\n<p>Now you have to make sure that the script is executed every time the instance is (re)started.<\/p>\n\n\n\n<p>Make the script executable with <strong>chmod<\/strong>.<\/p>\n\n\n\n<p>For Amazon Linux, just place the script in: \/var\/lib\/cloud\/scripts\/per-boot<\/p>\n\n\n\n<p>For Ubuntu Linux, create a service file and use <strong>systemd<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Your EC2 instance is assigned a fixed public IP from a list of Elastic IPs. But Amazon charges a considerable amount of money for the Elastic IP. Is there a way to automatically update the IP address of a DNS record defined in Amazon Route53 from the EC2 instance? Yes, there is, and it\u2019s not&#8230; <a class=\"more-link\" href=\"https:\/\/radzishevsky.com\/blog\/avoid-charges-for-aws-elastic-ips-how-to-automatically-update-the-ip-address-of-a-dns-record-of-a-domain-defined-in-amazon-route53-from-an-ec2-instance\/\">Continue reading <span class=\"meta-nav\">&#8594;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[145],"tags":[],"class_list":["post-1458","post","type-post","status-publish","format-standard","hentry","category-tech_hacks"],"_links":{"self":[{"href":"https:\/\/radzishevsky.com\/blog\/wp-json\/wp\/v2\/posts\/1458","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/radzishevsky.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/radzishevsky.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/radzishevsky.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/radzishevsky.com\/blog\/wp-json\/wp\/v2\/comments?post=1458"}],"version-history":[{"count":1,"href":"https:\/\/radzishevsky.com\/blog\/wp-json\/wp\/v2\/posts\/1458\/revisions"}],"predecessor-version":[{"id":1459,"href":"https:\/\/radzishevsky.com\/blog\/wp-json\/wp\/v2\/posts\/1458\/revisions\/1459"}],"wp:attachment":[{"href":"https:\/\/radzishevsky.com\/blog\/wp-json\/wp\/v2\/media?parent=1458"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/radzishevsky.com\/blog\/wp-json\/wp\/v2\/categories?post=1458"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/radzishevsky.com\/blog\/wp-json\/wp\/v2\/tags?post=1458"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}