Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Opsworks Custom Layer Deployment

I am trying to use a custom layer in AWS Opsworks to add a nginx webserver.

I have successfully created the layer, I added my app via GIT (no password on repo), but when I deploy the command is "successful" but I don't see any of my code on my server.

In the custom layer, the only deploy recipe is "deploy::default".

Do I need a custom recipe to handle the deployment?

Also, how do I configure "where" the deployment goes? I'd prefer to chose my document root rather than using what location Opsworks otherwise seems to always deploy to.

Thanks for ANY help on this.

like image 989
sudoyum Avatar asked Aug 06 '13 17:08

sudoyum


People also ask

How is AWS OpsWorks different than AWS CloudFormation?

AWS CloudFormation enables modeling, provisioning and version-controlling of a wide range of AWS resources. AWS OpsWorks is an application management service that simplifies software configuration, application deployment, scaling, and monitoring.

Which is an AWS OpsWorks stacks deployment lifecycle event?

One of the key AWS OpsWorks Stacks features is a set of lifecycle events—Setup, Configure, Deploy, Undeploy, and Shutdown—which automatically run a specified set of recipes at the appropriate time on each instance.

Does CodePipeline support OpsWorks?

You can use CodePipeline to automate the release of your Chef cookbooks and application code to AWS OpsWorks Stacks, on Chef 11.10, Chef 12, and Chef 12.2 stacks.


2 Answers

I've written a simple recipe which uses the Opsworks nginx recipe to deploy the app fully automatically. It checks out from your configured SCM, creates a new nginx vhost and reloads nginx if required.

Add this recipe to the deploy config in the layer:

deploy.rb

include_recipe "deploy"
include_recipe "php5"

node[:deploy].each do |application, deploy|

  Chef::Log.info("Deploying application #{application} on #{node[:opsworks][:instance][:hostname]}")

  if deploy[:application_type] != 'php'
    Chef::Log.warn("Skipping deploy::web application #{application} as it is not a PHP app")
    next
  end

  opsworks_deploy_dir do
    user deploy[:user]
    group deploy[:group]
    path deploy[:deploy_to]
  end

  opsworks_deploy do
    app application
    deploy_data deploy
  end

  nginx_web_app application do
    application deploy
  end

  Chef::Log.info("Running composer update on #{deploy[:deploy_to]}")
  composer_update do
    path deploy[:deploy_to]}
  end
end

To overwrite the nginx vhost template, just create a new cookbook called nginx and add a file site.erb in templates/default. Opsworks will automatically use this template then.

My site.erb looks like this

server {
  listen   80;
  server_name  <%= @application[:domains].join(" ") %> <%= node[:hostname] %>;
  access_log  <%= node[:nginx][:log_dir] %>/<%= @application[:domains].first %>.access.log;

  root   <%= @application[:absolute_document_root] %>;

  location / {
     try_files $uri /index.php?url=$uri&$args;
  }

  location ~ \.php {
      try_files $uri =404;

      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      fastcgi_pass  127.0.0.1:9000;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

      include fastcgi_params;
  }

  # Block all svn access
  if ($request_uri ~* ^.*\.svn.*$) {
     return 404;
  }

  # Block all git access
  if ($request_uri ~* ^.*\.git.*$) {
     return 404;
  }

  location /nginx_status {
    stub_status on;
    access_log off;
    allow 127.0.0.1;
    deny all;
  }

}

<% if @application[:ssl_support] %>
server {
  listen   443;
  server_name  <%= @application[:domains].join(" ") %> <%= node[:hostname] %>;
  access_log  <%= node[:nginx][:log_dir] %>/<%= @application[:domains].first %>-ssl.access.log;

  ssl on;
  ssl_certificate <%= node[:nginx][:dir] %>/ssl/<%= @application[:domains].first %>.crt;
  ssl_certificate_key <%= node[:nginx][:dir] %>/ssl/<%= @application[:domains].first %>.key;
  <% if @application[:ssl_certificate_ca] -%>
  ssl_client_certificate <%= node[:nginx][:dir] %>/ssl/<%= @application[:domains].first %>.ca;
  <% end -%>

  location / {
     try_files $uri /index.php?url=$uri&$args;
  }

  location ~ \.php {
      try_files $uri =404;

      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      fastcgi_pass  127.0.0.1:9000;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

      include fastcgi_params;
  }

  # Block all svn access
  if ($request_uri ~* ^.*\.svn.*$) {
     return 404;
  }

  # Block all git access
  if ($request_uri ~* ^.*\.git.*$) {
     return 404;
  }
}
<% end %>

My Berksfile (for composer)

source "https://supermarket.getchef.com"

cookbook 'composer', '~> 1.0.4'

My metadata.rb in the cookbook for the deploy appserver::deploy recipe

name             'appserver'
maintainer       'Michel Feldheim'
description      'Setting up the appserver environment'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version          '0.1.0'

depends          "nginx"
depends          "php5"
like image 178
Michel Feldheim Avatar answered Nov 16 '22 02:11

Michel Feldheim


Yes, you will need to write your own custom deploy recipe for a custom layer. Your deploy recipe can configure where the deployment goes and any steps required to deploy your software. Alternatively you can extend the OpsWorks static web server layer, which deploys Nginx, to meet your needs.

like image 37
Chrisb Avatar answered Nov 16 '22 02:11

Chrisb