{"id":6585,"date":"2020-11-04T10:56:29","date_gmt":"2020-11-04T16:56:29","guid":{"rendered":"http:\/\/gregsowell.com\/?p=6585"},"modified":"2020-11-04T10:58:47","modified_gmt":"2020-11-04T16:58:47","slug":"deploying-and-using-cyberark-conjur-with-ansible-tower","status":"publish","type":"post","link":"https:\/\/gregsowell.com\/?p=6585","title":{"rendered":"Deploying And Using CyberArk Conjur With Ansible Tower"},"content":{"rendered":"<p>First I have to say this wasn&#8217;t as simple and straight forward as I could have hoped for&#8230;in fact it took me the better part of 1.5 days to get working, and even then I had to get help from <a href=\"https:\/\/www.linkedin.com\/in\/jodyhuntatx\/\">Jody Hunt from CyberArk<\/a>(HUGE thanks to him).  In fact, I partially followed <a href=\"https:\/\/github.com\/jodyhuntatx\/ansible-conjur-oss-demo\">his guide here<\/a> to get started.  I figure it took me enough work to get it stood up, so why not go ahead and write a playbook to do all of it for me&#8230;and now I&#8217;ve made it available to you!<\/p>\n<h2>Video Demonstration<\/h2>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/PVgKge5fKyM\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<h2>Environment Building<\/h2>\n<p>To get the infrastructure up and working I followed the <a href=\"https:\/\/www.conjur.org\/get-started\/quick-start\/oss-environment\/\">Conjur Opensouce guide here<\/a>.  This walks through most of the CLI commands required to get the containers up and working.  If you wanted to do a manual deploy you can pretty much just follow along with copy\/paste.  <\/p>\n<p>First step is to clone the conjur-quickstart repo.  After that docker-compose is used to pull the various containers, generate a data key, load the key in as an environment variable, then start prepping the conjur environment.<\/p>\n<p>Once this is complete the structure of the system is loaded in via a policy.  A policy dictates what elements exist: hosts, users, variables(things that hold passwords and the like).  They also determine what devices can access what things.<\/p>\n<p>I created this simple flat policy that has two variables, one named password and one named ansible(I&#8217;m loading it in as a jinja template, though I&#8217;m not changing anything at the moment):<br \/>\n<script src=\"http:\/\/gist-it.appspot.com\/https:\/\/github.com\/gregsowell\/ansible-cyberark\/blob\/main\/network.yml.j2\"><\/script><br \/>\nLooking at the network.yml file that is created you can see where I setup my variables at the top, then I specify a host(it will be my tower server, so I named it tower), and the last is permitting tower to read\/execute the above variables.  When I load this policy in, it will generate the API key that the tower user will use, so I pipe this to a file for easy reference later.<\/p>\n<p>After I load that in I store a secret for the variables:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">docker-compose exec client conjur variable values add password redhat\r\ndocker-compose exec client conjur variable values add ansible redhat<\/code><\/pre>\n<h2>Deployment From Ansible<\/h2>\n<p><a href=\"https:\/\/github.com\/gregsowell\/ansible-cyberark\/blob\/main\/conjur-install-config.yml\">Here is the playbook <\/a>for full deployment:<br \/>\n<script src=\"http:\/\/gist-it.appspot.com\/https:\/\/github.com\/gregsowell\/ansible-cyberark\/blob\/main\/conjur-install-config.yml\"><\/script><br \/>\nI&#8217;ll break this down a little at a time.<br \/>\nIn the vars section at the top I&#8217;m specifying which folder the cloned quickstart repo will go in.  This is also where all of the key files will be stored.<br \/>\nNext I set what the passwords for my &#8220;password&#8221; and &#8220;ansible&#8221; variables will be(I set them to redhat by default).<\/p>\n<p>One of the quirks of connecting conjur to tower is that it requires the host name of &#8220;proxy&#8221; to be defined in tower&#8217;s host file(the name &#8220;proxy&#8221; is what tower uses to connect later on in the credential section).  So the first task adds an entry to tower&#8217;s hosts file with the IP of the ca-conjur host.<\/p>\n<p>I next create the storage directory, and then install some yum utilities and add the docker repo.<\/p>\n<p>Next the yum module is used to install docker and git.<\/p>\n<p>Since this is a lab server I kill the linux firewall, then crank on docker.<\/p>\n<p>I now grab the docker compose binary and set it to executable.  Docker compose is what&#8217;s used hence forth to interact with the containers.<\/p>\n<p>After that a simple git clone is done on the quickstart repo.<\/p>\n<p>Following up begins all of the docker-compose commands.  These commands will eventually create four files in the quickstart folder: data_key, admin_data, tower_data, and tower_pki_cert.<br \/>\nThe data_key file will store the key used to connect to the myConjurAccount(the account I create everything in).<br \/>\nadmin_data holds the key for the admin account.<br \/>\ntower_data holds the API key for the tower host that&#8217;s used to connect to conjur from tower.<br \/>\ntower_pki_cert contains the cert that is used to connect to conjur from tower.<\/p>\n<p>At the end of the script it spits out almost all of the info required to create the custom cert(the only thing not displayed is the cert because formatting gets messed up).<br \/>\nThis is an example of the final output:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">TASK [print out user info] *****************************************************\r\nok: [ca-conjur] =&gt; {\r\n    &quot;msg&quot;: [\r\n        {\r\n            &quot;Conjur URL&quot;: &quot;https:\/\/proxy:8443&quot;\r\n        },\r\n        &quot;API Key:       \\&quot;api_key\\&quot;: \\&quot;2kdm28c37ebx1akqtxzynheecjt9zk4ydwt0jb14hm91d2gtqpq2\\&quot;&quot;,\r\n        {\r\n            &quot;Account&quot;: &quot;myConjurAccount&quot;\r\n        },\r\n        {\r\n            &quot;Username&quot;: &quot;host\/tower&quot;\r\n        },\r\n        &quot;Public Key Cert: in file at \/opt\/conjur-repo\/tower_pki_cert.  I couldn&#039;t get formatting to look right for copy paste, so grab from file.&quot;\r\n    ]\r\n}<\/code><\/pre>\n<h2>Conjur Credential In Tower<\/h2>\n<p>So taking the final output from the script above I&#8217;ll fill in the proper details on tower:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">TASK [print out user info] *****************************************************\r\nok: [ca-conjur] =&gt; {\r\n    &quot;msg&quot;: [\r\n        {\r\n            &quot;Conjur URL&quot;: &quot;https:\/\/proxy:8443&quot;\r\n        },\r\n        &quot;API Key:       \\&quot;api_key\\&quot;: \\&quot;2kdm28c37ebx1akqtxzynheecjt9zk4ydwt0jb14hm91d2gtqpq2\\&quot;&quot;,\r\n        {\r\n            &quot;Account&quot;: &quot;myConjurAccount&quot;\r\n        },\r\n        {\r\n            &quot;Username&quot;: &quot;host\/tower&quot;\r\n        },\r\n        &quot;Public Key Cert: in file at \/opt\/conjur-repo\/tower_pki_cert.  I couldn&#039;t get formatting to look right for copy paste, so grab from file.&quot;\r\n    ]\r\n}<\/code><\/pre>\n<p>Here&#8217;s the screenshot of cating the tower_pki_cert file and applying all of the info to my tower:<br \/>\n<a href=\"http:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower1-300x186.png\" alt=\"\" width=\"300\" height=\"186\" class=\"aligncenter size-medium wp-image-6591\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower1-300x186.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower1-768x475.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower1-1024x634.png 1024w, https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower1.png 1306w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\n**notice that in the above host API key that the last \\ isn&#8217;t part of the key**<\/p>\n<p>With all of that info in place, click the test button and try the password or ansible variable:<br \/>\n<a href=\"http:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower2-300x141.png\" alt=\"\" width=\"300\" height=\"141\" class=\"aligncenter size-medium wp-image-6594\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower2-300x141.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower2-768x361.png 768w, https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower2-1024x481.png 1024w, https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower2.png 1704w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Now to utilize this credential as a machine cred, create a standard machine cred, but click the magnifying glass on password:<br \/>\n<a href=\"http:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower3-300x172.png\" alt=\"\" width=\"300\" height=\"172\" class=\"aligncenter size-medium wp-image-6596\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower3-300x172.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower3.png 744w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Now I choose the Conjur credential I just created:<br \/>\n<a href=\"http:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower4.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower4-300x227.png\" alt=\"\" width=\"300\" height=\"227\" class=\"aligncenter size-medium wp-image-6597\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower4-300x227.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower4.png 627w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Once I click &#8220;Next&#8221; I can put in the variable path; in this case it would be password or ansible:<br \/>\n<a href=\"http:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower5.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower5-300x169.png\" alt=\"\" width=\"300\" height=\"169\" class=\"aligncenter size-medium wp-image-6598\" srcset=\"https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower5-300x169.png 300w, https:\/\/gregsowell.com\/wp-content\/uploads\/2020\/11\/tower5.png 609w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h2>Troubleshooting<\/h2>\n<p>You can log into the conjur client from the CLI using the following:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">docker-compose exec client conjur authn login -u admin -p fvdkz72tjb7pd3twtv731csqd1523bxezg7vvn72g3qf7r29zpwyt<\/code><\/pre>\n<p>You can find the password in the above by catting the admin_data file and looking for the &#8220;API key for admin&#8221; section:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">[root@greg-ca-conjour conjur-repo]# cat admin_data\r\nCreated new account &#039;myConjurAccount&#039;\r\nToken-Signing Public Key: -----BEGIN PUBLIC KEY-----\r\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyNnZc4T17gatYNfWwByu\r\nOwpsgeI1Nc\/NuUbcVS88R2e0VsI0EM6A8yN0\/e0y9PxppbNnKRN3E7OEo7MWw6oI\r\nWBWzDJtfexDXPVJLYfbJ0iwjXESRevaORyA58Lh9LOtp2ByUpQqEViGp0mxdDNJb\r\n92ZdyCWhzAtMKhsqjQ38ZCIap0SCPSyZgZRTzh1cWeZaLpKGDXWy8cHEmeGHGeyQ\r\n8yMtITUkzP2SFLuJQjahWlI\/WlL8+Lm1yV5NZFv8WN0KhwCRB332RMVyJzaTwdqa\r\nxMxlmYUbqVaGO4Lq2LatOyGGGmIzfKV6HS+0ynDm8w4p8yeoTvOu9Y4kq43jMcPo\r\n+wIDAQAB\r\n-----END PUBLIC KEY-----\r\nAPI key for admin: 1wx2sj11a5wv821t62p133mw11xj1gm27011gjmtpp1dhcdqv2pk3617<\/code><\/pre>\n<p>Once logged in I can view the configured infrastructure with the conjur list command:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">[root@greg-ca-conjour conjur-repo]# docker-compose exec client conjur list\r\n[\r\n  &quot;myConjurAccount:policy:root&quot;,\r\n  &quot;myConjurAccount:variable:password&quot;,\r\n  &quot;myConjurAccount:variable:ansible&quot;,\r\n  &quot;myConjurAccount:host:tower&quot;\r\n]<\/code><\/pre>\n<p>^^ In the above myConfurAccount is the system account.  You can also see the variables in the system along with their location structure.  I also see my configured hosts.<\/p>\n<p>Now that I see my variables listed I can view their contents like so:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">[root@greg-ca-conjour conjur-repo]# docker-compose exec client conjur variable value password\r\nredhat<\/code><\/pre>\n<p>If I want to check out what my docker containers are doing I can issue the following:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">[root@greg-ca-conjour conjur-repo]# docker ps\r\nCONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                           NAMES\r\n0fcd7aab279f        cyberark\/conjur-cli:5            &quot;sleep infinity&quot;         19 hours ago        Up 19 hours                                         conjur_client\r\nc212738f44da        nginx:1.13.6-alpine              &quot;nginx -g &#039;daemon of\u2026&quot;   19 hours ago        Up 19 hours         80\/tcp, 0.0.0.0:8443-&gt;443\/tcp   nginx_proxy\r\n686336d019ec        cyberark\/conjur                  &quot;conjurctl server&quot;       19 hours ago        Up 19 hours         80\/tcp                          conjur_server\r\n096ace7521c8        cfmanteiga\/alpine-bash-curl-jq   &quot;tail -F anything&quot;       19 hours ago        Up 19 hours                                         bot_app\r\n7b41709e8a27        postgres:10.14                   &quot;docker-entrypoint.s\u2026&quot;   19 hours ago        Up 19 hours         5432\/tcp                        postgres_database<\/code><\/pre>\n<p>The above command will list the various containers and their current states.<\/p>\n<p>I can view their log files by issuing a docker logs command along with the container ID form the ps command:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">[root@greg-ca-conjour conjur-repo]# docker logs c212738f44da\r\n10.1.12.10 - - [03\/Nov\/2020:21:11:48 +0000] &quot;POST \/authn\/myConjurAccount\/host%2Ftower\/authenticate HTTP\/1.1&quot; 200 632 &quot;-&quot; &quot;python-requests\/2.23.0&quot;\r\n10.1.12.10 - - [03\/Nov\/2020:21:11:48 +0000] &quot;GET \/secrets\/myConjurAccount\/variable\/password HTTP\/1.1&quot; 200 16 &quot;-&quot; &quot;python-requests\/2.23.0&quot;\r\n10.1.12.10 - - [04\/Nov\/2020:14:46:04 +0000] &quot;POST \/authn\/myConjurAccount\/host%2Ftower\/authenticate HTTP\/1.1&quot; 200 632 &quot;-&quot; &quot;python-requests\/2.23.0&quot;\r\n10.1.12.10 - - [04\/Nov\/2020:14:46:04 +0000] &quot;GET \/secrets\/myConjurAccount\/variable\/password HTTP\/1.1&quot; 200 16 &quot;-&quot; &quot;python-requests\/2.23.0&quot;<\/code><\/pre>\n<p>You can also follow the logs while you are testing with -f:<\/p>\n<pre class=\"gs-code\"><code class=\"language-plaintext\">[root@greg-ca-conjour conjur-repo]# docker logs c212738f44da -f\r\n10.1.12.10 - - [03\/Nov\/2020:21:11:48 +0000] &quot;POST \/authn\/myConjurAccount\/host%2Ftower\/authenticate HTTP\/1.1&quot; 200 632 &quot;-&quot; &quot;python-requests\/2.23.0&quot;\r\n10.1.12.10 - - [03\/Nov\/2020:21:11:48 +0000] &quot;GET \/secrets\/myConjurAccount\/variable\/password HTTP\/1.1&quot; 200 16 &quot;-&quot; &quot;python-requests\/2.23.0&quot;\r\n10.1.12.10 - - [04\/Nov\/2020:14:46:04 +0000] &quot;POST \/authn\/myConjurAccount\/host%2Ftower\/authenticate HTTP\/1.1&quot; 200 632 &quot;-&quot; &quot;python-requests\/2.23.0&quot;\r\n10.1.12.10 - - [04\/Nov\/2020:14:46:04 +0000] &quot;GET \/secrets\/myConjurAccount\/variable\/password HTTP\/1.1&quot; 200 16 &quot;-&quot; &quot;python-requests\/2.23.0&quot;<\/code><\/pre>\n<h2>Conclusion<\/h2>\n<p>So enterprise Conjur would be MUCH simpler to deal with since it has a GUI that walks you simply through all of these steps.  I&#8217;d honestly like to give the enterprise edition a test drive just to see the differences, but for now, the system is done.  <\/p>\n<p>Let me know your questions and comments, and as always, happy automating!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>First I have to say this wasn&#8217;t as simple and straight forward as I could have hoped for&#8230;in fact it took me the better\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,14,13],"tags":[],"class_list":["post-6585","post","type-post","status-publish","format-standard","hentry","category-ansible","category-linux","category-server"],"_links":{"self":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/6585","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=6585"}],"version-history":[{"count":14,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/6585\/revisions"}],"predecessor-version":[{"id":6604,"href":"https:\/\/gregsowell.com\/index.php?rest_route=\/wp\/v2\/posts\/6585\/revisions\/6604"}],"wp:attachment":[{"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6585"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6585"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gregsowell.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6585"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}