{"id":7173,"date":"2022-03-14T14:18:28","date_gmt":"2022-03-14T20:18:28","guid":{"rendered":"https:\/\/gregsowell.com\/?p=7173"},"modified":"2022-03-14T14:26:03","modified_gmt":"2022-03-14T20:26:03","slug":"aws-ec2-inventory-in-ansible-automation-platform-aap","status":"publish","type":"post","link":"https:\/\/gregsowell.com\/?p=7173","title":{"rendered":"AWS EC2 Inventory In Ansible Automation Platform (AAP)"},"content":{"rendered":"<p><a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Untitled-1.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Untitled-1-300x169.jpg\" alt=\"\" width=\"300\" height=\"169\" class=\"aligncenter size-medium wp-image-7190\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Untitled-1-300x169.jpg 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Untitled-1-768x432.jpg 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Untitled-1-1024x576.jpg 1024w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Untitled-1.jpg 1280w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\nThis is a quick demonstration on pulling AWS hosts into the Ansible Automation Platfrom(AAP) controller.  The beautiful part of the process is just before I execute a piece of automation, controller will reach out to AWS and refresh the inventory so that I always have the freshest\/tastiest hosts.  I also demonstrate granular host filtering and automatic group creating\/assigning of hosts to groups.  While I do show filtering and group assignment based on tags I also explain what other options are available.<\/p>\n<h2>Video Demonstration<\/h2>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/M1MhmMnoeu0\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<h2>AAP Configuration<\/h2>\n<p>First create a credential for your EC2 instance:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_1.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_1-300x140.jpg\" alt=\"\" width=\"300\" height=\"140\" class=\"aligncenter size-medium wp-image-7174\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_1-300x140.jpg 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_1-768x358.jpg 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_1.jpg 882w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_2.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_2-300x213.jpg\" alt=\"\" width=\"300\" height=\"213\" class=\"aligncenter size-medium wp-image-7175\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_2-300x213.jpg 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_2-768x546.jpg 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_2.jpg 832w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Next create a standard inventory:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_3.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_3-300x148.jpg\" alt=\"\" width=\"300\" height=\"148\" class=\"aligncenter size-medium wp-image-7176\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_3-300x148.jpg 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_3-768x380.jpg 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_3.jpg 778w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_4.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_4-300x292.jpg\" alt=\"\" width=\"300\" height=\"292\" class=\"aligncenter size-medium wp-image-7177\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_4-300x292.jpg 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_4.jpg 683w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>After that I need to add an inventory source:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_5.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_5-300x95.jpg\" alt=\"\" width=\"300\" height=\"95\" class=\"aligncenter size-medium wp-image-7178\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_5-300x95.jpg 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_5.jpg 746w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_6.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_6-186x300.jpg\" alt=\"\" width=\"186\" height=\"300\" class=\"aligncenter size-medium wp-image-7179\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_6-186x300.jpg 186w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_6.jpg 549w\" sizes=\"auto, (max-width: 186px) 100vw, 186px\" \/><\/a><br \/>\nNotice that I choose source of Amazon EC2, then selected the credential I created in the first step.  Technically at this point I&#8217;m done and can syncronize all hosts that the account has access to.<\/p>\n<p>Additional options on inventory source:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_7.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_7-229x300.jpg\" alt=\"\" width=\"229\" height=\"300\" class=\"aligncenter size-medium wp-image-7180\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_7-229x300.jpg 229w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_7.jpg 590w\" sizes=\"auto, (max-width: 229px) 100vw, 229px\" \/><\/a><br \/>\nThere are three options here, and I&#8217;d recommend checking all three of them.<br \/>\n<strong>Overwrite<\/strong> will make sure that the AAP inventory always matches the AWS inventory.  When this option is set; if AAP has 10 hosts, and AWS only has 9 hosts, AAP will delete the one host that doesn&#8217;t match in its own inventory.<br \/>\n<strong>Overwirte variables<\/strong> will make sure that all variables and subsequently groups in the local inventory are kept in parity with what lives in AWS.<br \/>\n<strong>Update on launch<\/strong> will fire off this synchronization before any piece of automation runs that utilizes this inventory.  That way the inventory will always be updated with the most recent revision of hosts.<\/p>\n<h2>Automatically Creating Groups Inventory Source<\/h2>\n<p>Groups can be automatically created on synchronization via the source variables section using keyed_groups:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_8.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_8-164x300.jpg\" alt=\"\" width=\"164\" height=\"300\" class=\"aligncenter size-medium wp-image-7181\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_8-164x300.jpg 164w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_8.jpg 390w\" sizes=\"auto, (max-width: 164px) 100vw, 164px\" \/><\/a><br \/>\n<a href=\"https:\/\/docs.ansible.com\/ansible\/latest\/collections\/amazon\/aws\/aws_ec2_inventory.html#parameter-keyed_groups\">Documentation can be found here<\/a>, but may be a little confusing.<br \/>\nWhen a host is imported, a whole slew of variables are brought along with it; here&#8217;s an example of one of my imported hosts:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">ami_launch_index: 0\r\narchitecture: x86_64\r\nblock_device_mappings:\r\n  - device_name: \/dev\/sda1\r\n    ebs:\r\n      attach_time: &#039;2022-03-11T14:40:37+00:00&#039;\r\n      delete_on_termination: true\r\n      status: attached\r\n      volume_id: vol-0cc2c8c8193b42222\r\ncapacity_reservation_specification:\r\n  capacity_reservation_preference: open\r\nclient_token: &#039;&#039;\r\ncpu_options:\r\n  core_count: 1\r\n  threads_per_core: 1\r\nebs_optimized: false\r\nena_support: true\r\nenclave_options:\r\n  enabled: false\r\nhibernation_options:\r\n  configured: false\r\nhypervisor: xen\r\nimage_id: ami-0b0af3577fe5e3222\r\ninstance_id: i-08ed2eb8bc27a6222\r\ninstance_type: t2.micro\r\nkey_name: aws-ec2-personal\r\nlaunch_time: &#039;2022-03-11T14:40:36+00:00&#039;\r\nmetadata_options:\r\n  http_endpoint: enabled\r\n  http_put_response_hop_limit: 1\r\n  http_tokens: optional\r\n  state: applied\r\nmonitoring:\r\n  state: disabled\r\nnetwork_interfaces:\r\n  - attachment:\r\n      attach_time: &#039;2022-03-11T14:40:36+00:00&#039;\r\n      attachment_id: eni-attach-0a0554d977fdbd222\r\n      delete_on_termination: true\r\n      device_index: 0\r\n      network_card_index: 0\r\n      status: attached\r\n    description: &#039;&#039;\r\n    groups:\r\n      - group_id: sg-09e32db0f4185b222\r\n        group_name: launch-wizard-1\r\n    interface_type: interface\r\n    ipv6_addresses: []\r\n    mac_address: &#039;12:86:2e:9c:a1:4f&#039;\r\n    network_interface_id: eni-099f39193d3e62222\r\n    owner_id: &#039;726302647222&#039;\r\n    private_dns_name: ip-172-31-86-229.ec2.internal\r\n    private_ip_address: 172.31.86.229\r\n    private_ip_addresses:\r\n      - primary: true\r\n        private_dns_name: ip-172-31-86-229.ec2.internal\r\n        private_ip_address: 172.31.86.229\r\n    source_dest_check: true\r\n    status: in-use\r\n    subnet_id: subnet-04cbae8821c09d222\r\n    vpc_id: vpc-0c18720055c098222\r\nowner_id: &#039;726302647222&#039;\r\nplacement:\r\n  availability_zone: us-east-1c\r\n  group_name: &#039;&#039;\r\n  region: us-east-1\r\n  tenancy: default\r\nprivate_dns_name: ip-172-31-86-229.ec2.internal\r\nprivate_ip_address: 172.31.86.229\r\nproduct_codes: []\r\npublic_dns_name: &#039;&#039;\r\nrequester_id: &#039;&#039;\r\nreservation_id: r-0adfed50d497bd222\r\nroot_device_name: \/dev\/sda1\r\nroot_device_type: ebs\r\nsecurity_groups:\r\n  - group_id: sg-09e32db0f4185b222\r\n    group_name: launch-wizard-1\r\nsource_dest_check: true\r\nstate:\r\n  code: 80\r\n  name: stopped\r\nstate_reason:\r\n  code: Client.UserInitiatedShutdown\r\n  message: &#039;Client.UserInitiatedShutdown: User initiated shutdown&#039;\r\nstate_transition_reason: &#039;User initiated (2022-03-11 15:43:37 GMT)&#039;\r\nsubnet_id: subnet-04cbae8821c09d222\r\ntags:\r\n  gen_tag: tag1\r\n  type: web\r\nvirtualization_type: hvm\r\nvpc_id: vpc-0c18720055c098222<\/code><\/pre>\n<p>As you can see, it&#8217;s a LOT of information.  Any of the variables you see here are fair game for creating groups!  All you really have to do is specify the variable you want to use in the key_groups section.  For the screenshot above I used tags.  So any tags that my EC2 instances have, automatically get imported as groups:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_9.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_9-225x300.jpg\" alt=\"\" width=\"225\" height=\"300\" class=\"aligncenter size-medium wp-image-7183\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_9-225x300.jpg 225w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_9.jpg 476w\" sizes=\"auto, (max-width: 225px) 100vw, 225px\" \/><\/a><br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_10.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_10-300x265.jpg\" alt=\"\" width=\"300\" height=\"265\" class=\"aligncenter size-medium wp-image-7184\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_10-300x265.jpg 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_10.jpg 382w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_11.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_11-298x300.jpg\" alt=\"\" width=\"298\" height=\"300\" class=\"aligncenter size-medium wp-image-7185\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_11-298x300.jpg 298w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_11-150x150.jpg 150w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_11.jpg 335w\" sizes=\"auto, (max-width: 298px) 100vw, 298px\" \/><\/a><br \/>\nAs you can see the top image is my ansible inventory and the groups that were auto created, and the bottom two are the tags shown on my individual instances in the AWS console.<\/p>\n<p>As you can image a LOT of goups will be auto created.  Say for example all I really wanted to auto create are the &#8220;type&#8221; tags&#8230;so things like: web, db, lb, whatever.  I would create a key_groups filter like so:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">keyed_groups:\r\n  # This adds only the &quot;type&quot; tag as separate groups\r\n  - prefix: tag_type\r\n    key: tags.type<\/code><\/pre>\n<p>This would add only the tags of &#8220;type&#8221;.  Notice how it&#8217;s in standard variable dot notation.  As in variable.variable.variable.  Looking at one of my inventory hosts variables section I can see where the tags.type comes from:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_12.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_12-300x270.jpg\" alt=\"\" width=\"300\" height=\"270\" class=\"aligncenter size-medium wp-image-7186\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_12-300x270.jpg 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_12.jpg 542w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h2>Filtering Hosts In Inventory Source<\/h2>\n<p>To filter hosts that are coming from my AWS account I&#8217;ll make updates to the same source variables section as before:<br \/>\n<a href=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_13.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_13-249x300.jpg\" alt=\"\" width=\"249\" height=\"300\" class=\"aligncenter size-medium wp-image-7187\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_13-249x300.jpg 249w, https:\/\/gregsowell.com\/wp-content\/uploads\/2022\/03\/Screenshot_13.jpg 578w\" sizes=\"auto, (max-width: 249px) 100vw, 249px\" \/><\/a><br \/>\nHere I add a filters section, then under it specify the criteria I want to filter based on under it.  <a href=\"https:\/\/docs.aws.amazon.com\/cli\/latest\/reference\/ec2\/describe-instances.html#options\">The full list of filter options can be found here<\/a>.<br \/>\nYou&#8217;ll notice in the screenshot above that I chose to filter on instance tags and in particular I&#8217;m searing the gen_tag for any hosts that have a tag of &#8220;tag1&#8221;.  Keep in mind that the filter option still allows keyed_groups to be used to automatically create groups and associate hosts to them.<\/p>\n<h2>Conclusion<\/h2>\n<p>As you can see, it&#8217;s actually pretty easy to not only automatically create groups while importing AWS assets, you can also pretty easily filter the import of hosts based on all kinds of criteria!  If you have any questions or comments, please fire them my way.<\/p>\n<p>Good luck and happy importing!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is a quick demonstration on pulling AWS hosts into the Ansible Automation Platfrom(AAP) controller. The beautiful part of the process is just before\u2026<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[49,57],"tags":[],"class_list":["post-7173","post","type-post","status-publish","format-standard","hentry","category-ansible","category-cloud"],"_links":{"self":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/7173","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7173"}],"version-history":[{"count":6,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/7173\/revisions"}],"predecessor-version":[{"id":7193,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/7173\/revisions\/7193"}],"wp:attachment":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}