23

I need to add p3p headers to the static resource location on a standard Nodejs & Nginx Elastic Beanstalk.

I've created an ebextension script as explained on this question. The script uses set to add a add_header directive under the alias line, which is under the static location directive. It runs on the /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf file.

The script not only modifies the file, it also copies it to a "safe" location, i.e. /home/ec2-user. According to /var/log/cfn-init.log, the script runs correctly. As evidence, the copy of the modified file shows the additional header at the right place. But the /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf file does not have this modification.

I can only deduce that although my script runs fine, something else later in the deployment process overwrites it. Which is strange, because according to documentation container commands are run after the application and web server have been set up, so I don't see what does it.

So ho/what is overwriting this file and how can I prevent that?

vaquar khan
  • 10,864
  • 5
  • 72
  • 96
Antoine
  • 5,055
  • 11
  • 54
  • 82

6 Answers6

27

After spending almost entire day and trying out all the possible solutions, as of July 17, 2017, the above solution does not work. For me, I wanted to replace /etc/nginx/conf.d/elasticbeanstalk/00_application.conf I created the below shown folder structure in my .ebextension folder and the file was overwritten with my content. This solution also worked for nginx.conf which is located in /etc/nginx folder enter image description here

Monil Gandhi
  • 544
  • 1
  • 5
  • 13
  • 5
    Thanks, worked for me too. This behavior is documented [here](https://aws.amazon.com/blogs/aws/category/aws-elastic-beanstalk/). _You can now place an nginx.conf file in the .ebextensions/nginx folder to override the Nginx configuration. You can also place configuration files in the .ebextensions/nginx/conf.d folder in order to have them included in the Nginx configuration provided by the platform._ – Andy Jul 24 '17 at 12:06
  • 1
    A direct link to the blogpost mentioning the behavior is https://aws.amazon.com/blogs/aws/elastic-beanstalk-update-support-for-java-and-go/ – Steven Nov 01 '17 at 21:45
  • 6
    It is worth to mention that this solution work only with some ELB Platforms - Java and Go. If you use for example Docker Platform with nginx as proxy you have to use solution with configuration file (that use **files** keyword) placed inside **.ebextensions** - example below `files: "/etc/nginx/nginx.conf": content: | #your override nginx config here` – rkarczmarczyk Nov 13 '17 at 23:08
  • @rkarczmarczyk Actually when I tried to use with docker, I was unable to override any files in /etc/nginx folder. I was however able to override in sites_enabled. I will give your solution a shot. Thanks for the info. – Monil Gandhi Nov 14 '17 at 17:28
  • 3
    I can confirm this is not working with their latest node platform at the time of writing this. – Sean256 Mar 27 '18 at 20:57
  • can you tell how you made changes to the file – Mishu Aug 09 '18 at 12:24
  • I can confirm that it's working as of March 2019 for the Go platform – Valentin V Mar 20 '19 at 16:48
  • Yeaa! Works for me! – Matt Jul 25 '19 at 13:41
  • 3
    Placing in `./platform/nginx/*` for Ruby Amazon Linux 2 works. Stated in docs https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.migration-al.html. – jshah Aug 19 '20 at 20:08
17

It seems that Elastic Beanstalk has changed and the commonly recommended approach/hack of overwriting #etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf doesn't work any more. Nor does creating any file in /tmp/deployment/config.

The solution I found was to overwrite /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf directly, using a container_commands directive, since these commands are executed after the Elastic Beanstalk install creates it's version of the nginx config.

From http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html#linux-container-commands:

They [container_commands] run after the application and web server have been set up and the application version file has been extracted, but before the application version is deployed.

I did this in three steps within .ebextensions:

  1. Create my version of the nginx config file.

  2. Create a script to overwrite the standard config file with my own.

  3. Run the script.

The first two steps happen earlier in the install process, while the last uses container_commands so as described previous happens late in the install.

Here's the files I used:

File .ebextensions/install_nginx_config_01.config:
(Note that the indenting is important)

#
#   STEP 1 - Create the nginx config file
#
files:

  "/tmp/my.nginx.conf" :
    mode: "000755"
    owner: root
    group: root
    content: |
      # This file was overwritten during deployment
      # by .ebextensions/install_nginx_config_03.config

      upstream nodejs {
          server 127.0.0.1:3000;
          keepalive 256;
      }

      server {
          listen 8080;

          location / {
              proxy_pass  http://nodejs;
              proxy_set_header   Connection "";
              proxy_http_version 1.1;
              proxy_set_header        Host            $host;
              proxy_set_header        X-Real-IP       $remote_addr;
              proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
          }

          gzip on;
          gzip_comp_level 4;
          gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
      }

File .ebextensions/install_nginx_config_02.config:

#
#   STEP 2 - Create a script that will overwrite the Nginx config
#
files:

  "/tmp/install-nginx-config.sh" :
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/bin/sh
      cp /tmp/my.nginx.conf /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf

File .ebextensions/install_nginx_config_03.config:

#
#   STEP 3 - Run the script to overwrite the nginx config template.
#
container_commands:

  01_runmyshellscript:
    command: "/tmp/install-nginx-config.sh"
Philip Callender
  • 1,465
  • 1
  • 14
  • 21
  • this seems to be the only thing that works as of now – chris Oct 26 '16 at 14:52
  • 1
    When I try this I get: Service:AmazonCloudFormation, Message:[/Resources/AWSEBAutoScalingGroup/Metadata/AWS::CloudFormation::Init/prebuild_1_Homepage/files//tmp/install-nginx-config.sh] 'null' values are not allowed in templates – Ken Fehling May 12 '17 at 20:48
  • Thanks! I finally got this working using this method. It can be noted that all three steps can be put in a single file if one prefers it that way (both files to be written has to be under a single files clause in that case). – Henrik Hansson Dec 01 '20 at 22:28
13

As of this writing, the proper way to update/add values into the http config in the nginx.conf file without overwriting it is to add a .config file to the .ebextensions folder that looks like this:

files:
  "/etc/nginx/conf.d/custom_nginx.conf":
    content: |

      proxy_connect_timeout       600;
      proxy_send_timeout          600;
      proxy_read_timeout          600;
      send_timeout                600;

This creates a new file called custom_nginx.conf in the /etc/nginx/conf.d directory. Since the nginx.conf file contains

http {
  include       /etc/nginx/conf.d/*.conf;
}

when the server is started it will pull the 4 timeout vars from custom_nginx.conf into the http section of nginx.conf

McLovin
  • 1,455
  • 3
  • 19
  • 37
8

As of August, 2020 for Ruby 2.6 running on 64bit Amazon Linux 2/3.1.0:

Placing nginx files in the .platform/nginx/ works for me.

Here is my folder structure:

enter image description here

jshah
  • 1,599
  • 2
  • 17
  • 38
  • 3
    After spending a day on this, this is the only thing that has worked for me. `ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux] Amazon Linux 2` – eddz Oct 01 '20 at 09:35
  • 1
    The AWS documentation covers it here: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html See the section titled "Reverse proxy configuration" for details. – Rich Armstrong Oct 14 '20 at 22:38
4

To modify the config file without it being overwritten, the solution is to modify the template file located at /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf

I update this file instead to add the desired directive, and it is automatically deployed to /etc/nginx/conf.d, and voila, the modification is active.

mana
  • 6,347
  • 6
  • 50
  • 70
Antoine
  • 5,055
  • 11
  • 54
  • 82
  • Are there any different ways other than modifying this file through `files:` block inside a config file located in `.ebextensions` folder? The file is never modified although everything seems to be correct. I just see the default file at both `/tmp/deployment/config` folder and also at `/etc/nginx/` folder. – scaryguy Nov 17 '15 at 09:00
  • Yes, you can run code with the `commands` or `container_commands` sections of the config file. See http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html. – Antoine Nov 17 '15 at 09:15
  • `files:` doesn't work.`04modify_nginx_conf: command: sed -i '/EB_INCLUDE/a geoip_country /usr/share/GeoIP/GeoIP.dat;\ngeoip_city /usr/share/GeoIP/GeoLiteCity.dat;' /tmp/deployment/config/#etc#nginx#nginx.conf` doesn't work. `/etc/nginx/nginx.conf` never changes! I'm really pissed off. – scaryguy Nov 17 '15 at 09:37
  • What if you try to put your configuration in a separate file, like `00_elastic_beanstalk_proxy.conf`? – Antoine Nov 17 '15 at 09:46
  • It should be inside `http` block. And I also tried to modify `00_elastic_beanstalk_proxy.conf` but couldn't do that. It turns out creating a bash script and running is the only way to change those files? Doesn't it? – scaryguy Nov 17 '15 at 09:55
  • That's strange, I am updating it with container commands. Here's my config file: http://pastebin.com/aFVAsibh – Antoine Nov 17 '15 at 10:29
  • Thank you for sharing your config. I've tried creating a config file and doing a `cp -R` to the `/etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf` but now I get permission denied error.. – scaryguy Nov 17 '15 at 11:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/95329/discussion-between-antoine-and-scaryguy). – Antoine Nov 17 '15 at 11:08
  • 2
    This no longer works. @philip-callender comment is correct. – Brandon Oct 26 '16 at 14:53
3

Here are the latest instructions from Amazon, as of August 2018: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/nodejs-platform-proxy.html

(I have just used these instructions to customize the Nginx proxy for a Node.js app on Elastic Beanstalk, and it works as expected.)

Basically you use your own proxy.conf for Nginx, and remove the auto-generated stuff.

# .ebextensions/proxy.config
files:
  /etc/nginx/conf.d/proxy.conf:
    mode: "000644"
    owner: root
    group: root
    content: |
      upstream nodejs {
        server 127.0.0.1:5000;
        keepalive 256;
      }

      server {
        listen 8080;

        if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
            set $year $1;
            set $month $2;
            set $day $3;
            set $hour $4;
        }
        access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
        access_log  /var/log/nginx/access.log  main;

        location / {
            proxy_pass  http://nodejs;
            proxy_set_header   Connection "";
            proxy_http_version 1.1;
            proxy_set_header        Host            $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        gzip on;
        gzip_comp_level 4;
        gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        location /static {
            alias /var/app/current/static;
        }

      }

  /opt/elasticbeanstalk/hooks/configdeploy/post/99_kill_default_nginx.sh:
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/bin/bash -xe
      rm -f /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf
      service nginx stop 
      service nginx start

container_commands:
 removeconfig:
    command: "rm -f /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf"
talyric
  • 973
  • 2
  • 11
  • 14