[英]Access Elastic Beanstalk environment properties in NGINX configs running on AWS Linux 2
我之前在 AWS Linux AMI 上工作過,但在 AWS Linux 2 上沒有運氣。
在 EB 應用程序部署期間,我需要從 Nginx 配置文件訪問我的環境屬性。 這是一個單實例節點服務器。
我用 AWS Linux AMI 這樣做,它沒有問題:
.ebextensions/00_options.config
option_settings:
aws:elasticbeanstalk:application:environment:
DOMAIN: socket.example.com
MASTER_DOMAIN: https://example.com
etc..
.ebextensions/10_proxy.config
... some configs ...
files:
/etc/nginx/conf.d/proxy.conf:
mode: "000644"
owner: root
group: root
content: |
upstream nodejs {
server 127.0.0.1:8081;
keepalive 256;
}
map $http_origin $cors_header {
hostnames;
default "";
`{"Fn::GetOptionSetting": {"Namespace": "aws:elasticbeanstalk:application:environment", "OptionName": "MASTER_DOMAIN"}}` "$http_origin";
}
server {
listen 80;
listen 8080;
server_name `{"Fn::GetOptionSetting": {"Namespace": "aws:elasticbeanstalk:application:environment", "OptionName": "DOMAIN"}}`;
location ~ /.well-known {
allow all;
root /usr/share/nginx/html;
}
location / {
return 301 https://$host$request_uri;
}
}
etc..
.... some more configs ....
我沒有包括上面的大部分配置,因為它們不相關。
所以當我之前這樣做時,一切都按預期進行。 配置文件插入了我的屬性並在/etc/nginx/conf.d/proxy.conf
文件夾中創建了文件。
現在對於 AWS Linux 2,規格已經更改,我們必須在位於應用程序包根文件夾的.platform/nginx/conf.d
文件夾中添加 Nginx 配置文件。
這里參考(見反向代理配置)
所以我在上面提到的位置創建了一個proxy.conf
文件,其中包含之前插入的內容/etc/nginx/conf.d/proxy.conf
。
.platform/nginx/conf.d/proxy.conf
upstream nodejs {
server 127.0.0.1:8081;
keepalive 256;
}
map $http_origin $cors_header {
hostnames;
default "";
`{"Fn::GetOptionSetting": {"Namespace": "aws:elasticbeanstalk:application:environment", "OptionName": "MASTER_DOMAIN"}}` "$http_origin";
}
etc...
然后問題開始了..
第一次試驗unexpected "{" in /var/proxy/staging/nginx/conf.d/proxy.conf:11
。
之后我嘗試了很多東西。 嘗試使用${MASTER_DOMAIN}
並使用新的 EB AWS Linux 2 個hooks
(參見上面的鏈接Platform hooks )。 一切都無濟於事,您似乎無法訪問 Nginx 配置中的屬性。 我已經閱讀了一篇來自 Nginx 的文章或文檔,今天提到了類似的內容,但我再也找不到了(做了很多谷歌搜索)。
我還嘗試創建一個配置文件,就像我在工作版本中所做的那樣,目的是將臨時文件保存在包含屬性的某處,然后將此文件包含在所需的.platform/nginx/conf.d/proxy.conf
文件中,因為我開始認為沒有辦法將它們直接包含在新規范中。
.ebextensions/10_proxy.config
... some configs ....
files:
/var/proxy/staging/custom_folder/proxy.conf:
mode: "000644"
owner: root
group: root
content: |
etc...
.platform/nginx/conf.d/proxy.conf
include custom_folder/proxy.conf;
考慮到這個想法,我做了很多廢話,我創建了用於創建 ( mkdir
) 目錄的hooks
,我試圖在其中臨時保存導致新權限錯誤的文件。 我無法為 prebuild 和prebuild
文件提供適當的權限, postdeploy
是另一個問題。
還有更多的嘗試和失敗......
但后來我讀過(也來自上面的鏈接):
“如果您將代理配置為向多個應用程序進程發送流量,則可以配置多個環境屬性,並在代理配置和應用程序代碼中使用它們的值。 ”
希望回來了。這是否意味着我實際上可以直接將環境變量添加到位於.platform目錄中的.platform
配置中? ...我不知道..你呢?
我可以繼續描述我整晚嘗試的所有事情,所以我會在這里停下來。 我希望你能明白這個問題。 如果不問我,我會盡力讓所有這些都可以理解。
在與這個問題作斗爭 14 小時后,我的頭腦也不再很清楚了。 我需要休息。
如果你做到了最后,謝謝你的時間,我們將不勝感激。
一種方法是在.platform/hooks/postdeploy
postdeploy 中創建一個 shell 腳本。
這是一個簡化的示例,假設您有一個名為MASTER_DOMAIN
的 Elastic Beanstalk 環境屬性:
#!/bin/bash
# write nginx config file
cat > /etc/nginx/conf.d/elasticbeanstalk/test.conf << LIMIT_STRING
location /test/ {
default_type text/html;
return 200 "nginx variable: \$host, and EB env property: $MASTER_DOMAIN";
}
LIMIT_STRING
# restart nginx service so the config takes effect
systemctl restart nginx.service
此示例中的location
塊可以替換為原始帖子中.ebextensions/10_proxy.config
中的 nginx content
。 不過不需要Fn::GetOptionSetting
東西。
我認為您還需要.platform/confighooks/postdeploy
中的重復腳本。
詳情如下。
(對不起文字牆)
實際上,正如此處和此處所討論的,不可能(開箱即用)在http
、 server
或 nginx 配置文件中的location
塊中使用操作系統環境變量。 有一些解決方法,例如使用 lua、perl 或模板,但我們先不談這些。 這部分與 AWS 無關。
在 Amazon Linux AMI (AL1) 的 OP 原始配置中,使用.ebextensions/10_proxy.config
中的files
部分,他們實際上使用 shell 腳本在部署期間編寫 nginx 配置文件。 shell 腳本擴展了環境變量,但生成的proxy.conf
的 proxy.conf 實際上並沒有訪問任何環境變量。
這就是它在 AL1 上起作用的原因。
現在,對於 Amazon Linux 2 (AL2),我們可以使用.platform/hooks
和.platform/confighooks
文件夾中的 shell 腳本執行類似的操作。
這些.platform
掛鈎腳本以root
用戶身份執行,並且可以訪問 Elastic Beanstalk (EB) 環境屬性。 EB 環境屬性可以像普通操作系統環境變量一樣訪問,因此無需使用Fn::GetOptionSetting
東西。
基本上,我們需要創建一個 shell 腳本,該腳本使用原始.ebextensions/10_proxy.config
的content
寫入一個文件。 但是,我們需要考慮兩個問題:
我們應該使用prebuild
、 predeploy
還是postdeploy
鈎子?
我們的 nginx proxy.conf
文件的正確目標目錄是什么?
要回答這些問題,我們必須參考擴展 Elastic Beanstalk Linux 平台的 AWS 文檔,特別是實例部署工作流部分。
... 平台掛鈎的當前工作目錄 (cwd) 是應用程序的根目錄。 對於 prebuild 和 predeploy 文件,它是應用程序暫存目錄,對於 postdeploy 文件,它是當前應用程序目錄。 如果其中一個文件失敗(以非零退出代碼退出),部署將中止並失敗。
這很有趣,但留下了一些問題,例如“應用程序暫存目錄”位於何處? 我們可以通過檢查我們的部署日志文件之一來填補空白。 根據我們的eb-engine.log
,以下是應用程序部署期間平台掛鈎和 nginx 配置文件發生的情況(跳過很多細節):
/var/app/staging/
.platform/hooks/prebuild/
中的平台鈎子被執行/var/app/staging/.platform/nginx/
復制到/var/proxy/staging/nginx
.platform/hooks/predeploy/
中的平台鈎子被執行/var/proxy/staging/nginx/
復制到/etc/nginx
.platform/hooks/postdeploy/
中的平台鈎子被執行請注意,部署后,應用程序位於/var/app/current
中。
基於以上,有幾種選擇:
在寫入/etc/nginx/conf.d/proxy.conf
的.platform/hooks/postdeploy
postdeploy 中創建一個 shell 腳本。
nginx服務已經運行,現階段需要重啟才能使配置生效。
下面是一個最小的測試示例。 在此示例中,我們寫入elasticbeanstalk
子目錄,因為我們只想在默認server
塊內添加一個location
。 然后我們可以在瀏覽器中訪問/test/
頁面,以檢查配置是否有效。
我們使用一些bash io 重定向( <<
, >
)來編寫 nginx 配置文件。
請注意,我們需要轉義任何 nginx 變量,例如$host
變為\$host
,否則 shell 會將它們解釋為環境變量。
另請注意,shell 腳本需要具有執行權限,如文檔中有關平台掛鈎的更多信息中所述。
#!/bin/bash
cat > /etc/nginx/conf.d/elasticbeanstalk/test.conf << LIMIT_STRING
location /test/ {
default_type text/html
return 200 "nginx variable: \$host, and EB env property: $MASTER_DOMAIN";
}
LIMIT_STRING
systemctl restart nginx.service
或者,我們可以在.platform/hooks/predeploy
中創建一個 shell 腳本,該腳本寫入/var/proxy/staging/nginx/conf.d/proxy.conf
。
在這種情況下不需要重新啟動 nginx 服務,因為這個鈎子是在應用服務器配置之前執行的。
謹防:
不確定這是錯誤還是設計特性,但我們新創建的proxy.conf
在配置部署(與應用程序部署相反)后消失,除非我們將重復的腳本放在.platform/confighooks/postdeploy
目錄中。 不是很干...
編輯:AWS 支持人員確認在這種情況下我們需要hooks
和confighooks
掛鈎中的重復腳本。 文檔中的應用示例還在hooks
和confighooks
中顯示了一些重復項(至少是重復的文件名)。
編輯:除了復制腳本,我們還可以編寫一個調用鈎子的配置鈎子,例如.platform/confighooks/predeploy/01_my_confighook.sh
可能如下所示:
#!/bin/bash
source "/var/app/current/.platform/hooks/predeploy/01_my_hook.sh"
免責聲明:這是在新創建的單實例EB 環境中測試的,“Python 3.7 在 64 位亞馬遜 Linux 2/3.1.5 上運行”,使用所有默認配置和默認 AWS Python 示例應用程序(僅使用我們的自定義掛鈎進行擴展)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.