Hoping someone might be able to help with integrating the Ansible Playbook with Amazon CodeDeploy

Ok, this should the last of it. I’ll give a quick rundown of what I’ve done and hopefully you can let me know what is causing the last problem here.

server.yml has

- name: "WordPress Server: Install LEMP Stack with PHP 5.6 and MariaDB MySQL"
  hosts: tag_Site_Mysite
  sudo: yes
  remote_user: ubuntu

That works. Inside group_vars is a file called tag_Site_Mysite, with a copy of what is in group_vars/production, except wp_env: tag_Site_Mysite.

deploy.yml has similar settings-

---
- name: Deploy WP site
  hosts: tag_Site_Mysite
  remote_user: ubuntu
  sudo: yes

  vars:
    project: "{{ wordpress_sites[site] }}"
    project_root: "{{ www_root }}/{{ site }}"

  roles:
    - deploy

Now, here comes the problem. When I run ansible-playbook -i ec2.py deploy.yml --extra-vars="site=sitename" no matter what I place as the site name , nothing seems to work. I’m not sure what I should be playing in there. If I use the servers address I listed in group_vars/tag_Site_Mysite I get back-

failed: [52.7.246.149] => {"cmd": "/usr/bin/git ls-remote '' -h refs/heads/master", "failed": true, "rc": 128}
stderr: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

msg: Permission denied (publickey).
fatal: Could not read from remote repository.

Which really makes no sense, since SSH is most definitely set up correctly to Github. I’m assuming I’m either missing something extremely simple here, since I’ve spent so much time trying to solve all the complicated stuff, or I’m just not placing the correct variable in --extra-vars="site=sitename"

I appreciate you putting the effort in… I’m close. Just the fact that its provisioning any server tagged a certain way is pretty awesome. Now, just have to get down what seems like it would be the easy part and to deploy the site itself.

“sitename” is whatever you’ve named your site here.

Also I’m not sure you want to change wp_env. It should probably stay as production.

For deploy.yml: you may not need to change remote_user and sudo. Was it not working being left as the web_user? It’s recommend you stick with the web_user but you’ll have to add your own SSH keys for that user like this.

More info here and also make sure you have SSH forwarding working properly: https://developer.github.com/guides/using-ssh-agent-forwarding/

Mind you I did this over 24 hours ago, and was among a ton of things I tried until things finally worked, but I believe I changed user to Ubuntu because I got an error message saying I needed to SSH in as ubuntu. I added sudo based on something I saw on one of the 15-20 pages I had open in my browser trying to figure this out on the fly. Whether or not it contributed to things finally working, I’m not sure. I’ll try going back to the configuration above and simplifying things via process of elimination.

That SSH link you supplied is actually what I was using before I made the last post. Its why I believe that the error is based off bad configurations, not a result of my SSH keys. I still have no idea why I decided to switch up my the way I was doing things when I’m on a deadline with one of my largest clients, but I guess I love chaos.

Well, holy hell, it worked… With one small problem.

I had to set remote_user to ubuntu, and set sudo to yes. Then I had to create an SSH key in my root account on the server…

The reason being is that I can only log into my instance as Ubuntu. However, to have access to write to /srv/www, I need to have sudo access… Now I’m aware theres probably a better way to do this, but I don’t know what the www_user variable that was originally set would create. I guess I could SSH into the account and create a new user and give it SSH access, but I’m not sure what the www_user is. (i.e. I don’t think its www_user@myinstanceip.com, right?) If its www-data, then the only problem would be I don’t know the password to log in as that user when I’m ssh’ed in to be able to give it ssh access.

But, for now, this works… finally. Thank you so much… I’m sure this has been a pain, but someone at some point is going to have to deploy to an Auto Scaling Group with Bedrock. I just wish I had the last part above figured out so I could write out a solid guide.

Thanks again for all the help.

You can see exactly what the playbook does for the web user: https://github.com/roots/bedrock-ansible/blob/194b65ff7cfb8400854591e06cd05b92d085ac7d/roles/users/tasks/main.yml

You can see here how you get a public SSH key onto the server for the web user.

You’d think at this point I’d just look for that file and find out for myself… The little things are killing me right now… Thank you for those links. They should help me simplify the code .

I’m going to create a forked repo of Bedrock-Ansible with the ec2.py and ec2.ini scripts included, along with detailed instructions on how to easily deploy to either a single Amazon EC2 Instance, or an Auto Scaling Group. The beauty of doing it this way is, even if you were to start with a single instance, if your site ever gets big and has a spike in traffic, you’re already set up to expand just by creating more instances with the same tag that you defined. Nothing else to change or set up at all.

For anyone else that might be interested in what this accomplishes without having to look over the other 25 replies in this thread, heres an example-


So, the Amazon EC2 Instances for the site I’m building all have a tag attached to them to distinguish them from other Instances for other sites. I used the tag “Site = Nameofthesite” in this case. You can add multiple tags to further refine things. It doesn’t matter what the tag is, its just a way to tell Ansible what Instances you’d like to provision/deploy to. It also doesn’t matter how many Instances you have, or how many are created in the future, as long as they have the tag(s) you defined, the script will find the correct ones and allow you to provision or deploy to them without having to enter individual details about each one.

In my case, right now I have two EC2 Instances created to start, with the “Site = Mysitename” tag given to both within AWS. Without having to input any other details about them within Bedrock-Ansible, when I run ansible-playbook -i ec2.py server.yml it automatically finds the IP’s of all the Instances with the tag I defined and provisions them. Its cool in the way that when it provisions or deploys, it performs each step on all of the Instances at the same time, so you can easily see the progress, like this-

TASK: [php | Add PHP 5.6 PPA] ************************************************* 
ok: [52.7.246.149]
changed: [52.7.246.150]

TASK: [php | Install PHP 5.6] ************************************************* 
ok: [52.7.246.149] => (item=php5-common,php5-fpm,php5-mysqlnd,php5-xmlrpc,php5-mcrypt,php5-curl,php5-gd,php5-cli,php-pear,php5-dev,php5-imap)
changed: [52.7.246.150] => (item=php5-common,php5-fpm,php5-mysqlnd,php5-xmlrpc,php5-mcrypt,php5-curl,php5-gd,php5-cli,php-pear,php5-dev,php5-imap)

TASK: [php | Start php5-fpm service] ****************************************** 
ok: [52.7.246.150]
ok: [52.7.246.149]

You can see in the example above that the Instance with the IP ending in .149 already had PHP installed, so it outputted “ok”, whereas the IP ending in .150 didn’t have it installed yet, so it was “changed”. This is great, as I don’t have to worry about excluding Instances that have already been provisioned. When new Instances are created automatically within an Auto Scaling Group, all I have to do is run the command again, and it will provision those that need it, or update anything I might of changed on others. I could even set up a Bootstrap script, or an Automation to do this automatically when new Instances are spun up in the Auto Scaling Group to ensure they have they have the latest provisioning right off the bat. I’ll be adding this step to my workflow for sure.


If you’re interested in provisioning or deploying Bedrock to an AWS Auto Scaling Group, or even just a single EC2 Instance, this is a fantastic route to take. I have a few kinks to work out in order to simplify and enhance some of my code, but like I said, I’m going to upload a forked version of Bedrock-Ansible with all the necessary scripts and settings, along with detailed instructions on how to set it all up. I’ll be sure to post a link.

Scott, I really can’t thank you enough… You have no idea how much you’ve helped me, and how much this will continue to help me. The project I needed to create this for is my biggest client to date. I couldn’t rely on my old way of deploying, and I wanted to have a rock solid workflow set up from the beginning to prevent having to change things later. The fact that you took the amount of time you did to guide me through this over the last 24 hrs says a lot about you and the Roots team as a whole. In all, this proves just how amazingly flexible and adaptable Bedrock/Bedrock-Ansible really is.

-P.J.

4 Likes

I resent this comment, @kalenjohnson

Most definitely, thank you for your pain and suffering, I’ll be trying to emulate this tomorrow.