Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions Documentation/configuration/project-definition/container.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ deployment:
type: container
settings:
expose:
port: 80
service: app
- internal_port: 80
external_port: 80
service: app
services:
- name: app
image: nginxdemos/hello:latest
Expand All @@ -39,10 +40,22 @@ In the example above, Nginx will proxy web requests to the "app" container's por

Name of the Container service to receive the web request.

### port
### internal_port

Port of the given container service to receive the web request.

### external_port

Port that Nginx listens to.

:::caution
Setting _external_port_ to 443 is not allowed, as HTTPS forwarding is automatically enabled for exposes with `external_port=80`.
:::

:::note
Make sure to define the different _external_port_ within one project definition, so that each port is only used once!
:::

## services

The following configuration options are available inside a service definition:
Expand Down
5 changes: 3 additions & 2 deletions Documentation/introduction/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ deployment:
type: container
settings:
expose:
service: app
port: 80
- service: app
external_port: 80
internal_port: 80
services:
- name: app
image: nginxdemos/hello:latest
Expand Down
17 changes: 15 additions & 2 deletions ansible/__tests__/projects/container.dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ deployment:
type: container
settings:
expose:
service: nginx
port: 80
- service: nginx
internal_port: 80
external_port: 80
- service: pma
internal_port: 80
external_port: 81
services:
- name: data
image: getstackhead/project-demo-php:data-latest
Expand All @@ -21,3 +25,12 @@ deployment:
image: mariadb:10.5
environment:
MYSQL_ROOT_PASSWORD: example
- name: pma
image: phpmyadmin/phpmyadmin:latest
environment:
PMA_ARBITRARY: 1
MYSQL_ROOT_PASSWORD: example
volumes:
- type: local
src: sessions
dest: /sessions
8 changes: 7 additions & 1 deletion ansible/__tests__/steps/test_deploy-container.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ INVENTORY_PATH=ansible/__tests__/inventory.yml
sed -e "s/\${ipaddress}/${IP}/" -e "s/\${application}/container/" ansible/__tests__/inventory.dist.yml > ansible/__tests__/inventory.yml
sed -e "s/\${domain}/${DOMAIN}/" ansible/__tests__/projects/container.dist.yml > ansible/__tests__/projects/container.yml
TEST=1 ansible-playbook ansible/application-deploy.yml -i $INVENTORY_PATH -vv
content=$(wget --no-check-certificate --https-only -q -O - ${DOMAIN})
content=$(wget --no-check-certificate --https-only -q -O - https://${DOMAIN})
if [[ $content != *"Hello world!"* ]]; then
echo "HTTP content check on container project failed" 1>&2
exit 1
fi
# test that phpmyadmin is available
content=$(wget --no-check-certificate --https-only -q -O - https://${DOMAIN}:81)
if [[ $content != *"phpMyAdmin"* ]]; then
echo "HTTP content check on phpmyadmin in container project failed" 1>&2
exit 1
fi
TEST=1 ansible-playbook ansible/application-destroy.yml -i $INVENTORY_PATH --extra-vars "project_name=container" -vv
2 changes: 1 addition & 1 deletion ansible/__tests__/steps/test_deploy-native.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ INVENTORY_PATH=ansible/__tests__/inventory.yml
sed -e "s/\${ipaddress}/${IP}/" -e "s/\${application}/native/" ansible/__tests__/inventory.dist.yml > ansible/__tests__/inventory.yml
sed -e "s/\${domain}/${DOMAIN}/" ansible/__tests__/projects/native.dist.yml > ansible/__tests__/projects/native.yml
TEST=1 ansible-playbook ansible/application-deploy.yml -i $INVENTORY_PATH -vv
content=$(wget --no-check-certificate --http-user=user --http-password=pass --https-only -q -O - ${DOMAIN})
content=$(wget --no-check-certificate --http-user=user --http-password=pass --https-only -q -O - https://${DOMAIN})
if [[ $content != *"This website was provisioned by StackHead"* ]]; then
echo "HTTP content check on container project failed" 1>&2
exit 1
Expand Down
57 changes: 45 additions & 12 deletions ansible/__tests__/test-tf-generation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,56 @@
- hosts: localhost
connection: local
tasks:
- name: Generate nginx vhost Terraform file
- include_vars: "{{ playbook_dir }}/../config.yaml"
- set_fact:
stackhead__templates: "{{ playbook_dir }}/../templates"
- name: Generate nginx native Terraform file
template:
src: "../templates/terraform/nginx_server_block.tf.j2"
dest: "./nginx_vhost.tf"
src: "{{ stackhead__templates }}/terraform/nginx_server_block.tf.j2"
dest: "./nginx_vhost-native.tf"
force: true
vars:
nginx_dockerapp: 1
stackhead__acme_folder: ""
stackhead__certificates_folder: ""
project_name: test
resource_name: "{{ project_name }}"
app_config:
domain: example.com
nginx_htpasswd_path: /etc/nginx/passwd
nginx_basicauth_title: "Restricted area"
nginx_auth_basic:
- type: basic
username: user1
password: pass1
nginx_vhost:
server_name: "example.com"
use_https: 1
proxy_pass_port: "123"
state: present
filename: "example_com.conf"
root_path: "/var/www/project/htdocs"
- name: Generate nginx container Terraform file
template:
src: "{{ stackhead__templates }}/terraform/nginx_server_block_docker.tf.j2"
dest: "./nginx_vhost-container.tf"
force: true
vars:
nginx_dockerapp: 1
stackhead__acme_folder: ""
stackhead__certificates_folder: ""
nginx_vhost_content: "{{ lookup('template', nginx_vhost_template) }}"
project_name: test
containerapp__expose:
service: test
- service: test2
internal_port: 5000
external_port: 5000
- service: test
internal_port: 80
external_port: 80
resource_name: "{{ project_name }}"
app_config:
domain: example.com
nginx_htpasswd_path: /etc/nginx/passwd
nginx_vhost_template: "{{ playbook_dir }}/../templates/nginx-vhost.reverse-proxy.j2"
nginx_basicauth_title: "Restricted area"
nginx_auth_basic:
- type: basic
Expand All @@ -33,7 +65,7 @@
filename: "example_com.conf"
- name: "Test SSL Terraform file generation"
template:
src: "../templates/terraform/ssl-certificate.tf.j2"
src: "{{ stackhead__templates }}/terraform/ssl-certificate.tf.j2"
dest: "./ssl-certificate.tf"
vars:
app_config:
Expand All @@ -44,7 +76,7 @@
stackhead__tf_project_folder: "/stackhead-root/projects/test/terraform"
- name: "Test Docker Terraform file generation"
template:
src: "../templates/terraform/docker.tf.j2"
src: "{{ stackhead__templates }}/terraform/docker.tf.j2"
dest: "./docker.tf"
vars:
containerapp__project_name: test
Expand All @@ -57,15 +89,18 @@
containerapp__data_location_global: "/docker/global/%s"
containerapp__data_location_services: "/docker/services/%s/%s"
containerapp__expose:
service: nginx
port: 80
- service: php
internal_port: 3000
- service: nginx
internal_port: 80
containerapp__services:
- name: data
image: mycontainer:latest
- name: nginx
image: getstackhead/nginx:php
environment:
NGINX_PUBLIC_DIRECTORY: public
DOCKER_PROXY_SERVICE_NAME: "$DOCKER_SERVICE_NAME['php']"
volumes:
- type: global
src: data
Expand All @@ -75,8 +110,6 @@
src: uploads
dest: /var/www/public/uploads
mode: ro
environment:
DOCKER_PROXY_SERVICE_NAME: "$DOCKER_SERVICE_NAME['php']"
volumes_from:
- data:ro
- name: php
Expand Down
1 change: 1 addition & 0 deletions ansible/config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Global variable configurations accessible by all roles
---
stackhead__templates: "{{ playbook_dir }}/templates"
stackhead__root_folder: "/stackhead"
stackhead__bin_location: "{{ stackhead__root_folder }}/bin"
stackhead__acme_folder: "{{ stackhead__root_folder }}/acme-challenges"
Expand Down
2 changes: 2 additions & 0 deletions ansible/filter_plugins/tfreplace.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def filters(self):
}

def tf_replace(self, text, project_name):
if not isinstance(text, str):
return text
# Replace Docker service name variables
docker_service = re.compile(r'\$DOCKER_SERVICE_NAME\[\'(.*)\'\]')
text = docker_service.sub("${docker_container.stackhead-" + project_name + "-\\1.name}", text)
Expand Down
3 changes: 1 addition & 2 deletions ansible/roles/config_nginx/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
---
nginx_vhost_template: "{{ playbook_dir }}/templates/nginx-vhost.j2"
nginx_tf_template: "{{ playbook_dir }}/templates/terraform/nginx_server_block.tf.j2"
nginx_tf_template: "{{ stackhead__templates }}/terraform/nginx_server_block.tf.j2"
nginx_basicauth_title: "Restricted area"
nginx_dockerapp: 0
3 changes: 1 addition & 2 deletions ansible/roles/config_nginx/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

- name: Generate htpasswd Terraform file
template:
src: "templates/terraform/htpasswd.tf.j2"
src: "{{ stackhead__templates }}/terraform/htpasswd.tf.j2"
dest: "{{ stackhead__tf_project_folder }}/htpasswd.tf"
force: true
when: has_basic_auth
Expand All @@ -20,6 +20,5 @@
dest: "{{ stackhead__tf_project_folder }}/nginx_server_block.tf"
force: true
vars:
nginx_vhost_content: "{{ lookup('template', nginx_vhost_template) }}"
resource_name: "{{ project_name }}"

45 changes: 44 additions & 1 deletion ansible/roles/project_containerapp/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@
---
- name: "StackHead::Container || Build src folder list || Project: {{ containerapp__project_name }}"
block:
- name: "Collect local volumes"
set_fact:
managedContainerVolumePaths: "{{ managedContainerVolumePaths|default([]) + [ ''~ containerapp__data_location_services|format(item.0.name, item.1.src|default()) ~'' ] }}"
when: item.1.type == 'local'
with_subelements:
- "{{ containerapp__services }}"
- volumes
- flags:
skip_missing: True
- name: "Collect global volumes"
set_fact:
managedContainerVolumePaths: "{{ managedContainerVolumePaths|default([]) + [ '' ~ containerapp__data_location_global|format(item.1.src|default()) ~ '' ] }}"
when: item.1.type == 'global'
with_subelements:
- "{{ containerapp__services }}"
- volumes
- flags:
skip_missing: True
- name: "Collect custom volumes"
set_fact:
managedContainerVolumePaths: "{{ managedContainerVolumePaths|default([]) + [ '' ~ item.1.src ~ '' ] }}"
when: item.1.type == 'custom'
with_subelements:
- "{{ containerapp__services }}"
- volumes
- flags:
skip_missing: True
- block:
- name: "StackHead::Container || Checking volume folders"
stat:
path: "{{ item }}"
register: folder_stats
with_items: "{{ managedContainerVolumePaths }}"
- name: "StackHead::Container || Creating missing volume folders"
file:
path: "{{ item.item }}"
state: directory
mode: 0755
when: item.stat.exists == false
with_items: "{{ folder_stats.results }}"
when: managedContainerVolumePaths is defined
- name: "StackHead::Container || Generate Terraform Docker configuration file | Project: {{ containerapp__project_name }}"
template:
src: "templates/terraform/docker.tf.j2"
src: "{{ stackhead__templates }}/terraform/docker.tf.j2"
dest: "{{ stackhead__tf_project_folder }}/docker.tf"
force: true
2 changes: 1 addition & 1 deletion ansible/roles/project_nativeapp/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ nativeapp__project_name:
nativeapp__remote_path: "/var/www/{{ nativeapp__project_name }}"
nativeapp__public_path: "htdocs"
nativeapp__default_content: true
nativeapp__default_page: "templates/nativeapp-default.html.j2"
nativeapp__default_page: "{{ stackhead__templates }}/nativeapp-default.html.j2"
nativeapp__remote_public_fullpath: "{{ nativeapp__remote_path }}/{{ nativeapp__public_path }}"
3 changes: 1 addition & 2 deletions ansible/roles/stackhead_project/tasks/setup-containerapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
name: config_nginx
vars:
nginx_dockerapp: 1
nginx_vhost_template: "{{ playbook_dir }}/templates/nginx-vhost.reverse-proxy.j2"
nginx_tf_template: "{{ playbook_dir }}/templates/terraform/nginx_server_block_docker.tf.j2"
nginx_tf_template: "{{ stackhead__templates }}/terraform/nginx_server_block_docker.tf.j2"
nginx_auth_basic: "{{ app_config.security.authentication|default([]) }}"
nginx_vhost:
server_name: "{{ app_config.domain }}"
Expand Down
1 change: 0 additions & 1 deletion ansible/roles/stackhead_project/tasks/setup-nativeapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
include_role:
name: config_nginx
vars:
nginx_vhost_template: "{{ playbook_dir }}/templates/nginx-vhost.native.j2"
nginx_auth_basic: "{{ app_config.security.authentication|default([]) }}"
nginx_use_php: "{{ native_php_enabled }}"
nginx_vhost:
Expand Down
4 changes: 2 additions & 2 deletions ansible/roles/stackhead_project/tasks/ssl/ssl-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
# Create certificate files and remove Nginx configuration for ACME confirmation
- name: "Generate wrapper executable for environment variable"
template:
src: "templates/acme_challenge_resolver.sh.j2"
src: "{{ stackhead__templates }}/acme_challenge_resolver.sh.j2"
dest: "{{ stackhead__tf_project_folder }}/acme_challenge_resolver.sh"
mode: 0755
- name: "Generate Terraform SSL configuration file"
template:
src: "templates/terraform/ssl-certificate.tf.j2"
src: "{{ stackhead__templates }}/terraform/ssl-certificate.tf.j2"
dest: "{{ stackhead__tf_project_folder }}/ssl-certificate.tf"
force: true
vars:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
# Set up basic nginx that can handle ACME requests
- name: Generate nginx ACME challenge configuration Terraform file
template:
src: "templates/terraform/nginx_server_block.tf.j2"
src: "{{ stackhead__templates }}/terraform/nginx_server_block.tf.j2"
dest: "{{ stackhead__tf_project_folder }}/nginx_server_block-acme.tf"
force: true
vars:
nginx_dockerapp: 0
nginx_vhost_content: "{{ lookup('template', playbook_dir ~ '/templates/nginx-vhost.acmechallenge.j2') }}"
resource_name: "__acme-{{ project_name }}"
nginx_vhost:
server_name: "{{ app_config.domain }}"
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/stackhead_setup/tasks/setup-nginx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
- name: Setup Nginx
vars:
nginx_ppa_use: true
nginx_conf_template: "{{ playbook_dir }}/templates/nginx.conf.j2"
nginx_conf_template: "{{ stackhead__templates }}/nginx.conf.j2"
nginx_vhosts: []
__nginx_user: "stackhead"
root_group: "stackhead"
Expand Down
4 changes: 2 additions & 2 deletions ansible/roles/stackhead_setup/tasks/setup-terraform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
name: andrewrothstein.terraform
- name: Download Nginx provider
get_url:
url: https://github.com/getstackhead/terraform-nginx/releases/download/v1.2.0/terraform-provider-nginx
url: https://github.com/getstackhead/terraform-nginx/releases/download/v1.3.0/terraform-provider-nginx
dest: "{{ terraform_plugin_directory }}/terraform-provider-nginx"
mode: '0755'
owner: stackhead
Expand All @@ -31,5 +31,5 @@
force: yes
- name: Create Terraform provider configurations
template:
src: "templates/terraform/terraform-providers.tf.j2"
src: "{{ stackhead__templates }}/terraform/terraform-providers.tf.j2"
dest: "{{ stackhead__tf_root_folder }}/terraform-providers.tf"
4 changes: 0 additions & 4 deletions ansible/templates/nginx-vhost.acmechallenge.j2

This file was deleted.

Loading