From d90099d4e20d50170403f64cfbf67336fdd6a79a Mon Sep 17 00:00:00 2001 From: Phil Moore Date: Thu, 8 Feb 2024 09:35:46 -0500 Subject: [PATCH 01/43] use v0.12.0 k8s-hosting-services --- deploy/requirements.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/requirements.yml b/deploy/requirements.yml index f8b2b98f..eb0578ab 100644 --- a/deploy/requirements.yml +++ b/deploy/requirements.yml @@ -11,4 +11,4 @@ version: v1.6.0 - src: https://github.com/caktus/ansible-role-k8s-hosting-services name: caktus.k8s-hosting-services - version: v0.11.0 + version: v0.12.0 From ba290b9b61fbae9ba3e73be8da89a6283a4647a5 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 14 May 2024 10:34:30 -0400 Subject: [PATCH 02/43] Update deployment reqs, ingress nginx, cert manager, and cloudwatch metrics chart version --- deploy/group_vars/all.yml | 6 +++--- deploy/requirements.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index 9c483ae7..55d4e1d3 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -78,8 +78,8 @@ cloudformation_stack: k8s_cluster_type: aws # aws eks describe-cluster --name=philly-hip-stack-cluster --query 'cluster.arn' k8s_context: "arn:aws:eks:us-east-1:061553509755:cluster/{{ cluster_name }}" -k8s_ingress_nginx_chart_version: "4.6.0" -k8s_cert_manager_chart_version: "v1.11.1" +k8s_ingress_nginx_chart_version: "4.9.1" +k8s_cert_manager_chart_version: "v1.14.3" k8s_letsencrypt_email: admin@caktusgroup.com k8s_iam_users: [noop] # https://github.com/caktus/ansible-role-k8s-web-cluster/issues/17 # aws-for-fluent-bit @@ -89,7 +89,7 @@ k8s_aws_fluent_bit_chart_version: "0.1.18" # aws-cloudwatch-metrics: # - https://github.com/aws/eks-charts/tree/master/stable/aws-cloudwatch-metrics # - https://artifacthub.io/packages/helm/aws/aws-cloudwatch-metrics -k8s_aws_cloudwatch_metrics_chart_version: "0.0.9" +k8s_aws_cloudwatch_metrics_chart_version: "0.0.11" k8s_aws_cloudwatch_metrics_namespace: amazon-cloudwatch # ---------------------------------------------------------------------------- diff --git a/deploy/requirements.yml b/deploy/requirements.yml index f8b2b98f..74f3d99d 100644 --- a/deploy/requirements.yml +++ b/deploy/requirements.yml @@ -2,13 +2,13 @@ - src: https://github.com/caktus/ansible-role-aws-web-stacks name: caktus.aws-web-stacks - src: https://github.com/caktus/ansible-role-k8s-web-cluster - version: v1.5.0 + version: v1.6.0 name: caktus.k8s-web-cluster # Note: caktus.django-k8s version 1.4.0 has been released, but deploys fail due to issue: # msg: Failed to find exact match for rabbitmq.com/v1beta1.RabbitmqCluster by [kind, name, singularName, shortNames] - src: https://github.com/caktus/ansible-role-django-k8s name: caktus.django-k8s - version: v1.6.0 + version: v1.9.0 - src: https://github.com/caktus/ansible-role-k8s-hosting-services name: caktus.k8s-hosting-services - version: v0.11.0 + version: v0.12.0 From 0468c5bcfe8f2262ef14e98e59b105635aa9c8c4 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 14 May 2024 13:52:01 -0400 Subject: [PATCH 03/43] Update descheduler to latest version --- deploy/group_vars/all.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index 55d4e1d3..8aea2ff5 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -211,7 +211,7 @@ k8s_install_descheduler: yes # You must set the k8s_descheduler_chart_version to match the Kubernetes # node version (0.23.x -> K8s 1.23.x); see: # https://github.com/kubernetes-sigs/descheduler#compatibility-matrix -k8s_descheduler_chart_version: v0.25.2 +k8s_descheduler_chart_version: v0.29.0 # See values.yaml for options: # https://github.com/kubernetes-sigs/descheduler/blob/master/charts/descheduler/values.yaml#L63 k8s_descheduler_release_values: From dca238728906419cb9c0e4d14e4e992a70abd8b8 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 14 May 2024 18:13:50 +0000 Subject: [PATCH 04/43] Update docker k8s and python dependencies --- Dockerfile | 4 ++-- requirements/base/base.in | 4 ++-- requirements/base/base.txt | 6 ++--- requirements/dev/dev.in | 10 ++++----- requirements/dev/dev.txt | 45 ++++++++++++++++++++++++-------------- 5 files changed, 41 insertions(+), 28 deletions(-) diff --git a/Dockerfile b/Dockerfile index 286cd651..5f56ebd7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -121,8 +121,8 @@ RUN groupadd --gid $USER_GID $USERNAME \ # openssh-client -- for git over SSH # sudo -- to run commands as superuser # vim -- enhanced vi editor for commits -ENV KUBE_CLIENT_VERSION="v1.25.10" -ENV HELM_VERSION="3.12.0" +ENV KUBE_CLIENT_VERSION="v1.29.3" +ENV HELM_VERSION="3.14.4" RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt \ --mount=type=cache,mode=0755,target=/root/.cache/pip \ set -ex \ diff --git a/requirements/base/base.in b/requirements/base/base.in index 99d819cd..38cd03f8 100644 --- a/requirements/base/base.in +++ b/requirements/base/base.in @@ -18,8 +18,8 @@ django-sass-processor django-phonenumber-field django-honeypot whitenoise -boto3==1.28.4 -botocore==1.31.4 +boto3==1.34.104 +botocore==1.34.104 libsass phonenumberslite pdfid diff --git a/requirements/base/base.txt b/requirements/base/base.txt index e0ad15ad..f2a83197 100644 --- a/requirements/base/base.txt +++ b/requirements/base/base.txt @@ -10,9 +10,9 @@ asgiref==3.3.4 # via django beautifulsoup4==4.8.2 # via wagtail -boto3==1.28.4 +boto3==1.34.104 # via -r requirements/base/base.in -botocore==1.31.4 +botocore==1.34.104 # via # -r requirements/base/base.in # boto3 @@ -152,7 +152,7 @@ requests-oauthlib==1.3.0 # via social-auth-core rjsmin==1.1.0 # via django-compressor -s3transfer==0.6.1 +s3transfer==0.10.1 # via boto3 six==1.15.0 # via diff --git a/requirements/dev/dev.in b/requirements/dev/dev.in index 651bcc2d..ca13b19b 100644 --- a/requirements/dev/dev.in +++ b/requirements/dev/dev.in @@ -2,22 +2,22 @@ -c ../base/base.txt pyyaml==6.0.1 -black==22.6.0 +black==24.4.2 isort ipython jupyterlab # deploy -ansible==7.6.0 +ansible==9.5.1 invoke-kubesae==0.1.0 # AWS tools -awscli==1.29.4 +awscli==1.32.104 awslogs Jinja2==3.0.3 -openshift==0.12 +openshift==0.13.2 kubernetes==12.0.0 -kubernetes-validate~=1.25.0 +kubernetes-validate~=1.29.1 pre-commit coverage diff --git a/requirements/dev/dev.txt b/requirements/dev/dev.txt index 132f09f2..34f6c3f9 100644 --- a/requirements/dev/dev.txt +++ b/requirements/dev/dev.txt @@ -4,11 +4,11 @@ # # pip-compile --output-file=requirements/dev/dev.txt requirements/dev/dev.in # -ansible==7.6.0 +ansible==9.5.1 # via # -r requirements/dev/dev.in # invoke-kubesae -ansible-core==2.14.6 +ansible-core==2.16.6 # via ansible anyascii==0.1.7 # via @@ -30,7 +30,8 @@ attrs==20.3.0 # via # jsonschema # pytest -awscli==1.29.4 + # referencing +awscli==1.32.104 # via -r requirements/dev/dev.in awslogs==0.14.0 # via -r requirements/dev/dev.in @@ -42,16 +43,16 @@ beautifulsoup4==4.8.2 # via # -c requirements/dev/../base/base.txt # wagtail -black==22.6.0 +black==24.4.2 # via -r requirements/dev/dev.in bleach==3.3.0 # via nbconvert -boto3==1.28.4 +boto3==1.34.104 # via # -c requirements/dev/../base/base.txt # awslogs # invoke-kubesae -botocore==1.31.4 +botocore==1.34.104 # via # -c requirements/dev/../base/base.txt # awscli @@ -170,8 +171,11 @@ idna==2.10 # -c requirements/dev/../base/base.txt # anyio # requests + # yarl importlib-metadata==5.0.0 # via -r requirements/dev/dev.in +importlib-resources==6.4.0 + # via kubernetes-validate inflection==0.5.1 # via pytest-factoryboy iniconfig==1.1.1 @@ -206,7 +210,6 @@ jinja2==3.0.3 # jupyterlab-server # nbconvert # notebook - # openshift jmespath==0.10.0 # via # -c requirements/dev/../base/base.txt @@ -249,7 +252,7 @@ kubernetes==12.0.0 # via # -r requirements/dev/dev.in # openshift -kubernetes-validate==1.25.2 +kubernetes-validate==1.29.1 # via -r requirements/dev/dev.in l18n==2020.6.1 # via @@ -261,6 +264,8 @@ mccabe==0.7.0 # via flake8 mistune==0.8.4 # via nbconvert +multidict==6.0.5 + # via yarl mypy-extensions==0.4.3 # via black nbclassic==0.2.6 @@ -291,14 +296,16 @@ openpyxl==3.1.2 # via # -c requirements/dev/../base/base.txt # wagtail -openshift==0.12.0 +openshift==0.13.2 # via -r requirements/dev/dev.in -packaging==20.9 +packaging==24.0 # via # ansible-core + # black # bleach # jupyterlab # jupyterlab-server + # kubernetes-validate # pytest pandocfilters==1.4.3 # via nbconvert @@ -356,10 +363,10 @@ pygments==2.8.0 # jupyterlab-pygments # nbconvert # pudb -pyparsing==2.4.7 - # via packaging pyrsistent==0.17.3 - # via jsonschema + # via + # jsonschema + # referencing pytest==7.1.3 # via # -r requirements/dev/dev.in @@ -406,6 +413,8 @@ pyzmq==22.0.3 # jupyter-client # jupyter-server # notebook +referencing==0.8.11 + # via kubernetes-validate requests==2.25.1 # via # -c requirements/dev/../base/base.txt @@ -423,9 +432,7 @@ rsa==4.5 # via # awscli # google-auth -ruamel-yaml==0.16.12 - # via openshift -s3transfer==0.6.1 +s3transfer==0.10.1 # via # -c requirements/dev/../base/base.txt # awscli @@ -495,6 +502,10 @@ traitlets==5.0.5 # nbconvert # nbformat # notebook +typing-extensions==4.11.0 + # via + # black + # kubernetes-validate urllib3==1.26.4 # via # -c requirements/dev/../base/base.txt @@ -524,6 +535,8 @@ willow==1.4 # via # -c requirements/dev/../base/base.txt # wagtail +yarl==1.9.4 + # via referencing zipp==3.4.0 # via importlib-metadata From f88235c7c7a8db3d7fe75954e91ad9535eea6218 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Mon, 20 May 2024 13:36:20 -0400 Subject: [PATCH 05/43] Update fluent bit, dependencies, and ansible references --- deploy/deploy-cluster.yml | 7 +- deploy/group_vars/all.yml | 2 +- requirements/dev/dev.txt | 323 +++++++++++++++++++++++--------------- 3 files changed, 201 insertions(+), 131 deletions(-) diff --git a/deploy/deploy-cluster.yml b/deploy/deploy-cluster.yml index 89bc100d..b0db5604 100644 --- a/deploy/deploy-cluster.yml +++ b/deploy/deploy-cluster.yml @@ -10,7 +10,7 @@ tasks: - name: Add AWS for fluent bit helm chart (centralized logging) tags: fluentbit - community.kubernetes.helm: + kubernetes.core.helm: context: "{{ k8s_context|mandatory }}" kubeconfig: "{{ k8s_kubeconfig }}" chart_repo_url: "https://aws.github.io/eks-charts" @@ -29,7 +29,7 @@ wait: yes - name: Create Amazon CloudWatch Metrics namespace tags: cloudwatch - community.kubernetes.k8s: + kubernetes.core.k8s: context: "{{ k8s_context|mandatory }}" kubeconfig: "{{ k8s_kubeconfig }}" name: "{{ k8s_aws_cloudwatch_metrics_namespace }}" @@ -38,7 +38,7 @@ state: present - name: Add AWS CloudWatch Metrics helm chart (monitoring) tags: cloudwatch - community.kubernetes.helm: + kubernetes.core.helm: context: "{{ k8s_context|mandatory }}" kubeconfig: "{{ k8s_kubeconfig }}" chart_repo_url: "https://aws.github.io/eks-charts" @@ -54,6 +54,7 @@ tags: cloudwatch amazon.aws.cloudwatch_metric_alarm: state: present + aws_profile: "{{ aws_profile }}" region: us-east-1 name: "{{ item.name }}" description: "{{ item.description }}" diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index 8aea2ff5..b5ccfcbf 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -85,7 +85,7 @@ k8s_iam_users: [noop] # https://github.com/caktus/ansible-role-k8s-web-cluster/ # aws-for-fluent-bit # - https://github.com/aws/eks-charts/tree/master/stable/aws-for-fluent-bit # - https://artifacthub.io/packages/helm/aws/aws-for-fluent-bit -k8s_aws_fluent_bit_chart_version: "0.1.18" +k8s_aws_fluent_bit_chart_version: "0.1.32" # aws-cloudwatch-metrics: # - https://github.com/aws/eks-charts/tree/master/stable/aws-cloudwatch-metrics # - https://artifacthub.io/packages/helm/aws/aws-cloudwatch-metrics diff --git a/requirements/dev/dev.txt b/requirements/dev/dev.txt index 34f6c3f9..e577f2a5 100644 --- a/requirements/dev/dev.txt +++ b/requirements/dev/dev.txt @@ -14,38 +14,41 @@ anyascii==0.1.7 # via # -c requirements/dev/../base/base.txt # wagtail -anyio==2.1.0 +anyio==3.7.1 # via jupyter-server -appnope==0.1.2 +appnope==0.1.4 # via -r requirements/dev/dev.in -argon2-cffi==20.1.0 - # via notebook +argon2-cffi==23.1.0 + # via + # jupyter-server + # nbclassic + # notebook +argon2-cffi-bindings==21.2.0 + # via argon2-cffi asgiref==3.3.4 # via # -c requirements/dev/../base/base.txt # django -async-generator==1.10 - # via nbclient -attrs==20.3.0 +asttokens==2.4.1 + # via stack-data +attrs==23.2.0 # via # jsonschema - # pytest # referencing awscli==1.32.104 # via -r requirements/dev/dev.in awslogs==0.14.0 # via -r requirements/dev/dev.in -babel==2.9.0 +babel==2.15.0 # via jupyterlab-server -backcall==0.2.0 - # via ipython beautifulsoup4==4.8.2 # via # -c requirements/dev/../base/base.txt + # nbconvert # wagtail black==24.4.2 # via -r requirements/dev/dev.in -bleach==3.3.0 +bleach==6.1.0 # via nbconvert boto3==1.34.104 # via @@ -58,7 +61,7 @@ botocore==1.34.104 # awscli # boto3 # s3transfer -cachetools==4.2.1 +cachetools==5.3.3 # via google-auth certifi==2020.12.5 # via @@ -68,21 +71,23 @@ certifi==2020.12.5 cffi==1.14.5 # via # -c requirements/dev/../base/base.txt - # argon2-cffi + # argon2-cffi-bindings # cryptography -cfgv==3.2.0 +cfgv==3.4.0 # via pre-commit chardet==4.0.0 # via # -c requirements/dev/../base/base.txt # requests -click==8.1.3 +click==8.1.7 # via black -colorama==0.4.3 +colorama==0.4.6 # via # awscli # invoke-kubesae -coverage==5.4 +comm==0.2.2 + # via ipykernel +coverage[toml]==7.5.1 # via # -r requirements/dev/dev.in # pytest-cov @@ -90,13 +95,15 @@ cryptography==3.4.7 # via # -c requirements/dev/../base/base.txt # ansible-core -decorator==4.4.2 +debugpy==1.8.1 + # via ipykernel +decorator==5.1.1 # via ipython defusedxml==0.7.1 # via # -c requirements/dev/../base/base.txt # nbconvert -distlib==0.3.6 +distlib==0.3.8 # via virtualenv django==3.2.23 # via @@ -109,7 +116,7 @@ django==3.2.23 # django-treebeard # djangorestframework # wagtail -django-debug-toolbar==3.7.0 +django-debug-toolbar==4.3.0 # via -r requirements/dev/dev.in django-filter==2.4.0 # via @@ -135,72 +142,84 @@ djangorestframework==3.12.2 # via # -c requirements/dev/../base/base.txt # wagtail -docutils==0.15.2 +docutils==0.16 # via awscli draftjs-exporter==2.1.7 # via # -c requirements/dev/../base/base.txt # wagtail -entrypoints==0.3 - # via nbconvert +entrypoints==0.4 + # via jupyter-client et-xmlfile==1.0.1 # via # -c requirements/dev/../base/base.txt # openpyxl -factory-boy==3.2.0 +exceptiongroup==1.2.1 + # via + # anyio + # ipython + # pytest +executing==2.0.1 + # via stack-data +factory-boy==3.3.0 # via # -r requirements/dev/dev.in # pytest-factoryboy # wagtail-factories -faker==15.3.2 +faker==25.2.0 # via factory-boy -filelock==3.8.1 +fastjsonschema==2.19.1 + # via nbformat +filelock==3.14.0 # via virtualenv -flake8==6.0.0 +flake8==7.0.0 # via -r requirements/dev/dev.in -google-auth==1.26.1 +google-auth==2.29.0 # via kubernetes html5lib==1.1 # via # -c requirements/dev/../base/base.txt # wagtail -identify==1.5.13 +identify==2.5.36 # via pre-commit idna==2.10 # via # -c requirements/dev/../base/base.txt # anyio + # httpx # requests - # yarl -importlib-metadata==5.0.0 +importlib-metadata==7.1.0 # via -r requirements/dev/dev.in importlib-resources==6.4.0 # via kubernetes-validate inflection==0.5.1 # via pytest-factoryboy -iniconfig==1.1.1 +iniconfig==2.0.0 # via pytest -invoke==1.5.0 +invoke==2.2.0 # via invoke-kubesae invoke-kubesae==0.1.0 # via -r requirements/dev/dev.in -ipykernel==5.4.3 - # via notebook -ipython==7.20.0 +ipykernel==6.29.4 + # via + # jupyterlab + # nbclassic + # notebook +ipython==8.24.0 # via # -r requirements/dev/dev.in # ipykernel # jupyterlab ipython-genutils==0.2.0 # via - # jupyter-server - # nbformat + # nbclassic # notebook - # traitlets -isort==5.7.0 +isort==5.13.2 # via -r requirements/dev/dev.in -jedi==0.18.0 - # via ipython +jedi==0.19.1 + # via + # ipython + # pudb jinja2==3.0.3 # via # -r requirements/dev/dev.in @@ -208,6 +227,7 @@ jinja2==3.0.3 # jupyter-server # jupyterlab # jupyterlab-server + # nbclassic # nbconvert # notebook jmespath==0.10.0 @@ -216,37 +236,44 @@ jmespath==0.10.0 # awslogs # boto3 # botocore -json5==0.9.5 +json5==0.9.25 # via jupyterlab-server -jsonschema==3.2.0 +jsonschema==4.22.0 # via # jupyterlab-server # kubernetes-validate # nbformat -jupyter-client==6.1.11 +jsonschema-specifications==2023.12.1 + # via jsonschema +jupyter-client==7.2.0 # via # ipykernel # jupyter-server + # nbclassic # nbclient # notebook -jupyter-core==4.7.1 +jupyter-core==5.7.2 # via + # ipykernel # jupyter-client # jupyter-server # jupyterlab + # nbclassic + # nbclient # nbconvert # nbformat # notebook -jupyter-server==1.3.0 +jupyter-server==1.24.0 # via # jupyterlab # jupyterlab-server # nbclassic -jupyterlab==3.0.7 + # notebook-shim +jupyterlab==3.5.3 # via -r requirements/dev/dev.in -jupyterlab-pygments==0.1.2 +jupyterlab-pygments==0.3.0 # via nbconvert -jupyterlab-server==2.2.1 +jupyterlab-server==2.16.3 # via jupyterlab kubernetes==12.0.0 # via @@ -258,36 +285,52 @@ l18n==2020.6.1 # via # -c requirements/dev/../base/base.txt # wagtail -markupsafe==2.1.1 - # via jinja2 +markupsafe==2.1.5 + # via + # jinja2 + # nbconvert +matplotlib-inline==0.1.7 + # via + # ipykernel + # ipython mccabe==0.7.0 # via flake8 -mistune==0.8.4 +mistune==3.0.2 # via nbconvert -multidict==6.0.5 - # via yarl -mypy-extensions==0.4.3 +mypy-extensions==1.0.0 # via black -nbclassic==0.2.6 - # via jupyterlab -nbclient==0.5.2 +nbclassic==1.0.0 + # via + # jupyterlab + # notebook +nbclient==0.10.0 # via nbconvert -nbconvert==6.0.7 +nbconvert==7.16.4 # via # jupyter-server + # nbclassic # notebook -nbformat==5.1.2 +nbformat==5.10.4 # via # jupyter-server + # nbclassic # nbclient # nbconvert # notebook -nest-asyncio==1.5.1 - # via nbclient -nodeenv==1.5.0 +nest-asyncio==1.6.0 + # via + # ipykernel + # jupyter-client + # nbclassic + # notebook +nodeenv==1.8.0 # via pre-commit -notebook==6.2.0 - # via nbclassic +notebook==6.5.7 + # via jupyterlab +notebook-shim==0.2.4 + # via + # jupyterlab + # nbclassic oauthlib==3.1.0 # via # -c requirements/dev/../base/base.txt @@ -302,85 +345,86 @@ packaging==24.0 # via # ansible-core # black - # bleach + # ipykernel + # jupyter-server # jupyterlab # jupyterlab-server # kubernetes-validate + # nbconvert + # pudb # pytest -pandocfilters==1.4.3 + # pytest-factoryboy +pandocfilters==1.5.1 # via nbconvert -parso==0.8.1 +parso==0.8.4 # via jedi -pathspec==0.9.0 +pathspec==0.12.1 # via black -pexpect==4.8.0 - # via ipython -pickleshare==0.7.5 +pexpect==4.9.0 # via ipython pillow==9.3.0 # via # -c requirements/dev/../base/base.txt # wagtail -platformdirs==2.5.2 +platformdirs==4.2.2 # via # black + # jupyter-core # virtualenv -pluggy==0.13.1 +pluggy==1.5.0 # via pytest -pre-commit==2.20.0 +pre-commit==3.7.1 # via -r requirements/dev/dev.in -prometheus-client==0.9.0 +prometheus-client==0.20.0 # via # jupyter-server + # nbclassic # notebook -prompt-toolkit==3.0.16 +prompt-toolkit==3.0.43 # via ipython +psutil==5.9.8 + # via ipykernel ptyprocess==0.7.0 # via # pexpect # terminado -pudb==2020.1 +pudb==2024.1 # via -r requirements/dev/dev.in -py==1.10.0 - # via pytest -pyasn1==0.4.8 +pure-eval==0.2.2 + # via stack-data +pyasn1==0.6.0 # via # pyasn1-modules # rsa -pyasn1-modules==0.2.8 +pyasn1-modules==0.4.0 # via google-auth -pycodestyle==2.10.0 +pycodestyle==2.11.1 # via flake8 pycparser==2.20 # via # -c requirements/dev/../base/base.txt # cffi -pyflakes==3.0.1 +pyflakes==3.2.0 # via flake8 -pygments==2.8.0 +pygments==2.18.0 # via # ipython - # jupyterlab-pygments # nbconvert # pudb -pyrsistent==0.17.3 - # via - # jsonschema - # referencing -pytest==7.1.3 +pytest==8.2.1 # via # -r requirements/dev/dev.in # pytest-cov # pytest-django # pytest-factoryboy # pytest-mock -pytest-cov==2.11.1 +pytest-cov==5.0.0 # via -r requirements/dev/dev.in -pytest-django==4.1.0 +pytest-django==4.8.0 # via -r requirements/dev/dev.in -pytest-factoryboy==2.1.0 +pytest-factoryboy==2.7.0 # via -r requirements/dev/dev.in -pytest-mock==3.5.1 +pytest-mock==3.14.0 # via -r requirements/dev/dev.in python-dateutil==2.8.1 # via @@ -395,7 +439,6 @@ python-string-utils==1.0.0 pytz==2021.1 # via # -c requirements/dev/../base/base.txt - # babel # django # django-modelcluster # l18n @@ -408,13 +451,18 @@ pyyaml==6.0.1 # kubernetes # kubernetes-validate # pre-commit -pyzmq==22.0.3 +pyzmq==26.0.3 # via + # ipykernel # jupyter-client # jupyter-server + # nbclassic # notebook -referencing==0.8.11 - # via kubernetes-validate +referencing==0.35.1 + # via + # jsonschema + # jsonschema-specifications + # kubernetes-validate requests==2.25.1 # via # -c requirements/dev/../base/base.txt @@ -426,9 +474,13 @@ requests-oauthlib==1.3.0 # via # -c requirements/dev/../base/base.txt # kubernetes -resolvelib==0.5.4 +resolvelib==1.0.1 # via ansible-core -rsa==4.5 +rpds-py==0.18.1 + # via + # jsonschema + # referencing +rsa==4.7.2 # via # awscli # google-auth @@ -437,25 +489,25 @@ s3transfer==0.10.1 # -c requirements/dev/../base/base.txt # awscli # boto3 -send2trash==1.5.0 +send2trash==1.8.3 # via # jupyter-server + # nbclassic # notebook six==1.15.0 # via # -c requirements/dev/../base/base.txt - # argon2-cffi + # asttokens # bleach - # google-auth # html5lib - # jsonschema # kubernetes # l18n # openshift # python-dateutil - # websocket-client -sniffio==1.2.0 - # via anyio +sniffio==1.3.1 + # via + # anyio + # httpx soupsieve==2.2 # via # -c requirements/dev/../base/base.txt @@ -465,39 +517,46 @@ sqlparse==0.4.1 # -c requirements/dev/../base/base.txt # django # django-debug-toolbar +stack-data==0.6.3 + # via ipython telepath==0.2 # via # -c requirements/dev/../base/base.txt # wagtail -termcolor==1.1.0 +termcolor==2.4.0 # via awslogs -terminado==0.9.2 +terminado==0.18.1 # via # jupyter-server + # nbclassic # notebook -testpath==0.4.4 +tinycss2==1.3.0 # via nbconvert -toml==0.10.2 - # via pre-commit tomli==2.0.1 # via # black + # coverage + # jupyterlab # pytest -tornado==6.1 +tornado==6.4 # via # ipykernel # jupyter-client # jupyter-server # jupyterlab + # nbclassic # notebook # terminado -traitlets==5.0.5 +traitlets==5.14.3 # via + # comm # ipykernel # ipython # jupyter-client # jupyter-core # jupyter-server + # matplotlib-inline + # nbclassic # nbclient # nbconvert # nbformat @@ -505,39 +564,49 @@ traitlets==5.0.5 typing-extensions==4.11.0 # via # black + # ipython # kubernetes-validate + # pytest-factoryboy + # urwid urllib3==1.26.4 # via # -c requirements/dev/../base/base.txt # botocore # kubernetes # requests -urwid==2.1.2 +urwid==2.6.12 + # via + # pudb + # urwid-readline +urwid-readline==0.14 # via pudb -virtualenv==20.17.1 +virtualenv==20.26.2 # via pre-commit wagtail==4.2.2 # via # -c requirements/dev/../base/base.txt # wagtail-factories -wagtail-factories==2.0.1 +wagtail-factories==4.1.0 # via -r requirements/dev/dev.in -wcwidth==0.2.5 - # via prompt-toolkit +wcwidth==0.2.13 + # via + # prompt-toolkit + # urwid webencodings==0.5.1 # via # -c requirements/dev/../base/base.txt # bleach # html5lib -websocket-client==0.57.0 - # via kubernetes + # tinycss2 +websocket-client==1.8.0 + # via + # jupyter-server + # kubernetes willow==1.4 # via # -c requirements/dev/../base/base.txt # wagtail -yarl==1.9.4 - # via referencing -zipp==3.4.0 +zipp==3.18.2 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: From a12e1824e31024d60d1caac15affb5d5404b77a0 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 21 May 2024 13:48:56 +0000 Subject: [PATCH 06/43] Fix export data broken tests --- README.md | 2 +- apps/reports/tests/test_models.py | 57 ++++++++++++++++++------------- docker-compose.yml | 2 +- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 1327fe3f..83380247 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ These instructions assume that you will be working with dockerized services. First add the following line to your `.env` file: ```sh -(hip)$ echo "DATABASE_URL=postgres://postgres@127.0.0.1:5433/hip" >> .env +(hip)$ echo "DATABASE_URL=postgres://postgres@127.0.0.1:5432/hip" >> .env ``` The `docker-compose.yml` sets up environment variables in a file, ``.postgres``. diff --git a/apps/reports/tests/test_models.py b/apps/reports/tests/test_models.py index 061b7a17..ca69194a 100644 --- a/apps/reports/tests/test_models.py +++ b/apps/reports/tests/test_models.py @@ -84,23 +84,28 @@ def test_datareportslistpage_context_only_external_reports(db, rf): "last_updated": date(year=2021, month=1, day=1), "external": True, } + external_reports_data = [ + { + "type": "external_reports", # Block type + "value": { + "title": external_report_hiv["title"], + "url": external_report_hiv["url"], + "update_frequency": external_report_hiv["update_frequency"], + "last_updated": external_report_hiv["last_updated"], + }, + }, + { + "type": "external_reports", + "value": { + "title": external_report_hep_a["title"], + "url": external_report_hep_a["url"], + "update_frequency": external_report_hep_a["update_frequency"], + "last_updated": external_report_hep_a["last_updated"], + }, + }, + ] reports_list_page = DataReportListPageFactory( - external_reports__0__external_reports__title=external_report_hiv["title"], - external_reports__0__external_reports__url=external_report_hiv["url"], - external_reports__0__external_reports__update_frequency=external_report_hiv[ - "update_frequency" - ], - external_reports__0__external_reports__last_updated=external_report_hiv[ - "last_updated" - ], - external_reports__1__external_reports__title=external_report_hep_a["title"], - external_reports__1__external_reports__url=external_report_hep_a["url"], - external_reports__1__external_reports__update_frequency=external_report_hep_a[ - "update_frequency" - ], - external_reports__1__external_reports__last_updated=external_report_hep_a[ - "last_updated" - ], + external_reports=external_reports_data ) context = reports_list_page.get_context(rf.get("/someurl/")) @@ -127,15 +132,19 @@ def test_datareportslistpage_context_internal_and_external_reports(db, rf): "last_updated": "2021-01-01", "external": True, } + external_reports_data = [ + { + "type": "external_reports", + "value": { + "title": external_report_hiv["title"], + "url": external_report_hiv["url"], + "update_frequency": external_report_hiv["update_frequency"], + "last_updated": external_report_hiv["last_updated"], + }, + }, + ] reports_list_page = DataReportListPageFactory( - external_reports__0__external_reports__title=external_report_hiv["title"], - external_reports__0__external_reports__url=external_report_hiv["url"], - external_reports__0__external_reports__update_frequency=external_report_hiv[ - "update_frequency" - ], - external_reports__0__external_reports__last_updated=external_report_hiv[ - "last_updated" - ], + external_reports=external_reports_data ) # Create some internal reports (DataReportDetailPages) for the DataReportListPage. tuberculosis = DiseaseAndConditionDetailPageFactory(title="Tuberculosis") diff --git a/docker-compose.yml b/docker-compose.yml index ada29890..a9a2bf12 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -39,7 +39,7 @@ services: args: USER_UID: ${USER_UID:-1000} USER_GID: ${USER_GID:-1000} - command: ["sleep", "infinity"] + command: [ "sleep", "infinity" ] links: - db:db ports: From 42d6ad1f82a52867d4be0f2a49e5d4ee0c8b2fa3 Mon Sep 17 00:00:00 2001 From: Tobias McNulty Date: Wed, 19 Jun 2024 10:12:42 -0400 Subject: [PATCH 07/43] remove scheduled workflow, since GitHub disables it after long periods of no activity anyways --- .github/workflows/test.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dafab2e0..550ab85d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,9 +2,8 @@ name: Lint and Test code on: pull_request: - schedule: - # run once a week on early monday mornings - - cron: '22 2 * * 1' + push: + branches: [main, develop] jobs: test: From 7c793d5e4996edc6e3afe2c13f918a480f85418e Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 20 Jun 2024 14:19:21 +0000 Subject: [PATCH 08/43] Create a nat stack formation --- deploy/group_vars/all.yml | 2 +- deploy/stack/eks-nat.yml | 2360 +++++++++++++++++++++++++++++++++++++ 2 files changed, 2361 insertions(+), 1 deletion(-) create mode 100644 deploy/stack/eks-nat.yml diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index 9c483ae7..71587e9f 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -45,7 +45,7 @@ cloudformation_stack: region: "{{ aws_region }}" stack_name: "{{ stack_name }}" template_bucket: "aws-web-stacks-{{ app_name }}" - template_local_path: '{{ playbook_dir + "/stack/eks-no-nat.yml" }}' + template_local_path: '{{ playbook_dir + "/stack/eks-nat.yml" }}' create_changeset: true termination_protection: true diff --git a/deploy/stack/eks-nat.yml b/deploy/stack/eks-nat.yml new file mode 100644 index 00000000..8c940fab --- /dev/null +++ b/deploy/stack/eks-nat.yml @@ -0,0 +1,2360 @@ +# This Cloudformation stack template was generated by +# https://github.com/caktus/aws-web-stacks +# at 2021-03-10 21:34:32.220724 +# with parameters: +# USE_EKS = on +# USE_NAT_GATEWAY = on + +Conditions: + AssetsCloudFrontCertArnCondition: !Not + - !Equals + - !Ref 'AssetsCloudFrontCertArn' + - '' + AssetsCloudFrontDomainCondition: !Not + - !Equals + - !Ref 'AssetsCloudFrontDomain' + - '' + AssetsCreateCertificateCondition: !And + - !Not + - !Equals + - !Ref 'AssetsCloudFrontDomain' + - '' + - !Equals + - !Ref 'AWS::Region' + - us-east-1 + - !Equals + - !Ref 'AssetsCloudFrontCertArn' + - '' + AssetsUseCloudFrontCondition: !Equals + - !Ref 'AssetsUseCloudFront' + - 'true' + AuthTokenCondition: !Not + - !Equals + - !Ref 'RedisAuthToken' + - DO_NOT_CREATE_AUTH_TOKEN + BastionAMISet: !Not + - !Equals + - '' + - !Ref 'BastionAMI' + BastionDatabaseCondition: !And + - !Condition 'BastionTypeIsOpenVPNSet' + - !Condition 'DatabaseCondition' + BastionTypeAndAMISet: !And + - !Condition 'BastionTypeSet' + - !Condition 'BastionAMISet' + BastionTypeIsOpenVPNSet: !Equals + - OpenVPN + - !Ref 'BastionType' + BastionTypeIsSSHSet: !Equals + - SSH + - !Ref 'BastionType' + BastionTypeSet: !Not + - !Equals + - (none) + - !Ref 'BastionType' + CmkArnCondition: !Not + - !Equals + - !Ref 'CustomerManagedCmkArn' + - '' + DatabaseCondition: !Not + - !Equals + - !Ref 'DatabaseClass' + - (none) + DatabaseLoggingCondition: !Not + - !Equals + - !Join + - ',' + - !Ref 'DatabaseCloudWatchLogTypes' + - '' + DatabaseReplicationCondition: !And + - !Condition 'DatabaseCondition' + - !Equals + - !Ref 'DatabaseReplication' + - 'true' + EitherCacheCondition: !Or + - !Condition 'UsingMemcached' + - !Condition 'UsingRedis' + Elasticsearch: !Not + - !Equals + - !Ref 'ElasticsearchInstanceType' + - (none) + InGovCloudRegion: !Equals + - !Ref 'AWS::Region' + - us-gov-west-1 + NoAlternateDomains: !Equals + - !Join + - '' + - !Ref 'DomainNameAlternates' + - '' + RedisAutomaticFailoverCondition: !Equals + - !Ref 'RedisAutomaticFailover' + - 'true' + SecureRedisCondition: !And + - !Condition 'UsingRedis' + - !Condition 'UseAES256EncryptionCond' + UseAES256EncryptionCond: !Equals + - !Ref 'UseAES256Encryption' + - 'true' + UseSFTPServerCondition: !Equals + - !Ref 'UseSFTPServer' + - 'true' + UseSFTPWithKMSCondition: !And + - !Equals + - !Ref 'UseSFTPServer' + - 'true' + - !Condition 'UseAES256EncryptionCond' + - !Condition 'CmkArnCondition' + UseSFTPWithoutKMSCondition: !And + - !Equals + - !Ref 'UseSFTPServer' + - 'true' + - !Not + - !Condition 'CmkArnCondition' + UsingMemcached: !Not + - !Equals + - !Ref 'CacheNodeType' + - (none) + UsingRedis: !Not + - !Equals + - !Ref 'RedisNodeType' + - (none) +Mappings: + RdsEngineMap: + aurora: + Port: '3306' + mariadb: + Port: '3306' + mysql: + Port: '3306' + oracle-ee: + Port: '1521' + oracle-se: + Port: '1521' + oracle-se1: + Port: '1521' + oracle-se2: + Port: '1521' + postgres: + Port: '5432' + sqlserver-ee: + Port: '1433' + sqlserver-ex: + Port: '1433' + sqlserver-se: + Port: '1433' + sqlserver-web: + Port: '1433' +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Global + Parameters: + - UseAES256Encryption + - CustomerManagedCmkArn + - DomainName + - DomainNameAlternates + - PrimaryAZ + - SecondaryAZ + - VpcCidr + - PublicSubnetACidr + - PublicSubnetBCidr + - PrivateSubnetACidr + - PrivateSubnetBCidr + - Label: + default: Application Server + Parameters: + - AdministratorIPAddress + - DesiredScale + - MaxScale + - ContainerVolumeSize + - ContainerInstanceType + - Label: + default: Static Media + Parameters: + - AssetsBucketAccessControl + - AssetsUseCloudFront + - AssetsCloudFrontDomain + - AssetsCloudFrontCertArn + - Label: + default: Database + Parameters: + - DatabaseClass + - DatabaseReplication + - DatabaseEngine + - DatabaseEngineVersion + - DatabaseParameterGroupFamily + - DatabaseName + - DatabaseUser + - DatabasePassword + - DatabaseAllocatedStorage + - DatabaseMultiAZ + - DatabaseBackupRetentionDays + - DatabaseCloudWatchLogTypes + - Label: + default: Elasticsearch + Parameters: + - ElasticsearchInstanceType + - ElasticsearchVersion + - ElasticsearchVolumeSize + - Label: + default: SFTP + Parameters: + - UseSFTPServer + - Label: + default: Memcached + Parameters: + - CacheNodeType + - Label: + default: Redis + Parameters: + - RedisNodeType + - RedisAuthToken + - RedisVersion + - RedisNumCacheClusters + - RedisSnapshotRetentionLimit + - RedisAutomaticFailover + - Label: + default: Bastion Server + Parameters: + - BastionType + - BastionAMI + - BastionInstanceType + - BastionKeyName + ParameterLabels: + AdministratorIPAddress: + default: Admin IP Address + AssetsBucketAccessControl: + default: Assets Bucket ACL + AssetsCloudFrontCertArn: + default: CloudFront SSL Certificate ARN + AssetsCloudFrontDomain: + default: CloudFront Custom Domain + AssetsUseCloudFront: + default: Enable CloudFront + BastionAMI: + default: AMI + BastionInstanceType: + default: Instance Type + BastionKeyName: + default: SSH Key Name + BastionType: + default: Type + CacheNodeType: + default: Instance Type + ContainerInstanceType: + default: Instance Type + ContainerVolumeSize: + default: Root Volume Size + CustomerManagedCmkArn: + default: Customer managed key ARN + DatabaseAllocatedStorage: + default: Storage (GB) + DatabaseBackupRetentionDays: + default: Backup Retention Days + DatabaseClass: + default: Instance Type + DatabaseCloudWatchLogTypes: + default: Database Log Types + DatabaseEngine: + default: Engine + DatabaseEngineVersion: + default: Engine Version + DatabaseMultiAZ: + default: Enable MultiAZ + DatabaseName: + default: Database Name + DatabaseParameterGroupFamily: + default: Parameter Group Family + DatabasePassword: + default: Password + DatabaseReplication: + default: Database replication + DatabaseUser: + default: Username + DesiredScale: + default: Desired Instance Count + DomainName: + default: Domain Name + DomainNameAlternates: + default: Alternate Domain Names + ElasticsearchInstanceType: + default: Instance Type + ElasticsearchVersion: + default: Version + ElasticsearchVolumeSize: + default: Storage (GB) + MaxScale: + default: Maximum Instance Count + PrimaryAZ: + default: Primary Availability Zone + PrivateSubnetACidr: + default: Private Subnet A CIDR Block + PrivateSubnetBCidr: + default: Private Subnet B CIDR Block + PublicSubnetACidr: + default: Public Subnet A CIDR Block + PublicSubnetBCidr: + default: Public Subnet B CIDR Block + RedisAuthToken: + default: AuthToken + RedisAutomaticFailover: + default: Enable automatic failover + RedisNodeType: + default: Instance Type + RedisNumCacheClusters: + default: Number of node groups + RedisSnapshotRetentionLimit: + default: Snapshow retention limit + RedisVersion: + default: Redis Version + SecondaryAZ: + default: Secondary Availability Zone + UseAES256Encryption: + default: Enable Encryption + UseSFTPServer: + default: Enable SFTP Server + VpcCidr: + default: VPC IPv4 CIDR Block +Outputs: + AssetsBucketDomainName: + Description: Assets bucket domain name + Value: !GetAtt 'AssetsBucket.DomainName' + AssetsDistributionDomainName: + Condition: AssetsUseCloudFrontCondition + Description: The assets CDN domain name + Value: !GetAtt 'AssetsDistribution.DomainName' + BastionIP: + Condition: BastionTypeSet + Description: Public IP address of Bastion instance + Value: !Ref 'BastionEIP' + CacheAddress: + Condition: UsingMemcached + Description: The DNS address for the cache node/cluster. + Value: !If + - UsingMemcached + - !GetAtt 'CacheCluster.ConfigurationEndpoint.Address' + - '' + CachePort: + Condition: UsingMemcached + Description: The port number for the cache node/cluster. + Value: !GetAtt 'CacheCluster.ConfigurationEndpoint.Port' + CacheURL: + Condition: UsingMemcached + Description: URL to connect to the cache node/cluster. + Value: !If + - UsingMemcached + - !Join + - '' + - - memcached:// + - !If + - UsingMemcached + - !GetAtt 'CacheCluster.ConfigurationEndpoint.Address' + - '' + - ':' + - !If + - UsingMemcached + - !GetAtt 'CacheCluster.ConfigurationEndpoint.Port' + - '' + - '' + ClusterEndpoint: + Description: The connection endpoint for the EKS cluster API. + Value: !GetAtt 'EksCluster.Endpoint' + DatabaseAddress: + Condition: DatabaseCondition + Description: The connection endpoint for the database. + Value: !GetAtt 'DatabaseInstance.Endpoint.Address' + DatabasePort: + Condition: DatabaseCondition + Description: The port number on which the database accepts connections. + Value: !GetAtt 'DatabaseInstance.Endpoint.Port' + DatabaseReplicaAddress: + Condition: DatabaseReplicationCondition + Description: The connection endpoint for the database replica. + Value: !GetAtt 'DatabaseReplica.Endpoint.Address' + DatabaseReplicaURL: + Condition: DatabaseReplicationCondition + Description: URL to connect (without the password) to the database replica. + Value: !If + - DatabaseReplicationCondition + - !Join + - '' + - - !Ref 'DatabaseEngine' + - :// + - !Ref 'DatabaseUser' + - :_PASSWORD_@ + - !GetAtt 'DatabaseReplica.Endpoint.Address' + - ':' + - !GetAtt 'DatabaseReplica.Endpoint.Port' + - / + - !Ref 'DatabaseName' + - '' + DatabaseURL: + Condition: DatabaseCondition + Description: URL to connect (without the password) to the database. + Value: !If + - DatabaseCondition + - !Join + - '' + - - !Ref 'DatabaseEngine' + - :// + - !Ref 'DatabaseUser' + - :_PASSWORD_@ + - !GetAtt 'DatabaseInstance.Endpoint.Address' + - ':' + - !GetAtt 'DatabaseInstance.Endpoint.Port' + - / + - !Ref 'DatabaseName' + - '' + ElasticsearchDomainArn: + Condition: Elasticsearch + Description: Elasticsearch domain ARN + Value: !GetAtt 'ElasticsearchDomain.DomainArn' + ElasticsearchDomainEndpoint: + Condition: Elasticsearch + Description: Elasticsearch domain endpoint + Value: !GetAtt 'ElasticsearchDomain.DomainEndpoint' + PrivateAssetsBucketDomainName: + Description: Private assets bucket domain name + Value: !GetAtt 'PrivateAssetsBucket.DomainName' + RedisAddress: + Condition: UsingRedis + Description: The DNS address for the Redis node/cluster. + Value: !If + - UsingRedis + - !GetAtt 'RedisReplicationGroup.PrimaryEndPoint.Address' + - '' + RedisPort: + Condition: UsingRedis + Description: The port number for the Redis node/cluster. + Value: !If + - UsingRedis + - !GetAtt 'RedisReplicationGroup.PrimaryEndPoint.Port' + - '' + RedisURL: + Condition: UsingRedis + Description: URL to connect to the Redis node/cluster. + Value: !If + - UsingRedis + - !Join + - '' + - - redis + - !If + - SecureRedisCondition + - s + - '' + - :// + - !If + - AuthTokenCondition + - :_PASSWORD_@ + - '' + - !If + - UsingRedis + - !GetAtt 'RedisReplicationGroup.PrimaryEndPoint.Address' + - '' + - ':' + - !If + - UsingRedis + - !GetAtt 'RedisReplicationGroup.PrimaryEndPoint.Port' + - '' + - '' + RepositoryURL: + Description: The docker repository URL + Value: !Join + - '' + - - !Ref 'AWS::AccountId' + - .dkr.ecr. + - !Ref 'AWS::Region' + - .amazonaws.com/ + - !Ref 'ApplicationRepository' + SFTPBucketDomainName: + Condition: UseSFTPServerCondition + Description: SFTP bucket domain name + Value: !GetAtt 'SFTPAssetsBucket.DomainName' +Parameters: + AdministratorIPAddress: + Default: 192.0.2.0/24 + Description: The IP address allowed to access containers. Defaults to TEST-NET-1 + (ie, no valid IP) + Type: String + AssetsBucketAccessControl: + AllowedValues: + - PublicRead + - Private + ConstraintDescription: Must be PublicRead or Private. + Default: PublicRead + Description: Canned ACL for the public S3 bucket. Private is recommended; it allows + for objects to be make publicly readable, but prevents listing of the bucket + contents. + Type: String + AssetsCloudFrontCertArn: + Default: '' + Description: >- + If (1) you specified a custom static media domain, (2) your stack is NOT in + the us-east-1 region, and (3) you wish to serve static media over HTTPS, you + must manually create an ACM certificate in the us-east-1 region and provide + its ARN here. + Type: String + AssetsCloudFrontDomain: + Default: '' + Description: A custom domain name (CNAME) for your CloudFront distribution, e.g., + "static.example.com". + Type: String + AssetsUseCloudFront: + AllowedValues: + - 'true' + - 'false' + Default: 'true' + Description: Whether or not to create a CloudFront distribution tied to the S3 + assets bucket. + Type: String + BastionAMI: + Default: '' + Description: (Optional) Bastion or VPN server AMI in the same region as this stack. + Type: String + BastionInstanceType: + AllowedValues: + - t3.nano + - t3.micro + - t3.small + - t3.medium + - t3.large + - t3.xlarge + - t3.2xlarge + - t2.nano + - t2.micro + - t2.small + - t2.medium + - t2.large + - t2.xlarge + - t2.2xlarge + - m5.large + - m5.xlarge + - m5.2xlarge + - m5.4xlarge + - m5.12xlarge + - m5.24xlarge + - m5d.large + - m5d.xlarge + - m5d.2xlarge + - m5d.4xlarge + - m5d.12xlarge + - m5d.24xlarge + - m4.large + - m4.xlarge + - m4.2xlarge + - m4.4xlarge + - m4.10xlarge + - m4.16xlarge + - m3.medium + - m3.large + - m3.xlarge + - m3.2xlarge + - c5.large + - c5.xlarge + - c5.2xlarge + - c5.4xlarge + - c5.9xlarge + - c5.18xlarge + - c5d.large + - c5d.xlarge + - c5d.2xlarge + - c5d.4xlarge + - c5d.9xlarge + - c5d.18xlarge + - c4.large + - c4.xlarge + - c4.2xlarge + - c4.4xlarge + - c4.8xlarge + - c3.large + - c3.xlarge + - c3.2xlarge + - c3.4xlarge + - c3.8xlarge + - p2.xlarge + - p2.8xlarge + - p2.16xlarge + - g2.2xlarge + - g2.8xlarge + - x1.16large + - x1.32xlarge + - r5.large + - r5.xlarge + - r5.2xlarge + - r5.4xlarge + - r5.12xlarge + - r5.24xlarge + - r4.large + - r4.xlarge + - r4.2xlarge + - r4.4xlarge + - r4.8xlarge + - r4.16xlarge + - r3.large + - r3.xlarge + - r3.2xlarge + - r3.4xlarge + - r3.8xlarge + - i3.large + - i3.xlarge + - i3.2xlarge + - i3.4xlarge + - i3.8xlarge + - i3.16large + - d2.xlarge + - d2.2xlarge + - d2.4xlarge + - d2.8xlarge + - f1.2xlarge + - f1.16xlarge + Default: t2.nano + Description: (Optional) Instance type to use for bastion server. + Type: String + BastionKeyName: + ConstraintDescription: must be the name of an existing EC2 KeyPair. + Default: (none) + Description: Name of an existing EC2 KeyPair to enable SSH access to the Bastion + instance. This parameter is required even if no Bastion AMI is specified (but + will be unused). + Type: AWS::EC2::KeyPair::KeyName + BastionType: + AllowedValues: + - (none) + - SSH + - OpenVPN + Default: (none) + Description: Type of bastion server to create. Determines the default security + group ingress rules to create. + Type: String + CacheNodeType: + AllowedValues: + - (none) + - cache.t2.micro + - cache.t2.small + - cache.t2.medium + - cache.t3.micro + - cache.t3.small + - cache.t3.medium + - cache.m3.medium + - cache.m3.large + - cache.m3.xlarge + - cache.m3.2xlarge + - cache.m4.large + - cache.m4.xlarge + - cache.m4.2xlarge + - cache.m4.4xlarge + - cache.m4.10xlarge + - cache.r4.large + - cache.r4.xlarge + - cache.r4.2xlarge + - cache.r4.4xlarge + - cache.r4.8xlarge + - cache.r4.16xlarge + - cache.r3.large + - cache.r3.xlarge + - cache.r3.2xlarge + - cache.r3.4xlarge + - cache.r3.8xlarge + ConstraintDescription: must select a valid cache node type. + Default: (none) + Description: Cache instance type + Type: String + ContainerInstanceType: + AllowedValues: + - t3a.nano + - t3a.micro + - t3a.small + - t3a.medium + - t3a.large + - t3a.xlarge + - t3a.2xlarge + - t3.nano + - t3.micro + - t3.small + - t3.medium + - t3.large + - t3.xlarge + - t3.2xlarge + - t2.nano + - t2.micro + - t2.small + - t2.medium + - t2.large + - t2.xlarge + - t2.2xlarge + - m5.large + - m5.xlarge + - m5.2xlarge + - m5.4xlarge + - m5.12xlarge + - m5.24xlarge + - m5d.large + - m5d.xlarge + - m5d.2xlarge + - m5d.4xlarge + - m5d.12xlarge + - m5d.24xlarge + - m4.large + - m4.xlarge + - m4.2xlarge + - m4.4xlarge + - m4.10xlarge + - m4.16xlarge + - m3.medium + - m3.large + - m3.xlarge + - m3.2xlarge + - c5.large + - c5.xlarge + - c5.2xlarge + - c5.4xlarge + - c5.9xlarge + - c5.18xlarge + - c5d.large + - c5d.xlarge + - c5d.2xlarge + - c5d.4xlarge + - c5d.9xlarge + - c5d.18xlarge + - c4.large + - c4.xlarge + - c4.2xlarge + - c4.4xlarge + - c4.8xlarge + - c3.large + - c3.xlarge + - c3.2xlarge + - c3.4xlarge + - c3.8xlarge + - p2.xlarge + - p2.8xlarge + - p2.16xlarge + - g2.2xlarge + - g2.8xlarge + - x1.16large + - x1.32xlarge + - r5.large + - r5.xlarge + - r5.2xlarge + - r5.4xlarge + - r5.12xlarge + - r5.24xlarge + - r4.large + - r4.xlarge + - r4.2xlarge + - r4.4xlarge + - r4.8xlarge + - r4.16xlarge + - r3.large + - r3.xlarge + - r3.2xlarge + - r3.4xlarge + - r3.8xlarge + - i3.large + - i3.xlarge + - i3.2xlarge + - i3.4xlarge + - i3.8xlarge + - i3.16large + - d2.xlarge + - d2.2xlarge + - d2.4xlarge + - d2.8xlarge + - f1.2xlarge + - f1.16xlarge + Default: t3a.micro + Description: The application server instance type + Type: String + ContainerVolumeSize: + Default: '20' + Description: Size of instance EBS root volume (in GB) + Type: Number + CustomerManagedCmkArn: + Default: '' + Description: KMS CMK ARN to encrypt stack resources (except for public buckets). + Type: String + DatabaseAllocatedStorage: + ConstraintDescription: must be between 5 and 1024Gb. + Default: '20' + Description: The size of the database (Gb) + MaxValue: '1024' + MinValue: '5' + Type: Number + DatabaseBackupRetentionDays: + AllowedValues: + - '0' + - '1' + - '2' + - '3' + - '4' + - '5' + - '6' + - '7' + - '8' + - '9' + - '10' + - '11' + - '12' + - '13' + - '14' + - '15' + - '16' + - '17' + - '18' + - '19' + - '20' + - '21' + - '22' + - '23' + - '24' + - '25' + - '26' + - '27' + - '28' + - '29' + - '30' + - '31' + - '32' + - '33' + - '34' + - '35' + Default: '30' + Description: The number of days for which automated backups are retained. Setting + to 0 disables automated backups. + Type: Number + DatabaseClass: + AllowedValues: + - (none) + - db.r3.large + - db.r3.xlarge + - db.r3.2xlarge + - db.r3.4xlarge + - db.r3.8xlarge + - db.r4.large + - db.r4.xlarge + - db.r4.2xlarge + - db.r4.4xlarge + - db.r4.8xlarge + - db.r4.16xlarge + - db.r5.large + - db.r5.xlarge + - db.r5.2xlarge + - db.r5.4xlarge + - db.r5.8xlarge + - db.r5.12xlarge + - db.r5.16xlarge + - db.r5.24xlarge + - db.t2.micro + - db.t2.small + - db.t2.medium + - db.t2.large + - db.t3.micro + - db.t3.small + - db.t3.medium + - db.t3.large + - db.t3.xlarge + - db.t3.2xlarge + - db.m1.small + - db.m1.medium + - db.m1.large + - db.m1.xlarge + - db.m2.xlarge + - db.m2.2xlarge + - db.m2.4xlarge + - db.m3.medium + - db.m3.large + - db.m3.xlarge + - db.m3.2xlarge + - db.m4.large + - db.m4.xlarge + - db.m4.2xlarge + - db.m4.4xlarge + - db.m4.10xlarge + - db.m4.16xlarge + - db.m5.large + - db.m5.xlarge + - db.m5.2xlarge + - db.m5.4xlarge + - db.m5.8xlarge + - db.m5.12xlarge + - db.m5.16xlarge + - db.m5.24xlarge + ConstraintDescription: must select a valid database instance type. + Default: db.t3.micro + Description: Database instance class + Type: String + DatabaseCloudWatchLogTypes: + Default: '' + Description: A comma-separated list of the RDS log types (if any) to publish to + CloudWatch Logs. Note that log types are database engine-specific. + Type: CommaDelimitedList + DatabaseEngine: + AllowedValues: + - aurora + - mariadb + - mysql + - oracle-ee + - oracle-se2 + - oracle-se1 + - oracle-se + - postgres + - sqlserver-ee + - sqlserver-se + - sqlserver-ex + - sqlserver-web + ConstraintDescription: must select a valid database engine. + Default: postgres + Description: Database engine to use + Type: String + DatabaseEngineVersion: + Default: '' + Description: Database version to use + Type: String + DatabaseMultiAZ: + AllowedValues: + - 'true' + - 'false' + ConstraintDescription: must choose true or false. + Default: 'false' + Description: Whether or not to create a MultiAZ database + Type: String + DatabaseName: + AllowedPattern: '[a-zA-Z][a-zA-Z0-9_]*' + ConstraintDescription: must begin with a letter and contain only alphanumeric + characters. + Default: app + Description: Name of the database to create in the database server + MaxLength: '64' + MinLength: '1' + Type: String + DatabaseParameterGroupFamily: + AllowedValues: + - aurora-mysql5.7 + - docdb3.6 + - neptune1 + - aurora-postgresql9.6 + - aurora-postgresql10 + - mariadb10.0 + - mariadb10.1 + - mariadb10.2 + - mariadb10.3 + - mysql5.5 + - mysql5.6 + - mysql5.7 + - mysql8.0 + - oracle-ee-11.2 + - oracle-ee-12.1 + - oracle-ee-12.2 + - oracle-se-11.2 + - oracle-se1-11.2 + - oracle-se2-12.1 + - oracle-se2-12.2 + - aurora5.6 + - postgres9.3 + - postgres9.4 + - postgres9.5 + - postgres9.6 + - postgres10 + - postgres11 + - postgres12 + - sqlserver-ee-11.0 + - sqlserver-ee-12.0 + - sqlserver-ee-13.0 + - sqlserver-ee-14.0 + - sqlserver-ex-11.0 + - sqlserver-ex-12.0 + - sqlserver-ex-13.0 + - sqlserver-ex-14.0 + - sqlserver-se-11.0 + - sqlserver-se-12.0 + - sqlserver-se-13.0 + - sqlserver-se-14.0 + - sqlserver-web-11.0 + - sqlserver-web-12.0 + - sqlserver-web-13.0 + - sqlserver-web-14.0 + Description: Database parameter group family name; must match the engine and version + of the RDS instance. + Type: String + DatabasePassword: + AllowedPattern: '[ !#-.0-?A-~]*' + ConstraintDescription: must consist of 10-41 printable ASCII characters except + "/", """, or "@". + Description: The database admin account password must consist of 10-41 printableASCII + characters *except* "/", """, or "@". + MaxLength: '41' + MinLength: '10' + NoEcho: true + Type: String + DatabaseReplication: + AllowedValues: + - 'true' + - 'false' + Default: 'false' + Description: Whether to create a database server replica - WARNING this will fail + if DatabaseBackupRetentionDays is 0. + Type: String + DatabaseUser: + AllowedPattern: '[a-zA-Z][a-zA-Z0-9_]*' + ConstraintDescription: must begin with a letter and contain only alphanumeric + characters and underscores. + Default: app + Description: The database admin account username + MaxLength: '63' + MinLength: '1' + Type: String + DesiredScale: + Default: '2' + Description: Desired container instances count + Type: Number + DomainName: + Description: The fully-qualified domain name for the application. + Type: String + DomainNameAlternates: + Description: A comma-separated list of Alternate FQDNs to be included in the Subject + Alternative Name extension of the SSL certificate. + Type: CommaDelimitedList + ElasticsearchInstanceType: + AllowedValues: + - (none) + - t2.micro.elasticsearch + - t2.small.elasticsearch + - t2.medium.elasticsearch + - m3.medium.elasticsearch + - m3.large.elasticsearch + - m3.xlarge.elasticsearch + - m3.2xlarge.elasticsearch + - m4.large.elasticsearch + - m4.xlarge.elasticsearch + - m4.2xlarge.elasticsearch + - m4.4xlarge.elasticsearch + - m4.10xlarge.elasticsearch + - c4.large.elasticsearch + - c4.xlarge.elasticsearch + - c4.2xlarge.elasticsearch + - c4.4xlarge.elasticsearch + - c4.8xlarge.elasticsearch + - r3.large.elasticsearch + - r3.xlarge.elasticsearch + - r3.2xlarge.elasticsearch + - r3.4xlarge.elasticsearch + - r3.8xlarge.elasticsearch + - r4.large.elasticsearch + - r4.xlarge.elasticsearch + - r4.2xlarge.elasticsearch + - r4.4xlarge.elasticsearch + - r4.8xlarge.elasticsearch + - r4.16xlarge.elasticsearch + - i2.xlarge.elasticsearch + - i2.2xlarge.elasticsearch + ConstraintDescription: must select a valid Elasticsearch instance type. + Default: (none) + Description: 'Elasticsearch instance type. Note: not all types are supported in + all regions; see: http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-supported-instance-types.html' + Type: String + ElasticsearchVersion: + AllowedValues: + - '1.5' + - '2.3' + - '5.1' + - '5.3' + ConstraintDescription: must select a valid Elasticsearch version. + Default: '2.3' + Description: 'Elasticsearch version. Note: t2.micro.elasticsearch instances support + only versions 2.3 and 1.5.' + Type: String + ElasticsearchVolumeSize: + Default: '10' + Description: 'Elasticsearch EBS volume size, in GB. Note: maximum volume size + varies by instance type; see: http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-limits.html#ebsresource.' + MaxValue: '1536' + MinValue: '10' + Type: Number + MaxScale: + Default: '4' + Description: Maximum container instances count + Type: Number + PrimaryAZ: + Description: The primary availability zone for creating resources. + Type: AWS::EC2::AvailabilityZone::Name + PrivateSubnetACidr: + AllowedPattern: >- + ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ + ConstraintDescription: Must be a private IPv4 range with size /16 and /28. + Default: 10.0.8.0/22 + Description: IPv4 CIDR block for the private subnet in the primary AZ. [Possibly + not modifiable after stack creation] + Type: String + PrivateSubnetBCidr: + AllowedPattern: >- + ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ + ConstraintDescription: Must be a private IPv4 range with size /16 and /28. + Default: 10.0.12.0/22 + Description: IPv4 CIDR block for the private subnet in the secondary AZ. [Possibly + not modifiable after stack creation] + Type: String + PublicSubnetACidr: + AllowedPattern: >- + ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ + ConstraintDescription: Must be a private IPv4 range with size /16 and /28. + Default: 10.0.0.0/22 + Description: IPv4 CIDR block for the public subnet in the primary AZ. [Possibly + not modifiable after stack creation] + Type: String + PublicSubnetBCidr: + AllowedPattern: >- + ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ + ConstraintDescription: Must be a private IPv4 range with size /16 and /28. + Default: 10.0.4.0/22 + Description: IPv4 CIDR block for the public subnet in the secondary AZ. [Possibly + not modifiable after stack creation] + Type: String + RedisAuthToken: + AllowedPattern: '[ !#-.0-?A-~]*' + ConstraintDescription: must consist of 16-128 printable ASCII characters except + "/", """, or "@". + Default: DO_NOT_CREATE_AUTH_TOKEN + Description: The password used to access a Redis ReplicationGroup (required for + HIPAA). + MaxLength: '128' + MinLength: '16' + NoEcho: true + Type: String + RedisAutomaticFailover: + AllowedValues: + - 'true' + - 'false' + Default: 'false' + Description: Specifies whether a read-only replica is automatically promoted to + read/write primary if the existing primary fails. + Type: String + RedisNodeType: + AllowedValues: + - (none) + - cache.t2.micro + - cache.t2.small + - cache.t2.medium + - cache.t3.micro + - cache.t3.small + - cache.t3.medium + - cache.m3.medium + - cache.m3.large + - cache.m3.xlarge + - cache.m3.2xlarge + - cache.m4.large + - cache.m4.xlarge + - cache.m4.2xlarge + - cache.m4.4xlarge + - cache.m4.10xlarge + - cache.r4.large + - cache.r4.xlarge + - cache.r4.2xlarge + - cache.r4.4xlarge + - cache.r4.8xlarge + - cache.r4.16xlarge + - cache.r3.large + - cache.r3.xlarge + - cache.r3.2xlarge + - cache.r3.4xlarge + - cache.r3.8xlarge + ConstraintDescription: must select a valid cache node type. + Default: (none) + Description: Redis instance type + Type: String + RedisNumCacheClusters: + Default: '1' + Description: The number of clusters this replication group initially has. + Type: Number + RedisSnapshotRetentionLimit: + Default: '0' + Description: >- + The number of days for which ElastiCache retains automatic snapshots before + deleting them.For example, if you set SnapshotRetentionLimit to 5, a snapshot + that was taken today is retained for 5 days before being deleted. 0 = automatic + backups are disabled for this cluster. + Type: Number + RedisVersion: + Default: '' + Description: 'Redis version to use. See available versions: aws elasticache describe-cache-engine-versions' + Type: String + SecondaryAZ: + Description: The secondary availability zone for creating resources. Must differ + from primary zone. + Type: AWS::EC2::AvailabilityZone::Name + UseAES256Encryption: + AllowedValues: + - 'true' + - 'false' + Default: 'false' + Description: Whether or not to use server side encryption for S3, EBS, and RDS. + When true, encryption is enabled for all resources. + Type: String + UseSFTPServer: + AllowedValues: + - 'true' + - 'false' + Default: 'false' + Description: Whether or not to set up an SFTP service. If 'true', this will set + up a transfer server and add an S3 bucket for its use, along with a role and + policies for use when adding users. + Type: String + VpcCidr: + AllowedPattern: >- + ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ + ConstraintDescription: Must be a private IPv4 range with size /16 and /28. + Default: 10.0.0.0/20 + Description: The primary IPv4 CIDR block for the VPC. [Possibly not modifiable + after stack creation] + Type: String +Resources: + ApplicationRepository: + Properties: + ImageScanningConfiguration: + ScanOnPush: 'true' + RepositoryPolicyText: + Statement: + - Action: + - ecr:GetDownloadUrlForLayer + - ecr:BatchGetImage + - ecr:BatchCheckLayerAvailability + - ecr:PutImage + - ecr:InitiateLayerUpload + - ecr:UploadLayerPart + - ecr:CompleteLayerUpload + Effect: Allow + Principal: + AWS: + - !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':iam::' + - !Ref 'AWS::AccountId' + - :root + Sid: AllowPushPull + Version: '2008-10-17' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + Type: AWS::ECR::Repository + AssetsBucket: + DeletionPolicy: Retain + Properties: + AccessControl: !Ref 'AssetsBucketAccessControl' + BucketEncryption: !If + - UseAES256EncryptionCond + - ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + SSEAlgorithm: AES256 + - !Ref 'AWS::NoValue' + CorsConfiguration: + CorsRules: + - AllowedHeaders: + - '*' + AllowedMethods: + - POST + - PUT + - HEAD + - GET + AllowedOrigins: !Split + - ; + - !Join + - '' + - - https:// + - !Ref 'DomainName' + - !If + - NoAlternateDomains + - '' + - ;https:// + - !Join + - ;https:// + - !Ref 'DomainNameAlternates' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + VersioningConfiguration: + Status: Enabled + Type: AWS::S3::Bucket + AssetsCertificate: + Condition: AssetsCreateCertificateCondition + Properties: + DomainName: !Ref 'AssetsCloudFrontDomain' + DomainValidationOptions: + - DomainName: !Ref 'AssetsCloudFrontDomain' + ValidationDomain: !Ref 'AssetsCloudFrontDomain' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + Type: AWS::CertificateManager::Certificate + AssetsDistribution: + Condition: AssetsUseCloudFrontCondition + Properties: + DistributionConfig: + Aliases: !If + - AssetsCloudFrontDomainCondition + - - !Ref 'AssetsCloudFrontDomain' + - !Ref 'AWS::NoValue' + DefaultCacheBehavior: + ForwardedValues: + Headers: + - Origin + - Access-Control-Request-Headers + - Access-Control-Request-Method + QueryString: 'true' + TargetOriginId: Assets + ViewerProtocolPolicy: allow-all + Enabled: 'true' + Origins: + - DomainName: !GetAtt 'AssetsBucket.DomainName' + Id: Assets + S3OriginConfig: + OriginAccessIdentity: '' + ViewerCertificate: !If + - AssetsCreateCertificateCondition + - AcmCertificateArn: !Ref 'AssetsCertificate' + SslSupportMethod: sni-only + - !If + - AssetsCloudFrontCertArnCondition + - AcmCertificateArn: !Ref 'AssetsCloudFrontCertArn' + SslSupportMethod: sni-only + - !Ref 'AWS::NoValue' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + Type: AWS::CloudFront::Distribution + BastionEIP: + Condition: BastionTypeSet + Properties: + Domain: vpc + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + Type: AWS::EC2::EIP + BastionEIPAssociation: + Condition: BastionTypeAndAMISet + Properties: + AllocationId: !GetAtt 'BastionEIP.AllocationId' + InstanceId: !Ref 'BastionInstance' + Type: AWS::EC2::EIPAssociation + BastionInstance: + Condition: BastionTypeAndAMISet + Properties: + BlockDeviceMappings: + - DeviceName: /dev/sda1 + Ebs: + Encrypted: !Ref 'UseAES256Encryption' + KmsKeyId: !If + - CmkArnCondition + - !Ref 'CustomerManagedCmkArn' + - !Ref 'AWS::NoValue' + VolumeSize: 8 + VolumeType: gp2 + ImageId: !Ref 'BastionAMI' + InstanceType: !Ref 'BastionInstanceType' + KeyName: !Ref 'BastionKeyName' + SecurityGroupIds: + - !Ref 'BastionSecurityGroup' + SubnetId: !Ref 'PublicSubnetA' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - bastion + - Key: aws-web-stacks:role + Value: bastion + Type: AWS::EC2::Instance + BastionSecurityGroup: + Condition: BastionTypeSet + Properties: + GroupDescription: Bastion security group. + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - bastion + VpcId: !Ref 'Vpc' + Type: AWS::EC2::SecurityGroup + BastionSecurityGroupIngressHTTPS: + Condition: BastionTypeIsOpenVPNSet + Properties: + CidrIp: !Ref 'AdministratorIPAddress' + Description: Administrator HTTPS access. + FromPort: 443 + GroupId: !Ref 'BastionSecurityGroup' + IpProtocol: tcp + ToPort: 443 + Type: AWS::EC2::SecurityGroupIngress + BastionSecurityGroupIngressOpenVPN: + Condition: BastionTypeIsOpenVPNSet + Properties: + CidrIp: '0.0.0.0/0' + Description: OpenVPN Access. + FromPort: 1194 + GroupId: !Ref 'BastionSecurityGroup' + IpProtocol: udp + ToPort: 1194 + Type: AWS::EC2::SecurityGroupIngress + BastionSecurityGroupIngressSSH: + Condition: BastionTypeSet + Properties: + CidrIp: !Ref 'AdministratorIPAddress' + Description: Administrator SSH access. + FromPort: 22 + GroupId: !Ref 'BastionSecurityGroup' + IpProtocol: tcp + ToPort: 22 + Type: AWS::EC2::SecurityGroupIngress + CacheCluster: + Condition: UsingMemcached + Properties: + CacheNodeType: !Ref 'CacheNodeType' + CacheSubnetGroupName: !Ref 'CacheSubnetGroup' + Engine: memcached + NumCacheNodes: 1 + Port: 11211 + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - cache + VpcSecurityGroupIds: + - !Ref 'CacheSecurityGroup' + Type: AWS::ElastiCache::CacheCluster + CacheSecurityGroup: + Condition: EitherCacheCondition + Properties: + GroupDescription: Cache security group. + SecurityGroupIngress: + - !If + - UsingMemcached + - CidrIp: !Ref 'PrivateSubnetACidr' + FromPort: 11211 + IpProtocol: tcp + ToPort: 11211 + - !Ref 'AWS::NoValue' + - !If + - UsingMemcached + - CidrIp: !Ref 'PrivateSubnetBCidr' + FromPort: 11211 + IpProtocol: tcp + ToPort: 11211 + - !Ref 'AWS::NoValue' + - !If + - UsingRedis + - CidrIp: !Ref 'PrivateSubnetACidr' + FromPort: 6379 + IpProtocol: tcp + ToPort: 6379 + - !Ref 'AWS::NoValue' + - !If + - UsingRedis + - CidrIp: !Ref 'PrivateSubnetBCidr' + FromPort: 6379 + IpProtocol: tcp + ToPort: 6379 + - !Ref 'AWS::NoValue' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - cache + VpcId: !Ref 'Vpc' + Type: AWS::EC2::SecurityGroup + CacheSubnetGroup: + Condition: EitherCacheCondition + Properties: + Description: Subnets available for the cache instance + SubnetIds: + - !Ref 'PrivateSubnetA' + - !Ref 'PrivateSubnetB' + Type: AWS::ElastiCache::SubnetGroup + ContainerInstanceProfile: + Properties: + Path: / + Roles: + - !Ref 'ContainerInstanceRole' + Type: AWS::IAM::InstanceProfile + ContainerInstanceRole: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + ManagedPolicyArns: + - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy + - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly + - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy + Path: / + Policies: + - PolicyDocument: + Statement: !If + - UseSFTPServerCondition + - - Action: + - s3:ListBucket + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'AssetsBucket' + - Action: + - s3:* + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'AssetsBucket' + - /* + - Action: + - s3:ListBucket + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'PrivateAssetsBucket' + - Action: + - s3:* + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'PrivateAssetsBucket' + - /* + - Action: + - s3:ListBucket + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'SFTPAssetsBucket' + - Action: + - s3:* + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'SFTPAssetsBucket' + - /* + - - Action: + - s3:ListBucket + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'AssetsBucket' + - Action: + - s3:* + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'AssetsBucket' + - /* + - Action: + - s3:ListBucket + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'PrivateAssetsBucket' + - Action: + - s3:* + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'PrivateAssetsBucket' + - /* + PolicyName: AssetsManagementPolicy + - PolicyDocument: + Statement: + - Action: + - logs:Create* + - logs:PutLogEvents + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - :logs:*:*:* + PolicyName: LoggingPolicy + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + Type: AWS::IAM::Role + ContainerLogs: + DeletionPolicy: Retain + Properties: + RetentionInDays: 365 + Type: AWS::Logs::LogGroup + ContainerSecurityGroupOpenVPNIngress: + Condition: BastionTypeIsOpenVPNSet + Properties: + GroupId: !GetAtt 'EksCluster.ClusterSecurityGroupId' + IpProtocol: '-1' + SourceSecurityGroupId: !Ref 'BastionSecurityGroup' + Type: AWS::EC2::SecurityGroupIngress + ContainerSecurityGroupSSHBastionIngress: + Condition: BastionTypeIsSSHSet + Properties: + FromPort: 22 + GroupId: !GetAtt 'EksCluster.ClusterSecurityGroupId' + IpProtocol: tcp + SourceSecurityGroupId: !Ref 'BastionSecurityGroup' + ToPort: 22 + Type: AWS::EC2::SecurityGroupIngress + DatabaseInstance: + Condition: DatabaseCondition + DeletionPolicy: Snapshot + Properties: + AllocatedStorage: !Ref 'DatabaseAllocatedStorage' + BackupRetentionPeriod: !Ref 'DatabaseBackupRetentionDays' + DBInstanceClass: !Ref 'DatabaseClass' + DBName: !Ref 'DatabaseName' + DBParameterGroupName: !Ref 'DatabaseParameterGroup' + DBSubnetGroupName: !Ref 'DatabaseSubnetGroup' + EnableCloudwatchLogsExports: !If + - DatabaseLoggingCondition + - !Ref 'DatabaseCloudWatchLogTypes' + - !Ref 'AWS::NoValue' + Engine: !Ref 'DatabaseEngine' + EngineVersion: !Ref 'DatabaseEngineVersion' + KmsKeyId: !If + - CmkArnCondition + - !Ref 'CustomerManagedCmkArn' + - !Ref 'AWS::NoValue' + MasterUserPassword: !Ref 'DatabasePassword' + MasterUsername: !Ref 'DatabaseUser' + MultiAZ: !Ref 'DatabaseMultiAZ' + StorageEncrypted: !Ref 'UseAES256Encryption' + StorageType: gp2 + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + VPCSecurityGroups: + - !Ref 'DatabaseSecurityGroup' + Type: AWS::RDS::DBInstance + DatabaseParameterGroup: + Condition: DatabaseCondition + Properties: + Description: Database parameter group. + Family: !Ref 'DatabaseParameterGroupFamily' + Parameters: {} + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + Type: AWS::RDS::DBParameterGroup + DatabaseReplica: + Condition: DatabaseReplicationCondition + Properties: + DBInstanceClass: !Ref 'DatabaseClass' + Engine: !Ref 'DatabaseEngine' + SourceDBInstanceIdentifier: !Ref 'DatabaseInstance' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + VPCSecurityGroups: + - !Ref 'DatabaseSecurityGroup' + Type: AWS::RDS::DBInstance + DatabaseSecurityGroup: + Condition: DatabaseCondition + Properties: + GroupDescription: Database security group. + SecurityGroupIngress: + - CidrIp: !Ref 'PrivateSubnetACidr' + FromPort: !FindInMap + - RdsEngineMap + - !Ref 'DatabaseEngine' + - Port + IpProtocol: tcp + ToPort: !FindInMap + - RdsEngineMap + - !Ref 'DatabaseEngine' + - Port + - CidrIp: !Ref 'PrivateSubnetBCidr' + FromPort: !FindInMap + - RdsEngineMap + - !Ref 'DatabaseEngine' + - Port + IpProtocol: tcp + ToPort: !FindInMap + - RdsEngineMap + - !Ref 'DatabaseEngine' + - Port + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - rds + VpcId: !Ref 'Vpc' + Type: AWS::EC2::SecurityGroup + DatabaseSecurityGroupBastionIngress: + Condition: BastionDatabaseCondition + Properties: + Description: Bastion Access + FromPort: !FindInMap + - RdsEngineMap + - !Ref 'DatabaseEngine' + - Port + GroupId: !Ref 'DatabaseSecurityGroup' + IpProtocol: tcp + SourceSecurityGroupId: !Ref 'BastionSecurityGroup' + ToPort: !FindInMap + - RdsEngineMap + - !Ref 'DatabaseEngine' + - Port + Type: AWS::EC2::SecurityGroupIngress + DatabaseSubnetGroup: + Condition: DatabaseCondition + Properties: + DBSubnetGroupDescription: Subnets available for the RDS DB Instance + SubnetIds: + - !Ref 'PrivateSubnetA' + - !Ref 'PrivateSubnetB' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + Type: AWS::RDS::DBSubnetGroup + EksCluster: + Properties: + Name: !Sub '${AWS::StackName}-cluster' + ResourcesVpcConfig: + SecurityGroupIds: + - !Ref 'EksClusterSecurityGroup' + SubnetIds: + - !Ref 'PublicSubnetA' + - !Ref 'PublicSubnetB' + - !Ref 'PrivateSubnetA' + - !Ref 'PrivateSubnetB' + RoleArn: !GetAtt 'EksServiceRole.Arn' + Type: AWS::EKS::Cluster + EksClusterSecurityGroup: + Properties: + GroupDescription: EKS control plane security group. + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - eks-cluster + VpcId: !Ref 'Vpc' + Type: AWS::EC2::SecurityGroup + EksServiceRole: + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - eks.amazonaws.com + ManagedPolicyArns: + - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy + - arn:aws:iam::aws:policy/AmazonEKSServicePolicy + Path: / + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + Type: AWS::IAM::Role + ElasticsearchDomain: + Condition: Elasticsearch + Properties: + AccessPolicies: + Statement: + - Action: + - es:* + Effect: Allow + Principal: + AWS: + - !GetAtt 'ContainerInstanceRole.Arn' + EBSOptions: + EBSEnabled: 'true' + VolumeSize: !Ref 'ElasticsearchVolumeSize' + ElasticsearchClusterConfig: + InstanceType: !Ref 'ElasticsearchInstanceType' + ElasticsearchVersion: !Ref 'ElasticsearchVersion' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + Type: AWS::Elasticsearch::Domain + GatewayAttachement: + Properties: + InternetGatewayId: !Ref 'InternetGateway' + VpcId: !Ref 'Vpc' + Type: AWS::EC2::VPCGatewayAttachment + InternetGateway: + Properties: + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - igw + Type: AWS::EC2::InternetGateway + NatGateway: + Properties: + AllocationId: !GetAtt 'NatIp.AllocationId' + SubnetId: !Ref 'PublicSubnetA' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - nat + Type: AWS::EC2::NatGateway + NatGatewayRoute: + Properties: + DestinationCidrBlock: '0.0.0.0/0' + NatGatewayId: !Ref 'NatGateway' + RouteTableId: !Ref 'NatGatewayRouteTable' + Type: AWS::EC2::Route + NatGatewayRouteTable: + Properties: + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - private + VpcId: !Ref 'Vpc' + Type: AWS::EC2::RouteTable + NatIp: + Properties: + Domain: vpc + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + Type: AWS::EC2::EIP + Nodegroup: + DependsOn: + - EksCluster + Properties: + ClusterName: !Ref 'EksCluster' + DiskSize: !Ref 'ContainerVolumeSize' + InstanceTypes: + - !Ref 'ContainerInstanceType' + NodeRole: !GetAtt 'ContainerInstanceRole.Arn' + ScalingConfig: + DesiredSize: !Ref 'DesiredScale' + MaxSize: !Ref 'MaxScale' + MinSize: 2 + Subnets: + - !Ref 'PrivateSubnetA' + - !Ref 'PrivateSubnetB' + Tags: + aws-web-stacks:stack-name: !Ref 'AWS::StackName' + Type: AWS::EKS::Nodegroup + PrivateAssetsBucket: + DeletionPolicy: Retain + Properties: + AccessControl: Private + BucketEncryption: !If + - UseAES256EncryptionCond + - ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + KMSMasterKeyID: !If + - CmkArnCondition + - !Ref 'CustomerManagedCmkArn' + - !Ref 'AWS::NoValue' + SSEAlgorithm: !If + - CmkArnCondition + - aws:kms + - AES256 + - !Ref 'AWS::NoValue' + CorsConfiguration: + CorsRules: + - AllowedHeaders: + - '*' + AllowedMethods: + - POST + - PUT + - HEAD + - GET + AllowedOrigins: !Split + - ; + - !Join + - '' + - - https:// + - !Ref 'DomainName' + - !If + - NoAlternateDomains + - '' + - ;https:// + - !Join + - ;https:// + - !Ref 'DomainNameAlternates' + PublicAccessBlockConfiguration: + BlockPublicAcls: 'true' + BlockPublicPolicy: 'true' + IgnorePublicAcls: 'true' + RestrictPublicBuckets: 'true' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + VersioningConfiguration: + Status: Enabled + Type: AWS::S3::Bucket + PrivateSubnetA: + Properties: + AvailabilityZone: !Ref 'PrimaryAZ' + CidrBlock: !Ref 'PrivateSubnetACidr' + MapPublicIpOnLaunch: 'false' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - private-a + - Key: kubernetes.io/role/internal-elb + Value: '1' + VpcId: !Ref 'Vpc' + Type: AWS::EC2::Subnet + PrivateSubnetARouteTableAssociation: + Properties: + RouteTableId: !Ref 'NatGatewayRouteTable' + SubnetId: !Ref 'PrivateSubnetA' + Type: AWS::EC2::SubnetRouteTableAssociation + PrivateSubnetB: + Properties: + AvailabilityZone: !Ref 'SecondaryAZ' + CidrBlock: !Ref 'PrivateSubnetBCidr' + MapPublicIpOnLaunch: 'false' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - private-b + - Key: kubernetes.io/role/internal-elb + Value: '1' + VpcId: !Ref 'Vpc' + Type: AWS::EC2::Subnet + PrivateSubnetBRouteTableAssociation: + Properties: + RouteTableId: !Ref 'NatGatewayRouteTable' + SubnetId: !Ref 'PrivateSubnetB' + Type: AWS::EC2::SubnetRouteTableAssociation + PublicRoute: + Properties: + DestinationCidrBlock: '0.0.0.0/0' + GatewayId: !Ref 'InternetGateway' + RouteTableId: !Ref 'PublicRouteTable' + Type: AWS::EC2::Route + PublicRouteTable: + Properties: + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - public + VpcId: !Ref 'Vpc' + Type: AWS::EC2::RouteTable + PublicSubnetA: + Properties: + AvailabilityZone: !Ref 'PrimaryAZ' + CidrBlock: !Ref 'PublicSubnetACidr' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - public-a + - Key: kubernetes.io/role/elb + Value: '1' + VpcId: !Ref 'Vpc' + Type: AWS::EC2::Subnet + PublicSubnetARouteTableAssociation: + Properties: + RouteTableId: !Ref 'PublicRouteTable' + SubnetId: !Ref 'PublicSubnetA' + Type: AWS::EC2::SubnetRouteTableAssociation + PublicSubnetB: + Properties: + AvailabilityZone: !Ref 'SecondaryAZ' + CidrBlock: !Ref 'PublicSubnetBCidr' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - public-b + - Key: kubernetes.io/role/elb + Value: '1' + VpcId: !Ref 'Vpc' + Type: AWS::EC2::Subnet + PublicSubnetBRouteTableAssociation: + Properties: + RouteTableId: !Ref 'PublicRouteTable' + SubnetId: !Ref 'PublicSubnetB' + Type: AWS::EC2::SubnetRouteTableAssociation + RedisReplicationGroup: + Condition: UsingRedis + Properties: + AtRestEncryptionEnabled: !Ref 'UseAES256Encryption' + AuthToken: !If + - AuthTokenCondition + - !Ref 'RedisAuthToken' + - !Ref 'AWS::NoValue' + AutomaticFailoverEnabled: !Ref 'RedisAutomaticFailover' + CacheNodeType: !Ref 'RedisNodeType' + CacheSubnetGroupName: !Ref 'CacheSubnetGroup' + Engine: redis + EngineVersion: !Ref 'RedisVersion' + KmsKeyId: !If + - CmkArnCondition + - !Ref 'CustomerManagedCmkArn' + - !Ref 'AWS::NoValue' + MultiAZEnabled: !Ref 'RedisAutomaticFailover' + NumCacheClusters: !Ref 'RedisNumCacheClusters' + Port: 6379 + PreferredCacheClusterAZs: !If + - RedisAutomaticFailoverCondition + - - !Ref 'PrimaryAZ' + - !Ref 'SecondaryAZ' + - !Ref 'AWS::NoValue' + ReplicationGroupDescription: Redis ReplicationGroup + SecurityGroupIds: + - !Ref 'CacheSecurityGroup' + SnapshotRetentionLimit: !Ref 'RedisSnapshotRetentionLimit' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - redis + TransitEncryptionEnabled: !Ref 'UseAES256Encryption' + Type: AWS::ElastiCache::ReplicationGroup + SFTPAssetsBucket: + DeletionPolicy: Retain + Properties: + AccessControl: Private + BucketEncryption: !If + - UseAES256EncryptionCond + - ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + KMSMasterKeyID: !If + - CmkArnCondition + - !Ref 'CustomerManagedCmkArn' + - !Ref 'AWS::NoValue' + SSEAlgorithm: !If + - CmkArnCondition + - aws:kms + - AES256 + - !Ref 'AWS::NoValue' + CorsConfiguration: + CorsRules: + - AllowedHeaders: + - '*' + AllowedMethods: + - POST + - PUT + - HEAD + - GET + AllowedOrigins: !Split + - ; + - !Join + - '' + - - https:// + - !Ref 'DomainName' + - !If + - NoAlternateDomains + - '' + - ;https:// + - !Join + - ;https:// + - !Ref 'DomainNameAlternates' + PublicAccessBlockConfiguration: + BlockPublicAcls: 'true' + BlockPublicPolicy: 'true' + IgnorePublicAcls: 'true' + RestrictPublicBuckets: 'true' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + VersioningConfiguration: + Status: Enabled + Type: AWS::S3::Bucket + SFTPUserRole: + Condition: UseSFTPServerCondition + Properties: + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Effect: Allow + Principal: + Service: + - transfer.amazonaws.com + Policies: + - PolicyDocument: + Statement: !If + - UseSFTPWithKMSCondition + - - Action: + - s3:ListBucket + - s3:GetBucketLocation + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'SFTPAssetsBucket' + - Action: + - s3:PutObject + - s3:GetObject + - s3:DeleteObject + - s3:DeleteObjectVersion + - s3:GetObjectVersion + - s3:GetObjectACL + - s3:PutObjectACL + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'SFTPAssetsBucket' + - /* + - Action: + - kms:DescribeKey + - kms:GenerateDataKey + - kms:Encrypt + - kms:Decrypt + Effect: Allow + Resource: !Ref 'CustomerManagedCmkArn' + - - Action: + - s3:ListBucket + - s3:GetBucketLocation + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'SFTPAssetsBucket' + - Action: + - s3:PutObject + - s3:GetObject + - s3:DeleteObject + - s3:DeleteObjectVersion + - s3:GetObjectVersion + - s3:GetObjectACL + - s3:PutObjectACL + Effect: Allow + Resource: !Join + - '' + - - !If + - InGovCloudRegion + - arn:aws-us-gov + - arn:aws + - ':s3:::' + - !Ref 'SFTPAssetsBucket' + - /* + Version: '2012-10-17' + PolicyName: SFTPSUserRolePolicy + RoleName: !Join + - '-' + - - !Ref 'AWS::StackName' + - SFTPUserRole + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + Type: AWS::IAM::Role + SFTPUserScopeDownPolicy: + Condition: UseSFTPServerCondition + Properties: + PolicyDocument: + Statement: !If + - UseSFTPWithKMSCondition + - - Action: + - s3:ListBucket + Condition: + StringLike: + s3:prefix: + - ${transfer:UserName}/* + - ${transfer:UserName} + Effect: Allow + Resource: + - arn:aws:s3:::${transfer:HomeBucket} + Sid: AllowListingOfSFTPUserFolder + - Action: + - s3:PutObject + - s3:GetObject + - s3:DeleteObjectVersion + - s3:DeleteObject + - s3:GetObjectVersion + Effect: Allow + Resource: + - !Join + - / + - - !GetAtt 'SFTPAssetsBucket.Arn' + - ${transfer:UserName} + - !Join + - / + - - !GetAtt 'SFTPAssetsBucket.Arn' + - ${transfer:UserName}/* + Sid: HomeDirObjectAccess + - Action: + - kms:DescribeKey + - kms:GenerateDataKey + - kms:Encrypt + - kms:Decrypt + Effect: Allow + Resource: !Ref 'CustomerManagedCmkArn' + - - Action: + - s3:ListBucket + Condition: + StringLike: + s3:prefix: + - ${transfer:UserName}/* + - ${transfer:UserName} + Effect: Allow + Resource: + - arn:aws:s3:::${transfer:HomeBucket} + Sid: AllowListingOfSFTPUserFolder + - Action: + - s3:PutObject + - s3:GetObject + - s3:DeleteObjectVersion + - s3:DeleteObject + - s3:GetObjectVersion + Effect: Allow + Resource: + - !Join + - / + - - !GetAtt 'SFTPAssetsBucket.Arn' + - ${transfer:UserName} + - !Join + - / + - - !GetAtt 'SFTPAssetsBucket.Arn' + - ${transfer:UserName}/* + Sid: HomeDirObjectAccess + Version: '2012-10-17' + Type: AWS::IAM::ManagedPolicy + TransferServer: + Condition: UseSFTPServerCondition + Properties: + EndpointType: PUBLIC + IdentityProviderType: SERVICE_MANAGED + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - sftp + Type: AWS::Transfer::Server + VPCS3Endpoint: + Properties: + RouteTableIds: + - !Ref 'NatGatewayRouteTable' + ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3' + VpcId: !Ref 'Vpc' + Type: AWS::EC2::VPCEndpoint + Vpc: + Properties: + CidrBlock: !Ref 'VpcCidr' + EnableDnsHostnames: 'true' + EnableDnsSupport: 'true' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' + - Key: Name + Value: !Join + - '-' + - - !Ref 'AWS::StackName' + - vpc + Type: AWS::EC2::VPC + From 90270e091d1b327956431ff9349787eff4515e7b Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 1 Aug 2024 10:09:18 -0400 Subject: [PATCH 09/43] Update eks-nat files --- deploy/group_vars/all.yml | 2 + deploy/stack/eks-nat.yml | 258 +++-- deploy/stack/eks-no-nat.yml | 2036 ----------------------------------- 3 files changed, 166 insertions(+), 2130 deletions(-) delete mode 100644 deploy/stack/eks-no-nat.yml diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index 71587e9f..3fc357b2 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -68,6 +68,8 @@ cloudformation_stack: DatabaseUser: "{{ app_name }}_admin" DatabasePassword: "{{ admin_database_password }}" DatabaseMultiAZ: "true" + EksClusterName: "philly-hip-stack-cluster" + EksPublicAccessCidrs: "107.15.45.253/32,47.230.11.28/32" tags: Environment: "{{ app_name }}" diff --git a/deploy/stack/eks-nat.yml b/deploy/stack/eks-nat.yml index 8c940fab..ca822ccf 100644 --- a/deploy/stack/eks-nat.yml +++ b/deploy/stack/eks-nat.yml @@ -1,6 +1,6 @@ # This Cloudformation stack template was generated by # https://github.com/caktus/aws-web-stacks -# at 2021-03-10 21:34:32.220724 +# at 2023-10-12 14:57:50.784099 # with parameters: # USE_EKS = on # USE_NAT_GATEWAY = on @@ -78,6 +78,14 @@ Conditions: - !Equals - !Ref 'ElasticsearchInstanceType' - (none) + EnableEksEncryptionConfigCond: !And + - !Equals + - !Ref 'EnableEksEncryptionConfig' + - 'true' + - !Not + - !Equals + - !Ref 'CustomerManagedCmkArn' + - '' InGovCloudRegion: !Equals - !Ref 'AWS::Region' - us-gov-west-1 @@ -89,6 +97,12 @@ Conditions: RedisAutomaticFailoverCondition: !Equals - !Ref 'RedisAutomaticFailover' - 'true' + RestrictEksApiAccessCond: !Not + - !Equals + - !Join + - '' + - !Ref 'EksPublicAccessCidrs' + - '' SecureRedisCondition: !And - !Condition 'UsingRedis' - !Condition 'UseAES256EncryptionCond' @@ -214,6 +228,12 @@ Metadata: - RedisNumCacheClusters - RedisSnapshotRetentionLimit - RedisAutomaticFailover + - Label: + default: Elastic Kubernetes Service (EKS) + Parameters: + - EnableEksEncryptionConfig + - EksPublicAccessCidrs + - EksClusterName - Label: default: Bastion Server Parameters: @@ -278,12 +298,18 @@ Metadata: default: Domain Name DomainNameAlternates: default: Alternate Domain Names + EksClusterName: + default: Cluster name + EksPublicAccessCidrs: + default: Kubernetes API public access CIDRs ElasticsearchInstanceType: default: Instance Type ElasticsearchVersion: default: Version ElasticsearchVolumeSize: default: Storage (GB) + EnableEksEncryptionConfig: + default: Enable EKS EncryptionConfig MaxScale: default: Maximum Instance Count PrimaryAZ: @@ -474,8 +500,7 @@ Outputs: Parameters: AdministratorIPAddress: Default: 192.0.2.0/24 - Description: The IP address allowed to access containers. Defaults to TEST-NET-1 - (ie, no valid IP) + Description: The IP address allowed to access containers. Defaults to TEST-NET-1 (ie, no valid IP) Type: String AssetsBucketAccessControl: AllowedValues: @@ -483,30 +508,24 @@ Parameters: - Private ConstraintDescription: Must be PublicRead or Private. Default: PublicRead - Description: Canned ACL for the public S3 bucket. Private is recommended; it allows - for objects to be make publicly readable, but prevents listing of the bucket - contents. + Description: Canned ACL for the public S3 bucket. Private is recommended; it allows for objects to be make publicly readable, but prevents listing of the bucket contents. Type: String AssetsCloudFrontCertArn: Default: '' Description: >- - If (1) you specified a custom static media domain, (2) your stack is NOT in - the us-east-1 region, and (3) you wish to serve static media over HTTPS, you - must manually create an ACM certificate in the us-east-1 region and provide - its ARN here. + If (1) you specified a custom static media domain, (2) your stack is NOT in the us-east-1 region, and (3) you wish to serve static media over HTTPS, you must manually create an ACM certificate in + the us-east-1 region and provide its ARN here. Type: String AssetsCloudFrontDomain: Default: '' - Description: A custom domain name (CNAME) for your CloudFront distribution, e.g., - "static.example.com". + Description: A custom domain name (CNAME) for your CloudFront distribution, e.g., "static.example.com". Type: String AssetsUseCloudFront: AllowedValues: - 'true' - 'false' Default: 'true' - Description: Whether or not to create a CloudFront distribution tied to the S3 - assets bucket. + Description: Whether or not to create a CloudFront distribution tied to the S3 assets bucket. Type: String BastionAMI: Default: '' @@ -614,9 +633,7 @@ Parameters: BastionKeyName: ConstraintDescription: must be the name of an existing EC2 KeyPair. Default: (none) - Description: Name of an existing EC2 KeyPair to enable SSH access to the Bastion - instance. This parameter is required even if no Bastion AMI is specified (but - will be unused). + Description: Name of an existing EC2 KeyPair to enable SSH access to the Bastion instance. This parameter is required even if no Bastion AMI is specified (but will be unused). Type: AWS::EC2::KeyPair::KeyName BastionType: AllowedValues: @@ -624,8 +641,7 @@ Parameters: - SSH - OpenVPN Default: (none) - Description: Type of bastion server to create. Determines the default security - group ingress rules to create. + Description: Type of bastion server to create. Determines the default security group ingress rules to create. Type: String CacheNodeType: AllowedValues: @@ -820,8 +836,7 @@ Parameters: - '34' - '35' Default: '30' - Description: The number of days for which automated backups are retained. Setting - to 0 disables automated backups. + Description: The number of days for which automated backups are retained. Setting to 0 disables automated backups. Type: Number DatabaseClass: AllowedValues: @@ -849,6 +864,12 @@ Parameters: - db.t2.small - db.t2.medium - db.t2.large + - db.t4g.micro + - db.t4g.small + - db.t4g.medium + - db.t4g.large + - db.t4g.xlarge + - db.t4g.2xlarge - db.t3.micro - db.t3.small - db.t3.medium @@ -886,8 +907,7 @@ Parameters: Type: String DatabaseCloudWatchLogTypes: Default: '' - Description: A comma-separated list of the RDS log types (if any) to publish to - CloudWatch Logs. Note that log types are database engine-specific. + Description: A comma-separated list of the RDS log types (if any) to publish to CloudWatch Logs. Note that log types are database engine-specific. Type: CommaDelimitedList DatabaseEngine: AllowedValues: @@ -921,8 +941,7 @@ Parameters: Type: String DatabaseName: AllowedPattern: '[a-zA-Z][a-zA-Z0-9_]*' - ConstraintDescription: must begin with a letter and contain only alphanumeric - characters. + ConstraintDescription: must begin with a letter and contain only alphanumeric characters. Default: app Description: Name of the database to create in the database server MaxLength: '64' @@ -951,13 +970,12 @@ Parameters: - oracle-se2-12.1 - oracle-se2-12.2 - aurora5.6 - - postgres9.3 - - postgres9.4 - - postgres9.5 - - postgres9.6 - postgres10 - postgres11 - postgres12 + - postgres13 + - postgres14 + - postgres15 - sqlserver-ee-11.0 - sqlserver-ee-12.0 - sqlserver-ee-13.0 @@ -974,15 +992,12 @@ Parameters: - sqlserver-web-12.0 - sqlserver-web-13.0 - sqlserver-web-14.0 - Description: Database parameter group family name; must match the engine and version - of the RDS instance. + Description: Database parameter group family name; must match the engine and version of the RDS instance. Type: String DatabasePassword: AllowedPattern: '[ !#-.0-?A-~]*' - ConstraintDescription: must consist of 10-41 printable ASCII characters except - "/", """, or "@". - Description: The database admin account password must consist of 10-41 printableASCII - characters *except* "/", """, or "@". + ConstraintDescription: must consist of 10-41 printable ASCII characters except "/", """, or "@". + Description: The database admin account password must consist of 10-41 printableASCII characters *except* "/", """, or "@". MaxLength: '41' MinLength: '10' NoEcho: true @@ -992,13 +1007,11 @@ Parameters: - 'true' - 'false' Default: 'false' - Description: Whether to create a database server replica - WARNING this will fail - if DatabaseBackupRetentionDays is 0. + Description: Whether to create a database server replica - WARNING this will fail if DatabaseBackupRetentionDays is 0. Type: String DatabaseUser: AllowedPattern: '[a-zA-Z][a-zA-Z0-9_]*' - ConstraintDescription: must begin with a letter and contain only alphanumeric - characters and underscores. + ConstraintDescription: must begin with a letter and contain only alphanumeric characters and underscores. Default: app Description: The database admin account username MaxLength: '63' @@ -1012,8 +1025,14 @@ Parameters: Description: The fully-qualified domain name for the application. Type: String DomainNameAlternates: - Description: A comma-separated list of Alternate FQDNs to be included in the Subject - Alternative Name extension of the SSL certificate. + Description: A comma-separated list of Alternate FQDNs to be included in the Subject Alternative Name extension of the SSL certificate. + Type: CommaDelimitedList + EksClusterName: + Description: The unique name to give to your cluster. + Type: String + EksPublicAccessCidrs: + Default: '' + Description: The CIDR blocks that are allowed access to your cluster's public Kubernetes API server endpoint. Type: CommaDelimitedList ElasticsearchInstanceType: AllowedValues: @@ -1050,8 +1069,7 @@ Parameters: - i2.2xlarge.elasticsearch ConstraintDescription: must select a valid Elasticsearch instance type. Default: (none) - Description: 'Elasticsearch instance type. Note: not all types are supported in - all regions; see: http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-supported-instance-types.html' + Description: 'Elasticsearch instance type. Note: not all types are supported in all regions; see: http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-supported-instance-types.html' Type: String ElasticsearchVersion: AllowedValues: @@ -1061,16 +1079,21 @@ Parameters: - '5.3' ConstraintDescription: must select a valid Elasticsearch version. Default: '2.3' - Description: 'Elasticsearch version. Note: t2.micro.elasticsearch instances support - only versions 2.3 and 1.5.' + Description: 'Elasticsearch version. Note: t2.micro.elasticsearch instances support only versions 2.3 and 1.5.' Type: String ElasticsearchVolumeSize: Default: '10' - Description: 'Elasticsearch EBS volume size, in GB. Note: maximum volume size - varies by instance type; see: http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-limits.html#ebsresource.' + Description: 'Elasticsearch EBS volume size, in GB. Note: maximum volume size varies by instance type; see: http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-limits.html#ebsresource.' MaxValue: '1536' MinValue: '10' Type: Number + EnableEksEncryptionConfig: + AllowedValues: + - 'true' + - 'false' + Default: 'false' + Description: Use AWS Key Management Service (KMS) keys to provide envelope encryption of Kubernetes secrets. Depends on Customer managed key ARN. + Type: String MaxScale: Default: '4' Description: Maximum container instances count @@ -1083,40 +1106,34 @@ Parameters: ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: Must be a private IPv4 range with size /16 and /28. Default: 10.0.8.0/22 - Description: IPv4 CIDR block for the private subnet in the primary AZ. [Possibly - not modifiable after stack creation] + Description: IPv4 CIDR block for the private subnet in the primary AZ. [Possibly not modifiable after stack creation] Type: String PrivateSubnetBCidr: AllowedPattern: >- ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: Must be a private IPv4 range with size /16 and /28. Default: 10.0.12.0/22 - Description: IPv4 CIDR block for the private subnet in the secondary AZ. [Possibly - not modifiable after stack creation] + Description: IPv4 CIDR block for the private subnet in the secondary AZ. [Possibly not modifiable after stack creation] Type: String PublicSubnetACidr: AllowedPattern: >- ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: Must be a private IPv4 range with size /16 and /28. Default: 10.0.0.0/22 - Description: IPv4 CIDR block for the public subnet in the primary AZ. [Possibly - not modifiable after stack creation] + Description: IPv4 CIDR block for the public subnet in the primary AZ. [Possibly not modifiable after stack creation] Type: String PublicSubnetBCidr: AllowedPattern: >- ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: Must be a private IPv4 range with size /16 and /28. Default: 10.0.4.0/22 - Description: IPv4 CIDR block for the public subnet in the secondary AZ. [Possibly - not modifiable after stack creation] + Description: IPv4 CIDR block for the public subnet in the secondary AZ. [Possibly not modifiable after stack creation] Type: String RedisAuthToken: AllowedPattern: '[ !#-.0-?A-~]*' - ConstraintDescription: must consist of 16-128 printable ASCII characters except - "/", """, or "@". + ConstraintDescription: must consist of 16-128 printable ASCII characters except "/", """, or "@". Default: DO_NOT_CREATE_AUTH_TOKEN - Description: The password used to access a Redis ReplicationGroup (required for - HIPAA). + Description: The password used to access a Redis ReplicationGroup (required for HIPAA). MaxLength: '128' MinLength: '16' NoEcho: true @@ -1126,8 +1143,7 @@ Parameters: - 'true' - 'false' Default: 'false' - Description: Specifies whether a read-only replica is automatically promoted to - read/write primary if the existing primary fails. + Description: Specifies whether a read-only replica is automatically promoted to read/write primary if the existing primary fails. Type: String RedisNodeType: AllowedValues: @@ -1169,49 +1185,42 @@ Parameters: RedisSnapshotRetentionLimit: Default: '0' Description: >- - The number of days for which ElastiCache retains automatic snapshots before - deleting them.For example, if you set SnapshotRetentionLimit to 5, a snapshot - that was taken today is retained for 5 days before being deleted. 0 = automatic - backups are disabled for this cluster. + The number of days for which ElastiCache retains automatic snapshots before deleting them.For example, if you set SnapshotRetentionLimit to 5, a snapshot that was taken today is retained for 5 days + before being deleted. 0 = automatic backups are disabled for this cluster. Type: Number RedisVersion: Default: '' Description: 'Redis version to use. See available versions: aws elasticache describe-cache-engine-versions' Type: String SecondaryAZ: - Description: The secondary availability zone for creating resources. Must differ - from primary zone. + Description: The secondary availability zone for creating resources. Must differ from primary zone. Type: AWS::EC2::AvailabilityZone::Name UseAES256Encryption: AllowedValues: - 'true' - 'false' Default: 'false' - Description: Whether or not to use server side encryption for S3, EBS, and RDS. - When true, encryption is enabled for all resources. + Description: Whether or not to use server side encryption for S3, EBS, and RDS. When true, encryption is enabled for all resources. Type: String UseSFTPServer: AllowedValues: - 'true' - 'false' Default: 'false' - Description: Whether or not to set up an SFTP service. If 'true', this will set - up a transfer server and add an S3 bucket for its use, along with a role and - policies for use when adding users. + Description: Whether or not to set up an SFTP service. If 'true', this will set up a transfer server and add an S3 bucket for its use, along with a role and policies for use when adding users. Type: String VpcCidr: AllowedPattern: >- ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ ConstraintDescription: Must be a private IPv4 range with size /16 and /28. Default: 10.0.0.0/20 - Description: The primary IPv4 CIDR block for the VPC. [Possibly not modifiable - after stack creation] + Description: The primary IPv4 CIDR block for the VPC. [Possibly not modifiable after stack creation] Type: String Resources: ApplicationRepository: Properties: ImageScanningConfiguration: - ScanOnPush: 'true' + ScanOnPush: true RepositoryPolicyText: Statement: - Action: @@ -1303,10 +1312,10 @@ Resources: - Origin - Access-Control-Request-Headers - Access-Control-Request-Method - QueryString: 'true' + QueryString: true TargetOriginId: Assets ViewerProtocolPolicy: allow-all - Enabled: 'true' + Enabled: true Origins: - DomainName: !GetAtt 'AssetsBucket.DomainName' Id: Assets @@ -1482,6 +1491,9 @@ Resources: SubnetIds: - !Ref 'PrivateSubnetA' - !Ref 'PrivateSubnetB' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' Type: AWS::ElastiCache::SubnetGroup ContainerInstanceProfile: Properties: @@ -1629,6 +1641,8 @@ Resources: - Action: - logs:Create* - logs:PutLogEvents + - logs:DescribeLogGroups + - logs:DescribeLogStreams Effect: Allow Resource: !Join - '' @@ -1646,7 +1660,20 @@ Resources: DeletionPolicy: Retain Properties: RetentionInDays: 365 + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' Type: AWS::Logs::LogGroup + ContainerSecurityGroupKubernetesBastionIngress: + Condition: BastionTypeSet + Properties: + Description: Kubernetes API endpoint + FromPort: 443 + GroupId: !GetAtt 'EksCluster.ClusterSecurityGroupId' + IpProtocol: tcp + SourceSecurityGroupId: !Ref 'BastionSecurityGroup' + ToPort: 443 + Type: AWS::EC2::SecurityGroupIngress ContainerSecurityGroupOpenVPNIngress: Condition: BastionTypeIsOpenVPNSet Properties: @@ -1780,8 +1807,30 @@ Resources: Type: AWS::RDS::DBSubnetGroup EksCluster: Properties: - Name: !Sub '${AWS::StackName}-cluster' + EncryptionConfig: !If + - EnableEksEncryptionConfigCond + - - Provider: + KeyArn: !Ref 'CustomerManagedCmkArn' + Resources: + - secrets + - !Ref 'AWS::NoValue' + Logging: + ClusterLogging: + EnabledTypes: + - Type: api + - Type: audit + - Type: authenticator + Name: !Ref 'EksClusterName' ResourcesVpcConfig: + EndpointPrivateAccess: !If + - RestrictEksApiAccessCond + - true + - false + EndpointPublicAccess: true + PublicAccessCidrs: !If + - RestrictEksApiAccessCond + - !Ref 'EksPublicAccessCidrs' + - !Ref 'AWS::NoValue' SecurityGroupIds: - !Ref 'EksClusterSecurityGroup' SubnetIds: @@ -1790,6 +1839,9 @@ Resources: - !Ref 'PrivateSubnetA' - !Ref 'PrivateSubnetB' RoleArn: !GetAtt 'EksServiceRole.Arn' + Tags: + - Key: aws-web-stacks:stack-name + Value: !Ref 'AWS::StackName' Type: AWS::EKS::Cluster EksClusterSecurityGroup: Properties: @@ -1834,7 +1886,7 @@ Resources: AWS: - !GetAtt 'ContainerInstanceRole.Arn' EBSOptions: - EBSEnabled: 'true' + EBSEnabled: true VolumeSize: !Ref 'ElasticsearchVolumeSize' ElasticsearchClusterConfig: InstanceType: !Ref 'ElasticsearchInstanceType' @@ -1902,9 +1954,8 @@ Resources: - EksCluster Properties: ClusterName: !Ref 'EksCluster' - DiskSize: !Ref 'ContainerVolumeSize' - InstanceTypes: - - !Ref 'ContainerInstanceType' + LaunchTemplate: + Id: !Ref 'NodegroupLaunchTemplate' NodeRole: !GetAtt 'ContainerInstanceRole.Arn' ScalingConfig: DesiredSize: !Ref 'DesiredScale' @@ -1916,6 +1967,25 @@ Resources: Tags: aws-web-stacks:stack-name: !Ref 'AWS::StackName' Type: AWS::EKS::Nodegroup + NodegroupLaunchTemplate: + Properties: + LaunchTemplateData: + BlockDeviceMappings: + - DeviceName: /dev/xvda + Ebs: + DeleteOnTermination: true + Encrypted: !Ref 'UseAES256Encryption' + KmsKeyId: !If + - CmkArnCondition + - !Ref 'CustomerManagedCmkArn' + - !Ref 'AWS::NoValue' + VolumeSize: !Ref 'ContainerVolumeSize' + VolumeType: gp2 + InstanceType: !Ref 'ContainerInstanceType' + MetadataOptions: + HttpPutResponseHopLimit: 3 + HttpTokens: required + Type: AWS::EC2::LaunchTemplate PrivateAssetsBucket: DeletionPolicy: Retain Properties: @@ -1956,10 +2026,10 @@ Resources: - ;https:// - !Ref 'DomainNameAlternates' PublicAccessBlockConfiguration: - BlockPublicAcls: 'true' - BlockPublicPolicy: 'true' - IgnorePublicAcls: 'true' - RestrictPublicBuckets: 'true' + BlockPublicAcls: true + BlockPublicPolicy: true + IgnorePublicAcls: true + RestrictPublicBuckets: true Tags: - Key: aws-web-stacks:stack-name Value: !Ref 'AWS::StackName' @@ -1970,7 +2040,7 @@ Resources: Properties: AvailabilityZone: !Ref 'PrimaryAZ' CidrBlock: !Ref 'PrivateSubnetACidr' - MapPublicIpOnLaunch: 'false' + MapPublicIpOnLaunch: false Tags: - Key: aws-web-stacks:stack-name Value: !Ref 'AWS::StackName' @@ -1992,7 +2062,7 @@ Resources: Properties: AvailabilityZone: !Ref 'SecondaryAZ' CidrBlock: !Ref 'PrivateSubnetBCidr' - MapPublicIpOnLaunch: 'false' + MapPublicIpOnLaunch: false Tags: - Key: aws-web-stacks:stack-name Value: !Ref 'AWS::StackName' @@ -2149,10 +2219,10 @@ Resources: - ;https:// - !Ref 'DomainNameAlternates' PublicAccessBlockConfiguration: - BlockPublicAcls: 'true' - BlockPublicPolicy: 'true' - IgnorePublicAcls: 'true' - RestrictPublicBuckets: 'true' + BlockPublicAcls: true + BlockPublicPolicy: true + IgnorePublicAcls: true + RestrictPublicBuckets: true Tags: - Key: aws-web-stacks:stack-name Value: !Ref 'AWS::StackName' @@ -2346,8 +2416,8 @@ Resources: Vpc: Properties: CidrBlock: !Ref 'VpcCidr' - EnableDnsHostnames: 'true' - EnableDnsSupport: 'true' + EnableDnsHostnames: true + EnableDnsSupport: true Tags: - Key: aws-web-stacks:stack-name Value: !Ref 'AWS::StackName' diff --git a/deploy/stack/eks-no-nat.yml b/deploy/stack/eks-no-nat.yml deleted file mode 100644 index b99c3d00..00000000 --- a/deploy/stack/eks-no-nat.yml +++ /dev/null @@ -1,2036 +0,0 @@ -# This Cloudformation stack template was generated by -# https://github.com/caktus/aws-web-stacks -# at 2021-03-10 21:34:31.917371 -# with parameters: -# USE_EKS = on - -Conditions: - AssetsCloudFrontCertArnCondition: !Not - - !Equals - - !Ref 'AssetsCloudFrontCertArn' - - '' - AssetsCloudFrontDomainCondition: !Not - - !Equals - - !Ref 'AssetsCloudFrontDomain' - - '' - AssetsCreateCertificateCondition: !And - - !Not - - !Equals - - !Ref 'AssetsCloudFrontDomain' - - '' - - !Equals - - !Ref 'AWS::Region' - - us-east-1 - - !Equals - - !Ref 'AssetsCloudFrontCertArn' - - '' - AssetsUseCloudFrontCondition: !Equals - - !Ref 'AssetsUseCloudFront' - - 'true' - AuthTokenCondition: !Not - - !Equals - - !Ref 'RedisAuthToken' - - DO_NOT_CREATE_AUTH_TOKEN - CmkArnCondition: !Not - - !Equals - - !Ref 'CustomerManagedCmkArn' - - '' - DatabaseCondition: !Not - - !Equals - - !Ref 'DatabaseClass' - - (none) - DatabaseLoggingCondition: !Not - - !Equals - - !Join - - ',' - - !Ref 'DatabaseCloudWatchLogTypes' - - '' - DatabaseReplicationCondition: !And - - !Condition 'DatabaseCondition' - - !Equals - - !Ref 'DatabaseReplication' - - 'true' - EitherCacheCondition: !Or - - !Condition 'UsingMemcached' - - !Condition 'UsingRedis' - Elasticsearch: !Not - - !Equals - - !Ref 'ElasticsearchInstanceType' - - (none) - InGovCloudRegion: !Equals - - !Ref 'AWS::Region' - - us-gov-west-1 - NoAlternateDomains: !Equals - - !Join - - '' - - !Ref 'DomainNameAlternates' - - '' - RedisAutomaticFailoverCondition: !Equals - - !Ref 'RedisAutomaticFailover' - - 'true' - SecureRedisCondition: !And - - !Condition 'UsingRedis' - - !Condition 'UseAES256EncryptionCond' - UseAES256EncryptionCond: !Equals - - !Ref 'UseAES256Encryption' - - 'true' - UseSFTPServerCondition: !Equals - - !Ref 'UseSFTPServer' - - 'true' - UseSFTPWithKMSCondition: !And - - !Equals - - !Ref 'UseSFTPServer' - - 'true' - - !Condition 'UseAES256EncryptionCond' - - !Condition 'CmkArnCondition' - UseSFTPWithoutKMSCondition: !And - - !Equals - - !Ref 'UseSFTPServer' - - 'true' - - !Not - - !Condition 'CmkArnCondition' - UsingMemcached: !Not - - !Equals - - !Ref 'CacheNodeType' - - (none) - UsingRedis: !Not - - !Equals - - !Ref 'RedisNodeType' - - (none) -Mappings: - RdsEngineMap: - aurora: - Port: '3306' - mariadb: - Port: '3306' - mysql: - Port: '3306' - oracle-ee: - Port: '1521' - oracle-se: - Port: '1521' - oracle-se1: - Port: '1521' - oracle-se2: - Port: '1521' - postgres: - Port: '5432' - sqlserver-ee: - Port: '1433' - sqlserver-ex: - Port: '1433' - sqlserver-se: - Port: '1433' - sqlserver-web: - Port: '1433' -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: Global - Parameters: - - UseAES256Encryption - - CustomerManagedCmkArn - - DomainName - - DomainNameAlternates - - PrimaryAZ - - SecondaryAZ - - VpcCidr - - PublicSubnetACidr - - PublicSubnetBCidr - - PrivateSubnetACidr - - PrivateSubnetBCidr - - Label: - default: Application Server - Parameters: - - AdministratorIPAddress - - DesiredScale - - MaxScale - - ContainerVolumeSize - - ContainerInstanceType - - Label: - default: Static Media - Parameters: - - AssetsBucketAccessControl - - AssetsUseCloudFront - - AssetsCloudFrontDomain - - AssetsCloudFrontCertArn - - Label: - default: Database - Parameters: - - DatabaseClass - - DatabaseReplication - - DatabaseEngine - - DatabaseEngineVersion - - DatabaseParameterGroupFamily - - DatabaseName - - DatabaseUser - - DatabasePassword - - DatabaseAllocatedStorage - - DatabaseMultiAZ - - DatabaseBackupRetentionDays - - DatabaseCloudWatchLogTypes - - Label: - default: Elasticsearch - Parameters: - - ElasticsearchInstanceType - - ElasticsearchVersion - - ElasticsearchVolumeSize - - Label: - default: SFTP - Parameters: - - UseSFTPServer - - Label: - default: Memcached - Parameters: - - CacheNodeType - - Label: - default: Redis - Parameters: - - RedisNodeType - - RedisAuthToken - - RedisVersion - - RedisNumCacheClusters - - RedisSnapshotRetentionLimit - - RedisAutomaticFailover - ParameterLabels: - AdministratorIPAddress: - default: Admin IP Address - AssetsBucketAccessControl: - default: Assets Bucket ACL - AssetsCloudFrontCertArn: - default: CloudFront SSL Certificate ARN - AssetsCloudFrontDomain: - default: CloudFront Custom Domain - AssetsUseCloudFront: - default: Enable CloudFront - CacheNodeType: - default: Instance Type - ContainerInstanceType: - default: Instance Type - ContainerVolumeSize: - default: Root Volume Size - CustomerManagedCmkArn: - default: Customer managed key ARN - DatabaseAllocatedStorage: - default: Storage (GB) - DatabaseBackupRetentionDays: - default: Backup Retention Days - DatabaseClass: - default: Instance Type - DatabaseCloudWatchLogTypes: - default: Database Log Types - DatabaseEngine: - default: Engine - DatabaseEngineVersion: - default: Engine Version - DatabaseMultiAZ: - default: Enable MultiAZ - DatabaseName: - default: Database Name - DatabaseParameterGroupFamily: - default: Parameter Group Family - DatabasePassword: - default: Password - DatabaseReplication: - default: Database replication - DatabaseUser: - default: Username - DesiredScale: - default: Desired Instance Count - DomainName: - default: Domain Name - DomainNameAlternates: - default: Alternate Domain Names - ElasticsearchInstanceType: - default: Instance Type - ElasticsearchVersion: - default: Version - ElasticsearchVolumeSize: - default: Storage (GB) - MaxScale: - default: Maximum Instance Count - PrimaryAZ: - default: Primary Availability Zone - PrivateSubnetACidr: - default: Private Subnet A CIDR Block - PrivateSubnetBCidr: - default: Private Subnet B CIDR Block - PublicSubnetACidr: - default: Public Subnet A CIDR Block - PublicSubnetBCidr: - default: Public Subnet B CIDR Block - RedisAuthToken: - default: AuthToken - RedisAutomaticFailover: - default: Enable automatic failover - RedisNodeType: - default: Instance Type - RedisNumCacheClusters: - default: Number of node groups - RedisSnapshotRetentionLimit: - default: Snapshow retention limit - RedisVersion: - default: Redis Version - SecondaryAZ: - default: Secondary Availability Zone - UseAES256Encryption: - default: Enable Encryption - UseSFTPServer: - default: Enable SFTP Server - VpcCidr: - default: VPC IPv4 CIDR Block -Outputs: - AssetsBucketDomainName: - Description: Assets bucket domain name - Value: !GetAtt 'AssetsBucket.DomainName' - AssetsDistributionDomainName: - Condition: AssetsUseCloudFrontCondition - Description: The assets CDN domain name - Value: !GetAtt 'AssetsDistribution.DomainName' - CacheAddress: - Condition: UsingMemcached - Description: The DNS address for the cache node/cluster. - Value: !If - - UsingMemcached - - !GetAtt 'CacheCluster.ConfigurationEndpoint.Address' - - '' - CachePort: - Condition: UsingMemcached - Description: The port number for the cache node/cluster. - Value: !GetAtt 'CacheCluster.ConfigurationEndpoint.Port' - CacheURL: - Condition: UsingMemcached - Description: URL to connect to the cache node/cluster. - Value: !If - - UsingMemcached - - !Join - - '' - - - memcached:// - - !If - - UsingMemcached - - !GetAtt 'CacheCluster.ConfigurationEndpoint.Address' - - '' - - ':' - - !If - - UsingMemcached - - !GetAtt 'CacheCluster.ConfigurationEndpoint.Port' - - '' - - '' - ClusterEndpoint: - Description: The connection endpoint for the EKS cluster API. - Value: !GetAtt 'EksCluster.Endpoint' - DatabaseAddress: - Condition: DatabaseCondition - Description: The connection endpoint for the database. - Value: !GetAtt 'DatabaseInstance.Endpoint.Address' - DatabasePort: - Condition: DatabaseCondition - Description: The port number on which the database accepts connections. - Value: !GetAtt 'DatabaseInstance.Endpoint.Port' - DatabaseReplicaAddress: - Condition: DatabaseReplicationCondition - Description: The connection endpoint for the database replica. - Value: !GetAtt 'DatabaseReplica.Endpoint.Address' - DatabaseReplicaURL: - Condition: DatabaseReplicationCondition - Description: URL to connect (without the password) to the database replica. - Value: !If - - DatabaseReplicationCondition - - !Join - - '' - - - !Ref 'DatabaseEngine' - - :// - - !Ref 'DatabaseUser' - - :_PASSWORD_@ - - !GetAtt 'DatabaseReplica.Endpoint.Address' - - ':' - - !GetAtt 'DatabaseReplica.Endpoint.Port' - - / - - !Ref 'DatabaseName' - - '' - DatabaseURL: - Condition: DatabaseCondition - Description: URL to connect (without the password) to the database. - Value: !If - - DatabaseCondition - - !Join - - '' - - - !Ref 'DatabaseEngine' - - :// - - !Ref 'DatabaseUser' - - :_PASSWORD_@ - - !GetAtt 'DatabaseInstance.Endpoint.Address' - - ':' - - !GetAtt 'DatabaseInstance.Endpoint.Port' - - / - - !Ref 'DatabaseName' - - '' - ElasticsearchDomainArn: - Condition: Elasticsearch - Description: Elasticsearch domain ARN - Value: !GetAtt 'ElasticsearchDomain.DomainArn' - ElasticsearchDomainEndpoint: - Condition: Elasticsearch - Description: Elasticsearch domain endpoint - Value: !GetAtt 'ElasticsearchDomain.DomainEndpoint' - PrivateAssetsBucketDomainName: - Description: Private assets bucket domain name - Value: !GetAtt 'PrivateAssetsBucket.DomainName' - RedisAddress: - Condition: UsingRedis - Description: The DNS address for the Redis node/cluster. - Value: !If - - UsingRedis - - !GetAtt 'RedisReplicationGroup.PrimaryEndPoint.Address' - - '' - RedisPort: - Condition: UsingRedis - Description: The port number for the Redis node/cluster. - Value: !If - - UsingRedis - - !GetAtt 'RedisReplicationGroup.PrimaryEndPoint.Port' - - '' - RedisURL: - Condition: UsingRedis - Description: URL to connect to the Redis node/cluster. - Value: !If - - UsingRedis - - !Join - - '' - - - redis - - !If - - SecureRedisCondition - - s - - '' - - :// - - !If - - AuthTokenCondition - - :_PASSWORD_@ - - '' - - !If - - UsingRedis - - !GetAtt 'RedisReplicationGroup.PrimaryEndPoint.Address' - - '' - - ':' - - !If - - UsingRedis - - !GetAtt 'RedisReplicationGroup.PrimaryEndPoint.Port' - - '' - - '' - RepositoryURL: - Description: The docker repository URL - Value: !Join - - '' - - - !Ref 'AWS::AccountId' - - .dkr.ecr. - - !Ref 'AWS::Region' - - .amazonaws.com/ - - !Ref 'ApplicationRepository' - SFTPBucketDomainName: - Condition: UseSFTPServerCondition - Description: SFTP bucket domain name - Value: !GetAtt 'SFTPAssetsBucket.DomainName' -Parameters: - AdministratorIPAddress: - Default: 192.0.2.0/24 - Description: The IP address allowed to access containers. Defaults to TEST-NET-1 - (ie, no valid IP) - Type: String - AssetsBucketAccessControl: - AllowedValues: - - PublicRead - - Private - ConstraintDescription: Must be PublicRead or Private. - Default: PublicRead - Description: Canned ACL for the public S3 bucket. Private is recommended; it allows - for objects to be make publicly readable, but prevents listing of the bucket - contents. - Type: String - AssetsCloudFrontCertArn: - Default: '' - Description: >- - If (1) you specified a custom static media domain, (2) your stack is NOT in - the us-east-1 region, and (3) you wish to serve static media over HTTPS, you - must manually create an ACM certificate in the us-east-1 region and provide - its ARN here. - Type: String - AssetsCloudFrontDomain: - Default: '' - Description: A custom domain name (CNAME) for your CloudFront distribution, e.g., - "static.example.com". - Type: String - AssetsUseCloudFront: - AllowedValues: - - 'true' - - 'false' - Default: 'true' - Description: Whether or not to create a CloudFront distribution tied to the S3 - assets bucket. - Type: String - CacheNodeType: - AllowedValues: - - (none) - - cache.t2.micro - - cache.t2.small - - cache.t2.medium - - cache.t3.micro - - cache.t3.small - - cache.t3.medium - - cache.m3.medium - - cache.m3.large - - cache.m3.xlarge - - cache.m3.2xlarge - - cache.m4.large - - cache.m4.xlarge - - cache.m4.2xlarge - - cache.m4.4xlarge - - cache.m4.10xlarge - - cache.r4.large - - cache.r4.xlarge - - cache.r4.2xlarge - - cache.r4.4xlarge - - cache.r4.8xlarge - - cache.r4.16xlarge - - cache.r3.large - - cache.r3.xlarge - - cache.r3.2xlarge - - cache.r3.4xlarge - - cache.r3.8xlarge - ConstraintDescription: must select a valid cache node type. - Default: (none) - Description: Cache instance type - Type: String - ContainerInstanceType: - AllowedValues: - - t3a.nano - - t3a.micro - - t3a.small - - t3a.medium - - t3a.large - - t3a.xlarge - - t3a.2xlarge - - t3.nano - - t3.micro - - t3.small - - t3.medium - - t3.large - - t3.xlarge - - t3.2xlarge - - t2.nano - - t2.micro - - t2.small - - t2.medium - - t2.large - - t2.xlarge - - t2.2xlarge - - m5.large - - m5.xlarge - - m5.2xlarge - - m5.4xlarge - - m5.12xlarge - - m5.24xlarge - - m5d.large - - m5d.xlarge - - m5d.2xlarge - - m5d.4xlarge - - m5d.12xlarge - - m5d.24xlarge - - m4.large - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - - m4.10xlarge - - m4.16xlarge - - m3.medium - - m3.large - - m3.xlarge - - m3.2xlarge - - c5.large - - c5.xlarge - - c5.2xlarge - - c5.4xlarge - - c5.9xlarge - - c5.18xlarge - - c5d.large - - c5d.xlarge - - c5d.2xlarge - - c5d.4xlarge - - c5d.9xlarge - - c5d.18xlarge - - c4.large - - c4.xlarge - - c4.2xlarge - - c4.4xlarge - - c4.8xlarge - - c3.large - - c3.xlarge - - c3.2xlarge - - c3.4xlarge - - c3.8xlarge - - p2.xlarge - - p2.8xlarge - - p2.16xlarge - - g2.2xlarge - - g2.8xlarge - - x1.16large - - x1.32xlarge - - r5.large - - r5.xlarge - - r5.2xlarge - - r5.4xlarge - - r5.12xlarge - - r5.24xlarge - - r4.large - - r4.xlarge - - r4.2xlarge - - r4.4xlarge - - r4.8xlarge - - r4.16xlarge - - r3.large - - r3.xlarge - - r3.2xlarge - - r3.4xlarge - - r3.8xlarge - - i3.large - - i3.xlarge - - i3.2xlarge - - i3.4xlarge - - i3.8xlarge - - i3.16large - - d2.xlarge - - d2.2xlarge - - d2.4xlarge - - d2.8xlarge - - f1.2xlarge - - f1.16xlarge - Default: t3a.micro - Description: The application server instance type - Type: String - ContainerVolumeSize: - Default: '20' - Description: Size of instance EBS root volume (in GB) - Type: Number - CustomerManagedCmkArn: - Default: '' - Description: KMS CMK ARN to encrypt stack resources (except for public buckets). - Type: String - DatabaseAllocatedStorage: - ConstraintDescription: must be between 5 and 1024Gb. - Default: '20' - Description: The size of the database (Gb) - MaxValue: '1024' - MinValue: '5' - Type: Number - DatabaseBackupRetentionDays: - AllowedValues: - - '0' - - '1' - - '2' - - '3' - - '4' - - '5' - - '6' - - '7' - - '8' - - '9' - - '10' - - '11' - - '12' - - '13' - - '14' - - '15' - - '16' - - '17' - - '18' - - '19' - - '20' - - '21' - - '22' - - '23' - - '24' - - '25' - - '26' - - '27' - - '28' - - '29' - - '30' - - '31' - - '32' - - '33' - - '34' - - '35' - Default: '30' - Description: The number of days for which automated backups are retained. Setting - to 0 disables automated backups. - Type: Number - DatabaseClass: - AllowedValues: - - (none) - - db.r3.large - - db.r3.xlarge - - db.r3.2xlarge - - db.r3.4xlarge - - db.r3.8xlarge - - db.r4.large - - db.r4.xlarge - - db.r4.2xlarge - - db.r4.4xlarge - - db.r4.8xlarge - - db.r4.16xlarge - - db.r5.large - - db.r5.xlarge - - db.r5.2xlarge - - db.r5.4xlarge - - db.r5.8xlarge - - db.r5.12xlarge - - db.r5.16xlarge - - db.r5.24xlarge - - db.t2.micro - - db.t2.small - - db.t2.medium - - db.t2.large - - db.t3.micro - - db.t3.small - - db.t3.medium - - db.t3.large - - db.t3.xlarge - - db.t3.2xlarge - - db.m1.small - - db.m1.medium - - db.m1.large - - db.m1.xlarge - - db.m2.xlarge - - db.m2.2xlarge - - db.m2.4xlarge - - db.m3.medium - - db.m3.large - - db.m3.xlarge - - db.m3.2xlarge - - db.m4.large - - db.m4.xlarge - - db.m4.2xlarge - - db.m4.4xlarge - - db.m4.10xlarge - - db.m4.16xlarge - - db.m5.large - - db.m5.xlarge - - db.m5.2xlarge - - db.m5.4xlarge - - db.m5.8xlarge - - db.m5.12xlarge - - db.m5.16xlarge - - db.m5.24xlarge - ConstraintDescription: must select a valid database instance type. - Default: db.t3.micro - Description: Database instance class - Type: String - DatabaseCloudWatchLogTypes: - Default: '' - Description: A comma-separated list of the RDS log types (if any) to publish to - CloudWatch Logs. Note that log types are database engine-specific. - Type: CommaDelimitedList - DatabaseEngine: - AllowedValues: - - aurora - - mariadb - - mysql - - oracle-ee - - oracle-se2 - - oracle-se1 - - oracle-se - - postgres - - sqlserver-ee - - sqlserver-se - - sqlserver-ex - - sqlserver-web - ConstraintDescription: must select a valid database engine. - Default: postgres - Description: Database engine to use - Type: String - DatabaseEngineVersion: - Default: '' - Description: Database version to use - Type: String - DatabaseMultiAZ: - AllowedValues: - - 'true' - - 'false' - ConstraintDescription: must choose true or false. - Default: 'false' - Description: Whether or not to create a MultiAZ database - Type: String - DatabaseName: - AllowedPattern: '[a-zA-Z][a-zA-Z0-9_]*' - ConstraintDescription: must begin with a letter and contain only alphanumeric - characters. - Default: app - Description: Name of the database to create in the database server - MaxLength: '64' - MinLength: '1' - Type: String - DatabaseParameterGroupFamily: - AllowedValues: - - aurora-mysql5.7 - - docdb3.6 - - neptune1 - - aurora-postgresql9.6 - - aurora-postgresql10 - - mariadb10.0 - - mariadb10.1 - - mariadb10.2 - - mariadb10.3 - - mysql5.5 - - mysql5.6 - - mysql5.7 - - mysql8.0 - - oracle-ee-11.2 - - oracle-ee-12.1 - - oracle-ee-12.2 - - oracle-se-11.2 - - oracle-se1-11.2 - - oracle-se2-12.1 - - oracle-se2-12.2 - - aurora5.6 - - postgres9.3 - - postgres9.4 - - postgres9.5 - - postgres9.6 - - postgres10 - - postgres11 - - postgres12 - - sqlserver-ee-11.0 - - sqlserver-ee-12.0 - - sqlserver-ee-13.0 - - sqlserver-ee-14.0 - - sqlserver-ex-11.0 - - sqlserver-ex-12.0 - - sqlserver-ex-13.0 - - sqlserver-ex-14.0 - - sqlserver-se-11.0 - - sqlserver-se-12.0 - - sqlserver-se-13.0 - - sqlserver-se-14.0 - - sqlserver-web-11.0 - - sqlserver-web-12.0 - - sqlserver-web-13.0 - - sqlserver-web-14.0 - Description: Database parameter group family name; must match the engine and version - of the RDS instance. - Type: String - DatabasePassword: - AllowedPattern: '[ !#-.0-?A-~]*' - ConstraintDescription: must consist of 10-41 printable ASCII characters except - "/", """, or "@". - Description: The database admin account password must consist of 10-41 printableASCII - characters *except* "/", """, or "@". - MaxLength: '41' - MinLength: '10' - NoEcho: true - Type: String - DatabaseReplication: - AllowedValues: - - 'true' - - 'false' - Default: 'false' - Description: Whether to create a database server replica - WARNING this will fail - if DatabaseBackupRetentionDays is 0. - Type: String - DatabaseUser: - AllowedPattern: '[a-zA-Z][a-zA-Z0-9_]*' - ConstraintDescription: must begin with a letter and contain only alphanumeric - characters and underscores. - Default: app - Description: The database admin account username - MaxLength: '63' - MinLength: '1' - Type: String - DesiredScale: - Default: '2' - Description: Desired container instances count - Type: Number - DomainName: - Description: The fully-qualified domain name for the application. - Type: String - DomainNameAlternates: - Description: A comma-separated list of Alternate FQDNs to be included in the Subject - Alternative Name extension of the SSL certificate. - Type: CommaDelimitedList - ElasticsearchInstanceType: - AllowedValues: - - (none) - - t2.micro.elasticsearch - - t2.small.elasticsearch - - t2.medium.elasticsearch - - m3.medium.elasticsearch - - m3.large.elasticsearch - - m3.xlarge.elasticsearch - - m3.2xlarge.elasticsearch - - m4.large.elasticsearch - - m4.xlarge.elasticsearch - - m4.2xlarge.elasticsearch - - m4.4xlarge.elasticsearch - - m4.10xlarge.elasticsearch - - c4.large.elasticsearch - - c4.xlarge.elasticsearch - - c4.2xlarge.elasticsearch - - c4.4xlarge.elasticsearch - - c4.8xlarge.elasticsearch - - r3.large.elasticsearch - - r3.xlarge.elasticsearch - - r3.2xlarge.elasticsearch - - r3.4xlarge.elasticsearch - - r3.8xlarge.elasticsearch - - r4.large.elasticsearch - - r4.xlarge.elasticsearch - - r4.2xlarge.elasticsearch - - r4.4xlarge.elasticsearch - - r4.8xlarge.elasticsearch - - r4.16xlarge.elasticsearch - - i2.xlarge.elasticsearch - - i2.2xlarge.elasticsearch - ConstraintDescription: must select a valid Elasticsearch instance type. - Default: (none) - Description: 'Elasticsearch instance type. Note: not all types are supported in - all regions; see: http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-supported-instance-types.html' - Type: String - ElasticsearchVersion: - AllowedValues: - - '1.5' - - '2.3' - - '5.1' - - '5.3' - ConstraintDescription: must select a valid Elasticsearch version. - Default: '2.3' - Description: 'Elasticsearch version. Note: t2.micro.elasticsearch instances support - only versions 2.3 and 1.5.' - Type: String - ElasticsearchVolumeSize: - Default: '10' - Description: 'Elasticsearch EBS volume size, in GB. Note: maximum volume size - varies by instance type; see: http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/aes-limits.html#ebsresource.' - MaxValue: '1536' - MinValue: '10' - Type: Number - MaxScale: - Default: '4' - Description: Maximum container instances count - Type: Number - PrimaryAZ: - Description: The primary availability zone for creating resources. - Type: AWS::EC2::AvailabilityZone::Name - PrivateSubnetACidr: - AllowedPattern: >- - ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: Must be a private IPv4 range with size /16 and /28. - Default: 10.0.8.0/22 - Description: IPv4 CIDR block for the private subnet in the primary AZ. [Possibly - not modifiable after stack creation] - Type: String - PrivateSubnetBCidr: - AllowedPattern: >- - ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: Must be a private IPv4 range with size /16 and /28. - Default: 10.0.12.0/22 - Description: IPv4 CIDR block for the private subnet in the secondary AZ. [Possibly - not modifiable after stack creation] - Type: String - PublicSubnetACidr: - AllowedPattern: >- - ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: Must be a private IPv4 range with size /16 and /28. - Default: 10.0.0.0/22 - Description: IPv4 CIDR block for the public subnet in the primary AZ. [Possibly - not modifiable after stack creation] - Type: String - PublicSubnetBCidr: - AllowedPattern: >- - ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: Must be a private IPv4 range with size /16 and /28. - Default: 10.0.4.0/22 - Description: IPv4 CIDR block for the public subnet in the secondary AZ. [Possibly - not modifiable after stack creation] - Type: String - RedisAuthToken: - AllowedPattern: '[ !#-.0-?A-~]*' - ConstraintDescription: must consist of 16-128 printable ASCII characters except - "/", """, or "@". - Default: DO_NOT_CREATE_AUTH_TOKEN - Description: The password used to access a Redis ReplicationGroup (required for - HIPAA). - MaxLength: '128' - MinLength: '16' - NoEcho: true - Type: String - RedisAutomaticFailover: - AllowedValues: - - 'true' - - 'false' - Default: 'false' - Description: Specifies whether a read-only replica is automatically promoted to - read/write primary if the existing primary fails. - Type: String - RedisNodeType: - AllowedValues: - - (none) - - cache.t2.micro - - cache.t2.small - - cache.t2.medium - - cache.t3.micro - - cache.t3.small - - cache.t3.medium - - cache.m3.medium - - cache.m3.large - - cache.m3.xlarge - - cache.m3.2xlarge - - cache.m4.large - - cache.m4.xlarge - - cache.m4.2xlarge - - cache.m4.4xlarge - - cache.m4.10xlarge - - cache.r4.large - - cache.r4.xlarge - - cache.r4.2xlarge - - cache.r4.4xlarge - - cache.r4.8xlarge - - cache.r4.16xlarge - - cache.r3.large - - cache.r3.xlarge - - cache.r3.2xlarge - - cache.r3.4xlarge - - cache.r3.8xlarge - ConstraintDescription: must select a valid cache node type. - Default: (none) - Description: Redis instance type - Type: String - RedisNumCacheClusters: - Default: '1' - Description: The number of clusters this replication group initially has. - Type: Number - RedisSnapshotRetentionLimit: - Default: '0' - Description: >- - The number of days for which ElastiCache retains automatic snapshots before - deleting them.For example, if you set SnapshotRetentionLimit to 5, a snapshot - that was taken today is retained for 5 days before being deleted. 0 = automatic - backups are disabled for this cluster. - Type: Number - RedisVersion: - Default: '' - Description: 'Redis version to use. See available versions: aws elasticache describe-cache-engine-versions' - Type: String - SecondaryAZ: - Description: The secondary availability zone for creating resources. Must differ - from primary zone. - Type: AWS::EC2::AvailabilityZone::Name - UseAES256Encryption: - AllowedValues: - - 'true' - - 'false' - Default: 'false' - Description: Whether or not to use server side encryption for S3, EBS, and RDS. - When true, encryption is enabled for all resources. - Type: String - UseSFTPServer: - AllowedValues: - - 'true' - - 'false' - Default: 'false' - Description: Whether or not to set up an SFTP service. If 'true', this will set - up a transfer server and add an S3 bucket for its use, along with a role and - policies for use when adding users. - Type: String - VpcCidr: - AllowedPattern: >- - ^((10\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)|(172\.(1[6-9]|2[0-9]|3[0-1])\.)|192\.168\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: Must be a private IPv4 range with size /16 and /28. - Default: 10.0.0.0/20 - Description: The primary IPv4 CIDR block for the VPC. [Possibly not modifiable - after stack creation] - Type: String -Resources: - ApplicationRepository: - Properties: - ImageScanningConfiguration: - ScanOnPush: 'true' - RepositoryPolicyText: - Statement: - - Action: - - ecr:GetDownloadUrlForLayer - - ecr:BatchGetImage - - ecr:BatchCheckLayerAvailability - - ecr:PutImage - - ecr:InitiateLayerUpload - - ecr:UploadLayerPart - - ecr:CompleteLayerUpload - Effect: Allow - Principal: - AWS: - - !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':iam::' - - !Ref 'AWS::AccountId' - - :root - Sid: AllowPushPull - Version: '2008-10-17' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - Type: AWS::ECR::Repository - AssetsBucket: - DeletionPolicy: Retain - Properties: - AccessControl: !Ref 'AssetsBucketAccessControl' - BucketEncryption: !If - - UseAES256EncryptionCond - - ServerSideEncryptionConfiguration: - - ServerSideEncryptionByDefault: - SSEAlgorithm: AES256 - - !Ref 'AWS::NoValue' - CorsConfiguration: - CorsRules: - - AllowedHeaders: - - '*' - AllowedMethods: - - POST - - PUT - - HEAD - - GET - AllowedOrigins: !Split - - ; - - !Join - - '' - - - https:// - - !Ref 'DomainName' - - !If - - NoAlternateDomains - - '' - - ;https:// - - !Join - - ;https:// - - !Ref 'DomainNameAlternates' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - VersioningConfiguration: - Status: Enabled - Type: AWS::S3::Bucket - AssetsCertificate: - Condition: AssetsCreateCertificateCondition - Properties: - DomainName: !Ref 'AssetsCloudFrontDomain' - DomainValidationOptions: - - DomainName: !Ref 'AssetsCloudFrontDomain' - ValidationDomain: !Ref 'AssetsCloudFrontDomain' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - Type: AWS::CertificateManager::Certificate - AssetsDistribution: - Condition: AssetsUseCloudFrontCondition - Properties: - DistributionConfig: - Aliases: !If - - AssetsCloudFrontDomainCondition - - - !Ref 'AssetsCloudFrontDomain' - - !Ref 'AWS::NoValue' - DefaultCacheBehavior: - ForwardedValues: - Headers: - - Origin - - Access-Control-Request-Headers - - Access-Control-Request-Method - QueryString: 'true' - TargetOriginId: Assets - ViewerProtocolPolicy: allow-all - Enabled: 'true' - Origins: - - DomainName: !GetAtt 'AssetsBucket.DomainName' - Id: Assets - S3OriginConfig: - OriginAccessIdentity: '' - ViewerCertificate: !If - - AssetsCreateCertificateCondition - - AcmCertificateArn: !Ref 'AssetsCertificate' - SslSupportMethod: sni-only - - !If - - AssetsCloudFrontCertArnCondition - - AcmCertificateArn: !Ref 'AssetsCloudFrontCertArn' - SslSupportMethod: sni-only - - !Ref 'AWS::NoValue' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - Type: AWS::CloudFront::Distribution - CacheCluster: - Condition: UsingMemcached - Properties: - CacheNodeType: !Ref 'CacheNodeType' - CacheSubnetGroupName: !Ref 'CacheSubnetGroup' - Engine: memcached - NumCacheNodes: 1 - Port: 11211 - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - cache - VpcSecurityGroupIds: - - !Ref 'CacheSecurityGroup' - Type: AWS::ElastiCache::CacheCluster - CacheSecurityGroup: - Condition: EitherCacheCondition - Properties: - GroupDescription: Cache security group. - SecurityGroupIngress: - - !If - - UsingMemcached - - CidrIp: !Ref 'PrivateSubnetACidr' - FromPort: 11211 - IpProtocol: tcp - ToPort: 11211 - - !Ref 'AWS::NoValue' - - !If - - UsingMemcached - - CidrIp: !Ref 'PrivateSubnetBCidr' - FromPort: 11211 - IpProtocol: tcp - ToPort: 11211 - - !Ref 'AWS::NoValue' - - !If - - UsingRedis - - CidrIp: !Ref 'PrivateSubnetACidr' - FromPort: 6379 - IpProtocol: tcp - ToPort: 6379 - - !Ref 'AWS::NoValue' - - !If - - UsingRedis - - CidrIp: !Ref 'PrivateSubnetBCidr' - FromPort: 6379 - IpProtocol: tcp - ToPort: 6379 - - !Ref 'AWS::NoValue' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - cache - VpcId: !Ref 'Vpc' - Type: AWS::EC2::SecurityGroup - CacheSubnetGroup: - Condition: EitherCacheCondition - Properties: - Description: Subnets available for the cache instance - SubnetIds: - - !Ref 'PrivateSubnetA' - - !Ref 'PrivateSubnetB' - Type: AWS::ElastiCache::SubnetGroup - ContainerInstanceProfile: - Properties: - Path: / - Roles: - - !Ref 'ContainerInstanceRole' - Type: AWS::IAM::InstanceProfile - ContainerInstanceRole: - Properties: - AssumeRolePolicyDocument: - Statement: - - Action: - - sts:AssumeRole - Effect: Allow - Principal: - Service: - - ec2.amazonaws.com - ManagedPolicyArns: - - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy - - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly - - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy - - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy - Path: / - Policies: - - PolicyDocument: - Statement: !If - - UseSFTPServerCondition - - - Action: - - s3:ListBucket - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'AssetsBucket' - - Action: - - s3:* - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'AssetsBucket' - - /* - - Action: - - s3:ListBucket - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'PrivateAssetsBucket' - - Action: - - s3:* - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'PrivateAssetsBucket' - - /* - - Action: - - s3:ListBucket - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'SFTPAssetsBucket' - - Action: - - s3:* - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'SFTPAssetsBucket' - - /* - - - Action: - - s3:ListBucket - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'AssetsBucket' - - Action: - - s3:* - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'AssetsBucket' - - /* - - Action: - - s3:ListBucket - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'PrivateAssetsBucket' - - Action: - - s3:* - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'PrivateAssetsBucket' - - /* - PolicyName: AssetsManagementPolicy - - PolicyDocument: - Statement: - - Action: - - logs:Create* - - logs:PutLogEvents - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - :logs:*:*:* - PolicyName: LoggingPolicy - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - Type: AWS::IAM::Role - ContainerLogs: - DeletionPolicy: Retain - Properties: - RetentionInDays: 365 - Type: AWS::Logs::LogGroup - DatabaseInstance: - Condition: DatabaseCondition - DeletionPolicy: Snapshot - Properties: - AllocatedStorage: !Ref 'DatabaseAllocatedStorage' - BackupRetentionPeriod: !Ref 'DatabaseBackupRetentionDays' - DBInstanceClass: !Ref 'DatabaseClass' - DBName: !Ref 'DatabaseName' - DBParameterGroupName: !Ref 'DatabaseParameterGroup' - DBSubnetGroupName: !Ref 'DatabaseSubnetGroup' - EnableCloudwatchLogsExports: !If - - DatabaseLoggingCondition - - !Ref 'DatabaseCloudWatchLogTypes' - - !Ref 'AWS::NoValue' - Engine: !Ref 'DatabaseEngine' - EngineVersion: !Ref 'DatabaseEngineVersion' - KmsKeyId: !If - - CmkArnCondition - - !Ref 'CustomerManagedCmkArn' - - !Ref 'AWS::NoValue' - MasterUserPassword: !Ref 'DatabasePassword' - MasterUsername: !Ref 'DatabaseUser' - MultiAZ: !Ref 'DatabaseMultiAZ' - StorageEncrypted: !Ref 'UseAES256Encryption' - StorageType: gp2 - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - VPCSecurityGroups: - - !Ref 'DatabaseSecurityGroup' - Type: AWS::RDS::DBInstance - DatabaseParameterGroup: - Condition: DatabaseCondition - Properties: - Description: Database parameter group. - Family: !Ref 'DatabaseParameterGroupFamily' - Parameters: {} - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - Type: AWS::RDS::DBParameterGroup - DatabaseReplica: - Condition: DatabaseReplicationCondition - Properties: - DBInstanceClass: !Ref 'DatabaseClass' - Engine: !Ref 'DatabaseEngine' - SourceDBInstanceIdentifier: !Ref 'DatabaseInstance' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - VPCSecurityGroups: - - !Ref 'DatabaseSecurityGroup' - Type: AWS::RDS::DBInstance - DatabaseSecurityGroup: - Condition: DatabaseCondition - Properties: - GroupDescription: Database security group. - SecurityGroupIngress: - - CidrIp: !Ref 'PrivateSubnetACidr' - FromPort: !FindInMap - - RdsEngineMap - - !Ref 'DatabaseEngine' - - Port - IpProtocol: tcp - ToPort: !FindInMap - - RdsEngineMap - - !Ref 'DatabaseEngine' - - Port - - CidrIp: !Ref 'PrivateSubnetBCidr' - FromPort: !FindInMap - - RdsEngineMap - - !Ref 'DatabaseEngine' - - Port - IpProtocol: tcp - ToPort: !FindInMap - - RdsEngineMap - - !Ref 'DatabaseEngine' - - Port - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - rds - VpcId: !Ref 'Vpc' - Type: AWS::EC2::SecurityGroup - DatabaseSubnetGroup: - Condition: DatabaseCondition - Properties: - DBSubnetGroupDescription: Subnets available for the RDS DB Instance - SubnetIds: - - !Ref 'PrivateSubnetA' - - !Ref 'PrivateSubnetB' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - Type: AWS::RDS::DBSubnetGroup - EksCluster: - Properties: - Name: !Sub '${AWS::StackName}-cluster' - ResourcesVpcConfig: - SecurityGroupIds: - - !Ref 'EksClusterSecurityGroup' - SubnetIds: - - !Ref 'PublicSubnetA' - - !Ref 'PublicSubnetB' - - !Ref 'PrivateSubnetA' - - !Ref 'PrivateSubnetB' - RoleArn: !GetAtt 'EksServiceRole.Arn' - Type: AWS::EKS::Cluster - EksClusterSecurityGroup: - Properties: - GroupDescription: EKS control plane security group. - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - eks-cluster - VpcId: !Ref 'Vpc' - Type: AWS::EC2::SecurityGroup - EksServiceRole: - Properties: - AssumeRolePolicyDocument: - Statement: - - Action: - - sts:AssumeRole - Effect: Allow - Principal: - Service: - - eks.amazonaws.com - ManagedPolicyArns: - - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy - - arn:aws:iam::aws:policy/AmazonEKSServicePolicy - Path: / - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - Type: AWS::IAM::Role - ElasticsearchDomain: - Condition: Elasticsearch - Properties: - AccessPolicies: - Statement: - - Action: - - es:* - Effect: Allow - Principal: - AWS: - - !GetAtt 'ContainerInstanceRole.Arn' - EBSOptions: - EBSEnabled: 'true' - VolumeSize: !Ref 'ElasticsearchVolumeSize' - ElasticsearchClusterConfig: - InstanceType: !Ref 'ElasticsearchInstanceType' - ElasticsearchVersion: !Ref 'ElasticsearchVersion' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - Type: AWS::Elasticsearch::Domain - GatewayAttachement: - Properties: - InternetGatewayId: !Ref 'InternetGateway' - VpcId: !Ref 'Vpc' - Type: AWS::EC2::VPCGatewayAttachment - InternetGateway: - Properties: - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - igw - Type: AWS::EC2::InternetGateway - Nodegroup: - DependsOn: - - EksCluster - Properties: - ClusterName: !Ref 'EksCluster' - DiskSize: !Ref 'ContainerVolumeSize' - InstanceTypes: - - !Ref 'ContainerInstanceType' - NodeRole: !GetAtt 'ContainerInstanceRole.Arn' - ScalingConfig: - DesiredSize: !Ref 'DesiredScale' - MaxSize: !Ref 'MaxScale' - MinSize: 2 - Subnets: - - !Ref 'PrivateSubnetA' - - !Ref 'PrivateSubnetB' - Tags: - aws-web-stacks:stack-name: !Ref 'AWS::StackName' - Type: AWS::EKS::Nodegroup - PrivateAssetsBucket: - DeletionPolicy: Retain - Properties: - AccessControl: Private - BucketEncryption: !If - - UseAES256EncryptionCond - - ServerSideEncryptionConfiguration: - - ServerSideEncryptionByDefault: - KMSMasterKeyID: !If - - CmkArnCondition - - !Ref 'CustomerManagedCmkArn' - - !Ref 'AWS::NoValue' - SSEAlgorithm: !If - - CmkArnCondition - - aws:kms - - AES256 - - !Ref 'AWS::NoValue' - CorsConfiguration: - CorsRules: - - AllowedHeaders: - - '*' - AllowedMethods: - - POST - - PUT - - HEAD - - GET - AllowedOrigins: !Split - - ; - - !Join - - '' - - - https:// - - !Ref 'DomainName' - - !If - - NoAlternateDomains - - '' - - ;https:// - - !Join - - ;https:// - - !Ref 'DomainNameAlternates' - PublicAccessBlockConfiguration: - BlockPublicAcls: 'true' - BlockPublicPolicy: 'true' - IgnorePublicAcls: 'true' - RestrictPublicBuckets: 'true' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - VersioningConfiguration: - Status: Enabled - Type: AWS::S3::Bucket - PrivateSubnetA: - Properties: - AvailabilityZone: !Ref 'PrimaryAZ' - CidrBlock: !Ref 'PrivateSubnetACidr' - MapPublicIpOnLaunch: 'true' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - private-a - - Key: kubernetes.io/role/internal-elb - Value: '1' - VpcId: !Ref 'Vpc' - Type: AWS::EC2::Subnet - PrivateSubnetARouteTableAssociation: - Properties: - RouteTableId: !Ref 'PublicRouteTable' - SubnetId: !Ref 'PrivateSubnetA' - Type: AWS::EC2::SubnetRouteTableAssociation - PrivateSubnetB: - Properties: - AvailabilityZone: !Ref 'SecondaryAZ' - CidrBlock: !Ref 'PrivateSubnetBCidr' - MapPublicIpOnLaunch: 'true' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - private-b - - Key: kubernetes.io/role/internal-elb - Value: '1' - VpcId: !Ref 'Vpc' - Type: AWS::EC2::Subnet - PrivateSubnetBRouteTableAssociation: - Properties: - RouteTableId: !Ref 'PublicRouteTable' - SubnetId: !Ref 'PrivateSubnetB' - Type: AWS::EC2::SubnetRouteTableAssociation - PublicRoute: - Properties: - DestinationCidrBlock: '0.0.0.0/0' - GatewayId: !Ref 'InternetGateway' - RouteTableId: !Ref 'PublicRouteTable' - Type: AWS::EC2::Route - PublicRouteTable: - Properties: - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - public - VpcId: !Ref 'Vpc' - Type: AWS::EC2::RouteTable - PublicSubnetA: - Properties: - AvailabilityZone: !Ref 'PrimaryAZ' - CidrBlock: !Ref 'PublicSubnetACidr' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - public-a - - Key: kubernetes.io/role/elb - Value: '1' - VpcId: !Ref 'Vpc' - Type: AWS::EC2::Subnet - PublicSubnetARouteTableAssociation: - Properties: - RouteTableId: !Ref 'PublicRouteTable' - SubnetId: !Ref 'PublicSubnetA' - Type: AWS::EC2::SubnetRouteTableAssociation - PublicSubnetB: - Properties: - AvailabilityZone: !Ref 'SecondaryAZ' - CidrBlock: !Ref 'PublicSubnetBCidr' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - public-b - - Key: kubernetes.io/role/elb - Value: '1' - VpcId: !Ref 'Vpc' - Type: AWS::EC2::Subnet - PublicSubnetBRouteTableAssociation: - Properties: - RouteTableId: !Ref 'PublicRouteTable' - SubnetId: !Ref 'PublicSubnetB' - Type: AWS::EC2::SubnetRouteTableAssociation - RedisReplicationGroup: - Condition: UsingRedis - Properties: - AtRestEncryptionEnabled: !Ref 'UseAES256Encryption' - AuthToken: !If - - AuthTokenCondition - - !Ref 'RedisAuthToken' - - !Ref 'AWS::NoValue' - AutomaticFailoverEnabled: !Ref 'RedisAutomaticFailover' - CacheNodeType: !Ref 'RedisNodeType' - CacheSubnetGroupName: !Ref 'CacheSubnetGroup' - Engine: redis - EngineVersion: !Ref 'RedisVersion' - KmsKeyId: !If - - CmkArnCondition - - !Ref 'CustomerManagedCmkArn' - - !Ref 'AWS::NoValue' - MultiAZEnabled: !Ref 'RedisAutomaticFailover' - NumCacheClusters: !Ref 'RedisNumCacheClusters' - Port: 6379 - PreferredCacheClusterAZs: !If - - RedisAutomaticFailoverCondition - - - !Ref 'PrimaryAZ' - - !Ref 'SecondaryAZ' - - !Ref 'AWS::NoValue' - ReplicationGroupDescription: Redis ReplicationGroup - SecurityGroupIds: - - !Ref 'CacheSecurityGroup' - SnapshotRetentionLimit: !Ref 'RedisSnapshotRetentionLimit' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - redis - TransitEncryptionEnabled: !Ref 'UseAES256Encryption' - Type: AWS::ElastiCache::ReplicationGroup - SFTPAssetsBucket: - DeletionPolicy: Retain - Properties: - AccessControl: Private - BucketEncryption: !If - - UseAES256EncryptionCond - - ServerSideEncryptionConfiguration: - - ServerSideEncryptionByDefault: - KMSMasterKeyID: !If - - CmkArnCondition - - !Ref 'CustomerManagedCmkArn' - - !Ref 'AWS::NoValue' - SSEAlgorithm: !If - - CmkArnCondition - - aws:kms - - AES256 - - !Ref 'AWS::NoValue' - CorsConfiguration: - CorsRules: - - AllowedHeaders: - - '*' - AllowedMethods: - - POST - - PUT - - HEAD - - GET - AllowedOrigins: !Split - - ; - - !Join - - '' - - - https:// - - !Ref 'DomainName' - - !If - - NoAlternateDomains - - '' - - ;https:// - - !Join - - ;https:// - - !Ref 'DomainNameAlternates' - PublicAccessBlockConfiguration: - BlockPublicAcls: 'true' - BlockPublicPolicy: 'true' - IgnorePublicAcls: 'true' - RestrictPublicBuckets: 'true' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - VersioningConfiguration: - Status: Enabled - Type: AWS::S3::Bucket - SFTPUserRole: - Condition: UseSFTPServerCondition - Properties: - AssumeRolePolicyDocument: - Statement: - - Action: - - sts:AssumeRole - Effect: Allow - Principal: - Service: - - transfer.amazonaws.com - Policies: - - PolicyDocument: - Statement: !If - - UseSFTPWithKMSCondition - - - Action: - - s3:ListBucket - - s3:GetBucketLocation - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'SFTPAssetsBucket' - - Action: - - s3:PutObject - - s3:GetObject - - s3:DeleteObject - - s3:DeleteObjectVersion - - s3:GetObjectVersion - - s3:GetObjectACL - - s3:PutObjectACL - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'SFTPAssetsBucket' - - /* - - Action: - - kms:DescribeKey - - kms:GenerateDataKey - - kms:Encrypt - - kms:Decrypt - Effect: Allow - Resource: !Ref 'CustomerManagedCmkArn' - - - Action: - - s3:ListBucket - - s3:GetBucketLocation - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'SFTPAssetsBucket' - - Action: - - s3:PutObject - - s3:GetObject - - s3:DeleteObject - - s3:DeleteObjectVersion - - s3:GetObjectVersion - - s3:GetObjectACL - - s3:PutObjectACL - Effect: Allow - Resource: !Join - - '' - - - !If - - InGovCloudRegion - - arn:aws-us-gov - - arn:aws - - ':s3:::' - - !Ref 'SFTPAssetsBucket' - - /* - Version: '2012-10-17' - PolicyName: SFTPSUserRolePolicy - RoleName: !Join - - '-' - - - !Ref 'AWS::StackName' - - SFTPUserRole - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - Type: AWS::IAM::Role - SFTPUserScopeDownPolicy: - Condition: UseSFTPServerCondition - Properties: - PolicyDocument: - Statement: !If - - UseSFTPWithKMSCondition - - - Action: - - s3:ListBucket - Condition: - StringLike: - s3:prefix: - - ${transfer:UserName}/* - - ${transfer:UserName} - Effect: Allow - Resource: - - arn:aws:s3:::${transfer:HomeBucket} - Sid: AllowListingOfSFTPUserFolder - - Action: - - s3:PutObject - - s3:GetObject - - s3:DeleteObjectVersion - - s3:DeleteObject - - s3:GetObjectVersion - Effect: Allow - Resource: - - !Join - - / - - - !GetAtt 'SFTPAssetsBucket.Arn' - - ${transfer:UserName} - - !Join - - / - - - !GetAtt 'SFTPAssetsBucket.Arn' - - ${transfer:UserName}/* - Sid: HomeDirObjectAccess - - Action: - - kms:DescribeKey - - kms:GenerateDataKey - - kms:Encrypt - - kms:Decrypt - Effect: Allow - Resource: !Ref 'CustomerManagedCmkArn' - - - Action: - - s3:ListBucket - Condition: - StringLike: - s3:prefix: - - ${transfer:UserName}/* - - ${transfer:UserName} - Effect: Allow - Resource: - - arn:aws:s3:::${transfer:HomeBucket} - Sid: AllowListingOfSFTPUserFolder - - Action: - - s3:PutObject - - s3:GetObject - - s3:DeleteObjectVersion - - s3:DeleteObject - - s3:GetObjectVersion - Effect: Allow - Resource: - - !Join - - / - - - !GetAtt 'SFTPAssetsBucket.Arn' - - ${transfer:UserName} - - !Join - - / - - - !GetAtt 'SFTPAssetsBucket.Arn' - - ${transfer:UserName}/* - Sid: HomeDirObjectAccess - Version: '2012-10-17' - Type: AWS::IAM::ManagedPolicy - TransferServer: - Condition: UseSFTPServerCondition - Properties: - EndpointType: PUBLIC - IdentityProviderType: SERVICE_MANAGED - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - sftp - Type: AWS::Transfer::Server - Vpc: - Properties: - CidrBlock: !Ref 'VpcCidr' - EnableDnsHostnames: 'true' - EnableDnsSupport: 'true' - Tags: - - Key: aws-web-stacks:stack-name - Value: !Ref 'AWS::StackName' - - Key: Name - Value: !Join - - '-' - - - !Ref 'AWS::StackName' - - vpc - Type: AWS::EC2::VPC From a2e23f8c1b7f75f11bf435b19452b71072626565 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 15 Aug 2024 12:29:51 -0400 Subject: [PATCH 10/43] Begin config to add Github Runner --- README.md | 29 +++++++ deploy/deploy-runner.yml | 152 ++++++++++++++++++++++++++++++++++++ deploy/group_vars/all.yml | 10 ++- deploy/host_vars/runner.yml | 35 +++++++++ 4 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 deploy/deploy-runner.yml create mode 100644 deploy/host_vars/runner.yml diff --git a/README.md b/README.md index 1327fe3f..f57d3093 100644 --- a/README.md +++ b/README.md @@ -294,3 +294,32 @@ To reset your local database from a deployed environment: As mentioned in the Database setup instructions, you may need to visit [/cms/sites](http://localhost:8000/cms/sites/) and change the first entry's `Hostname` field to `localhost` to enable page previews in the Wagtail admin. + +### GitHub Actions Runner + +There are [GitHub Actions self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners) deployed on a virtual machine within the same VPC. Other runners may be added in the future, if needed. + +Setup instructions: + +* Obtain a [GitHub PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) with the `admin:org` scope that's valid for one week (it needs to be active only for the initial deployment). Add this to a local environment variable `RUNNER_CFG_PAT`: + +```sh +export RUNNER_CFG_PAT="gh......" +``` + +* Run the playbook to deploy the runner: + +```sh +ansible-playbook deploy-runner.yml +``` + +* The runner can be forcibly reinstalled by passing `-e force_reinstall=yes` or removed by passing `-e force_removal=yes`. + +Run OS updates: + +```sh +cd deploy/ +ansible-playbook run-os-updates.yml +# You may need to specify your username +ansible-playbook -u myusername run-os-updates.yaml +``` \ No newline at end of file diff --git a/deploy/deploy-runner.yml b/deploy/deploy-runner.yml new file mode 100644 index 00000000..ddcce4d2 --- /dev/null +++ b/deploy/deploy-runner.yml @@ -0,0 +1,152 @@ +--- +- hosts: runner + become: yes + tags: base + roles: + - caktus.hosting_services.users + tasks: + - name: Set hostname + hostname: + name: "{{ inventory_hostname_short }}" + when: inventory_hostname_short is defined and inventory_hostname_short + - name: Add new hostname to /etc/hosts + lineinfile: + path: /etc/hosts + regexp: '^127\.0\.1\.1' + line: '127.0.1.1 {{ inventory_hostname_short }}' + owner: root + group: root + mode: 0644 + when: inventory_hostname_short is defined and inventory_hostname_short + +- name: Install GitHub Actions Runner + hosts: runner + tags: runner + become: yes + tasks: + - name: Create runner user + ansible.builtin.user: + name: "{{ github_runner_user }}" + comment: Github Actions Runner + # Install Docker + # https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository + - name: Install dependencies + ansible.builtin.package: + name: + - jq + - ca-certificates + - curl + - gnupg + - lsb-release + - name: Add Docker's official GPG key + ansible.builtin.apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + state: present + - name: Add Docker repository + ansible.builtin.apt_repository: + repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable + state: present + - name: Install Docker Engine + ansible.builtin.package: + name: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin + update_cache: yes + - name: Task name + stat: + path: /home/{{ github_runner_user }}/runner + register: runner_dir + - name: Set vars + set_fact: + run_removal_tasks: >- + {{ + runner_dir.stat.exists + and ( + (force_reinstall is defined and force_reinstall == "yes") + or (force_removal is defined and force_removal == "yes") + ) + }} + # Various complicated Ansible roles exist, but this just works: + # https://github.com/actions/runner/blob/main/docs/automate.md + - name: Remove the runner + ansible.builtin.shell: + cmd: > + curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/remove-svc.sh + | bash -s {{ github_scope }} + chdir: /home/{{ github_runner_user }} + environment: + RUNNER_CFG_PAT: "{{ github_pat }}" + when: run_removal_tasks + ignore_errors: True + - name: Delete the runner + ansible.builtin.shell: + cmd: > + curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/delete.sh + | bash -s {{ github_scope }} {{ github_runner_name }} + chdir: /home/{{ github_runner_user }} + environment: + RUNNER_CFG_PAT: "{{ github_pat }}" + when: run_removal_tasks + ignore_errors: True + - name: Remove old runner directory and files + ansible.builtin.file: + path: "{{ item }}" + state: absent + loop: + - /home/{{ github_runner_user }}/runner + when: run_removal_tasks + - name: Add user '{{ github_runner_user }}' to group docker + user: + name: "{{ github_runner_user }}" + groups: docker + append: yes + - name: Restart docker service + ansible.builtin.service: + name: docker + state: restarted + # Poetry + - name: Install Poetry dependencies + ansible.builtin.package: + name: + - acl + - python3-pip + - python3-venv + - name: Install pipx Python package + ansible.builtin.pip: + name: pipx + - name: Install poetry + community.general.pipx: + name: poetry + state: present + environment: + PIPX_HOME: /opt/pipx + PIPX_BIN_DIR: /usr/local/bin + - name: Install pipx + ansible.builtin.shell: + cmd: | + python3 -m pip install --user pipx + python3 -m pipx ensurepath + chdir: /home/{{ github_runner_user }} + become_user: "{{ github_runner_user }}" + - name: Install Poetry + ansible.builtin.shell: + cmd: | + pipx install poetry + chdir: /home/{{ github_runner_user }} + become_user: "{{ github_runner_user }}" + - name: Install the runner [If error, RUNNER_CFG_PAT might be missing or expired! See README.md] + ansible.builtin.shell: + cmd: > + curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/create-latest-svc.sh + | bash -s -- + -s {{ github_scope }} + -n {{ github_runner_name }} + -l {{ github_runner_location }},self-hosted + -u {{ github_runner_user }} + chdir: /home/{{ github_runner_user }} + environment: + RUNNER_CFG_PAT: "{{ github_pat }}" + when: (not runner_dir.stat.exists) or (force_reinstall is defined and force_reinstall=="yes") \ No newline at end of file diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index 3fc357b2..b51e7b26 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -17,6 +17,9 @@ ansible_python_interpreter: "{{ ansible_playbook_python }}" k8s_cluster_name: "{{ cluster_name }}" k8s_namespace: "{{ app_name }}-{{ env_name }}" +# Caktus office IP address +administrator_ip_cidr: "70.62.97.170/32" + # CloudFormation Outputs # These values are taken from the CF 'Output' tab # aws eks describe-cluster --name=philly-hip-stack-cluster | grep endpoint @@ -51,6 +54,11 @@ cloudformation_stack: template_parameters: UseAES256Encryption: "true" + AdministratorIPAddress: "{{ administrator_ip_cidr }}" + BastionAMI: "" # Needed - don't know how to get it. + BastionKeyName: ron_hip + BastionInstanceType: t3.small # Is this a proper size? + BastionType: SSH CustomerManagedCmkArn: "" DomainName: "{{ app_name }}-prod.caktus-built.com" DomainNameAlternates: "" @@ -69,7 +77,7 @@ cloudformation_stack: DatabasePassword: "{{ admin_database_password }}" DatabaseMultiAZ: "true" EksClusterName: "philly-hip-stack-cluster" - EksPublicAccessCidrs: "107.15.45.253/32,47.230.11.28/32" + EksPublicAccessCidrs: " {{ administrator_ip_cidr }}" tags: Environment: "{{ app_name }}" diff --git a/deploy/host_vars/runner.yml b/deploy/host_vars/runner.yml new file mode 100644 index 00000000..23c68172 --- /dev/null +++ b/deploy/host_vars/runner.yml @@ -0,0 +1,35 @@ +--- +## users role configuration ## +users_groups: [adm, dialout, docker, sudo] +users_shell: /bin/bash + +# when removing a user, add their username to this list: +users_remove: + # Remove default user installed by Ubuntu. You might need to comment this out + # temporarily when first configuring a server, and possibly even reboot the + # server before the user can be removed. + - ubuntu + +# users to provision on all servers +# find your ssh key with: `cat ~/.ssh/id_*.pub` (should be one line) +# optionally generate password via `mkpasswd -m sha-512 -R 2000000` +users: + # in alphabetical order + - username: copelco + authorized_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICMtpiB+QFK/YDEx3qiq62zUcxKOiuIOe1CNmD+NQYKt copelco@caktusgroup.com + - username: ronardlunagerman + authorized_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEhNwSFktLJpdP/e04FPZxEwXsZyqTi8URd2IBjuw0Je rluna@caktusgroup.com + - username: tobias + authorized_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFti2WxKH5TJh6SN44pkvG2V4268sJfirn00YrKLy+lY tobias@red-ed25519 + +# On GitHub +github_pat: "{{ lookup('env', 'RUNNER_CFG_PAT') }}" +github_scope: caktus + +# On the VM +github_runner_user: runner +github_runner_name: philly-hip-runner +github_runner_location: philly-hip \ No newline at end of file From 90b7107f784d6af7687e192a46b42d10cfb335bb Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Fri, 23 Aug 2024 13:45:27 -0400 Subject: [PATCH 11/43] Make changes so runner deploys --- deploy/deploy-runner.yml | 30 ------------------------------ deploy/group_vars/all.yml | 20 ++++++++++++-------- deploy/inventory | 2 ++ deploy/requirements.yml | 3 +++ 4 files changed, 17 insertions(+), 38 deletions(-) diff --git a/deploy/deploy-runner.yml b/deploy/deploy-runner.yml index ddcce4d2..58710f80 100644 --- a/deploy/deploy-runner.yml +++ b/deploy/deploy-runner.yml @@ -107,36 +107,6 @@ ansible.builtin.service: name: docker state: restarted - # Poetry - - name: Install Poetry dependencies - ansible.builtin.package: - name: - - acl - - python3-pip - - python3-venv - - name: Install pipx Python package - ansible.builtin.pip: - name: pipx - - name: Install poetry - community.general.pipx: - name: poetry - state: present - environment: - PIPX_HOME: /opt/pipx - PIPX_BIN_DIR: /usr/local/bin - - name: Install pipx - ansible.builtin.shell: - cmd: | - python3 -m pip install --user pipx - python3 -m pipx ensurepath - chdir: /home/{{ github_runner_user }} - become_user: "{{ github_runner_user }}" - - name: Install Poetry - ansible.builtin.shell: - cmd: | - pipx install poetry - chdir: /home/{{ github_runner_user }} - become_user: "{{ github_runner_user }}" - name: Install the runner [If error, RUNNER_CFG_PAT might be missing or expired! See README.md] ansible.builtin.shell: cmd: > diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index b51e7b26..30f106a1 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -11,14 +11,18 @@ stack_name: "{{ long_app_name }}-stack" aws_profile: "{{ long_app_name }}" cluster_name: "{{ stack_name }}-cluster" -ansible_connection: local -ansible_python_interpreter: "{{ ansible_playbook_python }}" +# ansible_connection: local +# ansible_python_interpreter: "{{ ansible_playbook_python }}" k8s_cluster_name: "{{ cluster_name }}" k8s_namespace: "{{ app_name }}-{{ env_name }}" -# Caktus office IP address -administrator_ip_cidr: "70.62.97.170/32" +# IP addresses +administrator_ip_cidrs: + - 70.62.97.170/32 # Caktus office + - 107.15.45.253/32 # Tobias + - 47.230.11.28/32 # Ronard + - 107.223.185.195/32 # Colin # CloudFormation Outputs # These values are taken from the CF 'Output' tab @@ -54,9 +58,9 @@ cloudformation_stack: template_parameters: UseAES256Encryption: "true" - AdministratorIPAddress: "{{ administrator_ip_cidr }}" - BastionAMI: "" # Needed - don't know how to get it. - BastionKeyName: ron_hip + AdministratorIPAddress: "{{ administrator_ip_cidrs[0] }}" # Stack allows only single IP here to SSH to bastion + BastionAMI: "ami-0ad554caf874569d2" # https://cloud-images.ubuntu.com/locator/ec2/ [us-east-1 amd64] + BastionKeyName: rluna_hip BastionInstanceType: t3.small # Is this a proper size? BastionType: SSH CustomerManagedCmkArn: "" @@ -77,7 +81,7 @@ cloudformation_stack: DatabasePassword: "{{ admin_database_password }}" DatabaseMultiAZ: "true" EksClusterName: "philly-hip-stack-cluster" - EksPublicAccessCidrs: " {{ administrator_ip_cidr }}" + EksPublicAccessCidrs: " {{ administrator_ip_cidrs | join(',') }}" tags: Environment: "{{ app_name }}" diff --git a/deploy/inventory b/deploy/inventory index baa6cafd..15793b0f 100644 --- a/deploy/inventory +++ b/deploy/inventory @@ -1,3 +1,5 @@ +runner ansible_host=100.29.176.240 + [k8s] dr staging diff --git a/deploy/requirements.yml b/deploy/requirements.yml index eb0578ab..34e612de 100644 --- a/deploy/requirements.yml +++ b/deploy/requirements.yml @@ -12,3 +12,6 @@ - src: https://github.com/caktus/ansible-role-k8s-hosting-services name: caktus.k8s-hosting-services version: v0.12.0 + +- src: weareinteractive.users + version: 1.17.0 \ No newline at end of file From 82b725c08fa94693719f8d64400e8bb172cdfd2d Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Fri, 23 Aug 2024 13:53:32 -0400 Subject: [PATCH 12/43] Add runner deploy instructions --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f57d3093..25dd6260 100644 --- a/README.md +++ b/README.md @@ -310,6 +310,10 @@ export RUNNER_CFG_PAT="gh......" * Run the playbook to deploy the runner: ```sh +cd deploy/ +# first time: connect as ubuntu user +ansible-playbook -u ubuntu deploy-runner.yml +# second time and beyond ansible-playbook deploy-runner.yml ``` From 1bcee36ded23716552009878f106b1d5371a42e4 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Fri, 23 Aug 2024 14:31:27 -0400 Subject: [PATCH 13/43] Run deploys in runner --- .github/workflows/deploy.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5df0e159..05094cba 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -8,7 +8,9 @@ on: jobs: deploy: - runs-on: ubuntu-20.04 + runs-on: + - self-hosted + - philly-hip env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} From 3b333576bd63f09389a64c157c7f23bedf884769 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Fri, 23 Aug 2024 15:12:01 -0400 Subject: [PATCH 14/43] Update runner and version of psycopg2-binary --- deploy/deploy-runner.yml | 3 +++ requirements/base/base.in | 2 +- requirements/base/base.txt | 2 +- requirements/dev/dev.txt | 14 +++++--------- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/deploy/deploy-runner.yml b/deploy/deploy-runner.yml index 58710f80..aa773fa8 100644 --- a/deploy/deploy-runner.yml +++ b/deploy/deploy-runner.yml @@ -38,6 +38,9 @@ - curl - gnupg - lsb-release + - libpq-dev + - python3.10 + - python3.10-dev - name: Add Docker's official GPG key ansible.builtin.apt_key: url: https://download.docker.com/linux/ubuntu/gpg diff --git a/requirements/base/base.in b/requirements/base/base.in index 38cd03f8..d15cee6e 100644 --- a/requirements/base/base.in +++ b/requirements/base/base.in @@ -27,7 +27,7 @@ pdfid social-auth-app-django # Postgres -psycopg2-binary +psycopg2-binary==2.9.9 # Wagtail diff --git a/requirements/base/base.txt b/requirements/base/base.txt index f2a83197..c734fb56 100644 --- a/requirements/base/base.txt +++ b/requirements/base/base.txt @@ -122,7 +122,7 @@ phonenumberslite==8.12.18 # via -r requirements/base/base.in pillow==9.3.0 # via wagtail -psycopg2-binary==2.8.6 +psycopg2-binary==2.9.9 # via -r requirements/base/base.in pycparser==2.20 # via cffi diff --git a/requirements/dev/dev.txt b/requirements/dev/dev.txt index e577f2a5..ff1c56c8 100644 --- a/requirements/dev/dev.txt +++ b/requirements/dev/dev.txt @@ -17,7 +17,9 @@ anyascii==0.1.7 anyio==3.7.1 # via jupyter-server appnope==0.1.4 - # via -r requirements/dev/dev.in + # via + # -r requirements/dev/dev.in + # ipykernel argon2-cffi==23.1.0 # via # jupyter-server @@ -186,7 +188,6 @@ idna==2.10 # via # -c requirements/dev/../base/base.txt # anyio - # httpx # requests importlib-metadata==7.1.0 # via -r requirements/dev/dev.in @@ -202,7 +203,6 @@ invoke-kubesae==0.1.0 # via -r requirements/dev/dev.in ipykernel==6.29.4 # via - # jupyterlab # nbclassic # notebook ipython==8.24.0 @@ -328,9 +328,7 @@ nodeenv==1.8.0 notebook==6.5.7 # via jupyterlab notebook-shim==0.2.4 - # via - # jupyterlab - # nbclassic + # via nbclassic oauthlib==3.1.0 # via # -c requirements/dev/../base/base.txt @@ -505,9 +503,7 @@ six==1.15.0 # openshift # python-dateutil sniffio==1.3.1 - # via - # anyio - # httpx + # via anyio soupsieve==2.2 # via # -c requirements/dev/../base/base.txt From f3f9832a3841a06f48b664555b524806c8dc8855 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Fri, 23 Aug 2024 15:28:24 -0400 Subject: [PATCH 15/43] Update & pin cffi --- requirements/base/base.in | 2 ++ requirements/base/base.txt | 6 ++++-- requirements/dev/dev.txt | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/requirements/base/base.in b/requirements/base/base.in index d15cee6e..fd3d0433 100644 --- a/requirements/base/base.in +++ b/requirements/base/base.in @@ -34,3 +34,5 @@ psycopg2-binary==2.9.9 wagtail wagtailfontawesome wagtailmenus + +cffi==1.17.0 \ No newline at end of file diff --git a/requirements/base/base.txt b/requirements/base/base.txt index c734fb56..aeecf329 100644 --- a/requirements/base/base.txt +++ b/requirements/base/base.txt @@ -19,8 +19,10 @@ botocore==1.34.104 # s3transfer certifi==2020.12.5 # via requests -cffi==1.14.5 - # via cryptography +cffi==1.17.0 + # via + # -r requirements/base/base.in + # cryptography chardet==4.0.0 # via requests cryptography==3.4.7 diff --git a/requirements/dev/dev.txt b/requirements/dev/dev.txt index ff1c56c8..61283d96 100644 --- a/requirements/dev/dev.txt +++ b/requirements/dev/dev.txt @@ -70,7 +70,7 @@ certifi==2020.12.5 # -c requirements/dev/../base/base.txt # kubernetes # requests -cffi==1.14.5 +cffi==1.17.0 # via # -c requirements/dev/../base/base.txt # argon2-cffi-bindings From 90706075d42251580cd6fd781fffbf45db19dd54 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 12 Sep 2024 11:03:30 -0400 Subject: [PATCH 16/43] Test arc-runner-set k8s self-hosted runner --- .github/workflows/test.yml | 114 +++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 550ab85d..27f9697a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,60 +7,62 @@ on: jobs: test: - runs-on: ubuntu-20.04 - env: - DJANGO_SETTINGS_MODULE: hip.settings.dev - services: - postgres: - image: postgres - env: - POSTGRES_PASSWORD: postgres - POSTGRES_DB: hip_ci - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 + runs-on: arc-runner-set #ubuntu-20.04 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: '16' - - name: Cache node modules - uses: actions/cache@v3 - env: - cache-name: cache-node-modules - with: - path: ~/.npm - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - run: npm install - - run: npm run build - - uses: actions/setup-python@v4 - with: - python-version: '3.10' - cache: 'pip' - cache-dependency-path: 'requirements/*/**.txt' - - name: Cache pre-commit - uses: actions/cache@v3 - with: - path: ~/.cache/pre-commit - key: ${{ runner.os }}-precommit-${{ hashFiles('.pre-commit-config.yaml') }} - restore-keys: | - ${{ runner.os }}-precommit- - - name: Install dependencies - run: | - python -m pip install --upgrade pip wheel pip-tools - pip-sync requirements/base/base.txt requirements/dev/dev.txt - - uses: pre-commit/action@v3.0.0 - - name: Run Tests - run: make run-tests - env: - DATABASE_URL: postgres://postgres:postgres@localhost:5432/hip_ci - - name: Test build deploy image - run: inv image.build + - run: echo "🎉 This job just ran on runner 'arc-runner-set' scale set runners!" + # env: + # DJANGO_SETTINGS_MODULE: hip.settings.dev + # services: + # postgres: + # image: postgres + # env: + # POSTGRES_PASSWORD: postgres + # POSTGRES_DB: hip_ci + # options: >- + # --health-cmd pg_isready + # --health-interval 10s + # --health-timeout 5s + # --health-retries 5 + # ports: + # - 5432:5432 + # steps: + # - uses: actions/checkout@v3 + # - uses: actions/setup-node@v3 + # with: + # node-version: '16' + # - name: Cache node modules + # uses: actions/cache@v3 + # env: + # cache-name: cache-node-modules + # with: + # path: ~/.npm + # key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} + # restore-keys: | + # ${{ runner.os }}-build-${{ env.cache-name }}- + # ${{ runner.os }}-build- + # ${{ runner.os }}- + # - run: npm install + # - run: npm run build + # - uses: actions/setup-python@v4 + # with: + # python-version: '3.10' + # cache: 'pip' + # cache-dependency-path: 'requirements/*/**.txt' + # - name: Cache pre-commit + # uses: actions/cache@v3 + # with: + # path: ~/.cache/pre-commit + # key: ${{ runner.os }}-precommit-${{ hashFiles('.pre-commit-config.yaml') }} + # restore-keys: | + # ${{ runner.os }}-precommit- + # - name: Install dependencies + # run: | + # python -m pip install --upgrade pip wheel pip-tools + # pip-sync requirements/base/base.txt requirements/dev/dev.txt + # - uses: pre-commit/action@v3.0.0 + # - name: Run Tests + # run: make run-tests + # env: + # DATABASE_URL: postgres://postgres:postgres@localhost:5432/hip_ci + # - name: Test build deploy image + # run: inv image.build From 53292dfae98c70fb8c89ce673c5593eea5a90474 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 12 Sep 2024 13:30:33 -0400 Subject: [PATCH 17/43] Run test and deployment in self-hosted runner --- .github/workflows/deploy.yml | 4 +- .github/workflows/test.yml | 114 +++++++++++++++++------------------ deploy/group_vars/all.yml | 3 +- 3 files changed, 59 insertions(+), 62 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 05094cba..188bd9da 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -8,9 +8,7 @@ on: jobs: deploy: - runs-on: - - self-hosted - - philly-hip + runs-on: arc-runner-set env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 27f9697a..3a3f769a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,62 +7,60 @@ on: jobs: test: - runs-on: arc-runner-set #ubuntu-20.04 + runs-on: arc-runner-set + env: + DJANGO_SETTINGS_MODULE: hip.settings.dev + services: + postgres: + image: postgres + env: + POSTGRES_PASSWORD: postgres + POSTGRES_DB: hip_ci + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 steps: - - run: echo "🎉 This job just ran on runner 'arc-runner-set' scale set runners!" - # env: - # DJANGO_SETTINGS_MODULE: hip.settings.dev - # services: - # postgres: - # image: postgres - # env: - # POSTGRES_PASSWORD: postgres - # POSTGRES_DB: hip_ci - # options: >- - # --health-cmd pg_isready - # --health-interval 10s - # --health-timeout 5s - # --health-retries 5 - # ports: - # - 5432:5432 - # steps: - # - uses: actions/checkout@v3 - # - uses: actions/setup-node@v3 - # with: - # node-version: '16' - # - name: Cache node modules - # uses: actions/cache@v3 - # env: - # cache-name: cache-node-modules - # with: - # path: ~/.npm - # key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} - # restore-keys: | - # ${{ runner.os }}-build-${{ env.cache-name }}- - # ${{ runner.os }}-build- - # ${{ runner.os }}- - # - run: npm install - # - run: npm run build - # - uses: actions/setup-python@v4 - # with: - # python-version: '3.10' - # cache: 'pip' - # cache-dependency-path: 'requirements/*/**.txt' - # - name: Cache pre-commit - # uses: actions/cache@v3 - # with: - # path: ~/.cache/pre-commit - # key: ${{ runner.os }}-precommit-${{ hashFiles('.pre-commit-config.yaml') }} - # restore-keys: | - # ${{ runner.os }}-precommit- - # - name: Install dependencies - # run: | - # python -m pip install --upgrade pip wheel pip-tools - # pip-sync requirements/base/base.txt requirements/dev/dev.txt - # - uses: pre-commit/action@v3.0.0 - # - name: Run Tests - # run: make run-tests - # env: - # DATABASE_URL: postgres://postgres:postgres@localhost:5432/hip_ci - # - name: Test build deploy image - # run: inv image.build + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '16' + - name: Cache node modules + uses: actions/cache@v3 + env: + cache-name: cache-node-modules + with: + path: ~/.npm + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + - run: npm install + - run: npm run build + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + cache: 'pip' + cache-dependency-path: 'requirements/*/**.txt' + - name: Cache pre-commit + uses: actions/cache@v3 + with: + path: ~/.cache/pre-commit + key: ${{ runner.os }}-precommit-${{ hashFiles('.pre-commit-config.yaml') }} + restore-keys: | + ${{ runner.os }}-precommit- + - name: Install dependencies + run: | + python -m pip install --upgrade pip wheel pip-tools + pip-sync requirements/base/base.txt requirements/dev/dev.txt + - uses: pre-commit/action@v3.0.0 + - name: Run Tests + run: make run-tests + env: + DATABASE_URL: postgres://postgres:postgres@localhost:5432/hip_ci + - name: Test build deploy image + run: inv image.build diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index b26cec5a..4e27b524 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -61,7 +61,8 @@ cloudformation_stack: AdministratorIPAddress: "{{ administrator_ip_cidrs[0] }}" # Stack allows only single IP here to SSH to bastion BastionAMI: "ami-0ad554caf874569d2" # https://cloud-images.ubuntu.com/locator/ec2/ [us-east-1 amd64] BastionKeyName: rluna_hip - BastionInstanceType: t3.small # Is this a proper size? + # Instance sizes - https://aws.amazon.com/ec2/instance-types/t3/ + BastionInstanceType: t3.small BastionType: SSH CustomerManagedCmkArn: "" DomainName: "{{ app_name }}-prod.caktus-built.com" From 953078cdfd3c41e4d2b0fced7fda8652cc97d89d Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 12 Sep 2024 16:52:09 -0400 Subject: [PATCH 18/43] Add current branch to push branches as test --- .github/workflows/deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 188bd9da..ca9dc14c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,6 +5,7 @@ on: branches: - main - develop + - CU-8689pdzrr-k8s-self-hosted-runner jobs: deploy: From cee2fa22075cc4d1581def4ed1527dc4784f239b Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 10:27:58 -0400 Subject: [PATCH 19/43] Limit necessary reqs to build img --- .github/workflows/deploy.yml | 4 ++-- .github/workflows/test.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ca9dc14c..c4669ae2 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -9,7 +9,7 @@ on: jobs: deploy: - runs-on: arc-runner-set + runs-on: arc-runner-set # K8s self hosted runner env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -27,7 +27,7 @@ jobs: id: pip-install run: | python -m pip install --upgrade pip wheel pip-tools - pip-sync requirements/base/base.txt requirements/dev/dev.txt + pip-sync requirements/dev/dev.txt - name: Login to Docker id: docker-login run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3a3f769a..7eba9bd4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ on: jobs: test: - runs-on: arc-runner-set + runs-on: arc-runner-set # K8s self hosted runner env: DJANGO_SETTINGS_MODULE: hip.settings.dev services: From 0af401685f4fc10eb32673b74a65989f5b2add2c Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 10:41:29 -0400 Subject: [PATCH 20/43] Install apt dependencies on deploy --- .github/workflows/deploy.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c4669ae2..38b3a802 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -22,7 +22,12 @@ jobs: with: python-version: '3.10' cache: 'pip' - cache-dependency-path: 'requirements/*/**.txt' + cache-dependency-path: 'requirements/*/dev.txt' + - name: Install apt packages + uses: awalsh128/cache-apt-pkgs-action@v1.4.2 + with: + packages: git + version: 1.0 # cache version (increment if needed) - name: Install dependencies id: pip-install run: | From 1790b145a412e1f4205ae12d129b7f3395e0fcf9 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 10:46:10 -0400 Subject: [PATCH 21/43] Install apt dependencies on deploy --- .github/workflows/deploy.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 38b3a802..3ebd2d67 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -24,10 +24,7 @@ jobs: cache: 'pip' cache-dependency-path: 'requirements/*/dev.txt' - name: Install apt packages - uses: awalsh128/cache-apt-pkgs-action@v1.4.2 - with: - packages: git - version: 1.0 # cache version (increment if needed) + run: sudo apt-get install -y git - name: Install dependencies id: pip-install run: | From 0703e105213c8861c8e7ad602500242c71c50b00 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 10:49:13 -0400 Subject: [PATCH 22/43] Add apt-get update --- .github/workflows/deploy.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3ebd2d67..3e203d3e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -24,7 +24,9 @@ jobs: cache: 'pip' cache-dependency-path: 'requirements/*/dev.txt' - name: Install apt packages - run: sudo apt-get install -y git + run: | + sudo apt-get update + sudo apt-get install -y git - name: Install dependencies id: pip-install run: | From 1c6fbcefb9ec59ca10cc6a963a22d6ac905ed926 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 10:59:15 -0400 Subject: [PATCH 23/43] Divide deployment job --- .github/workflows/deploy.yml | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3e203d3e..072138e5 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -8,8 +8,8 @@ on: - CU-8689pdzrr-k8s-self-hosted-runner jobs: - deploy: - runs-on: arc-runner-set # K8s self hosted runner + build-push: + runs-on: ubuntu-22.04 # standard (not self-hosted) runner env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -23,10 +23,6 @@ jobs: python-version: '3.10' cache: 'pip' cache-dependency-path: 'requirements/*/dev.txt' - - name: Install apt packages - run: | - sudo apt-get update - sudo apt-get install -y git - name: Install dependencies id: pip-install run: | @@ -37,16 +33,36 @@ jobs: run: | inv aws.docker-login - name: Build, tag, push, and deploy image - id: build-tag-push-deploy + id: build-tag-push run: | [ "$GITHUB_REF" = refs/heads/main ] && ENV="production" || ENV="staging" echo "env is $ENV" - inv $ENV image deploy --verbosity=0 + inv $ENV image push --verbosity=0 - uses: act10ns/slack@v1 with: status: ${{ job.status }} steps: ${{ toJson(steps) }} # always() means to notify regardless of status if: always() + deploy: + runs-on: arc-runner-set # K8s self-hosted runner + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} + # https://github.com/marketplace/actions/slack-github-actions-slack-integration + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + cache: 'pip' + cache-dependency-path: 'requirements/*/dev.txt' + - name: Install dependencies + id: pip-install + run: | + python -m pip install --upgrade pip wheel pip-tools + pip-sync requirements/dev/dev.txt From d4e0f5f09f89ec26a4c0bf1361f0cd724dd7348b Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 11:02:30 -0400 Subject: [PATCH 24/43] Improve deploy & test files --- .github/workflows/deploy.yml | 3 ++- .github/workflows/test.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 072138e5..c3728060 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -39,7 +39,7 @@ jobs: ENV="production" || ENV="staging" echo "env is $ENV" - inv $ENV image push --verbosity=0 + inv $ENV image.push --verbosity=0 - uses: act10ns/slack@v1 with: status: ${{ job.status }} @@ -48,6 +48,7 @@ jobs: if: always() deploy: runs-on: arc-runner-set # K8s self-hosted runner + needs: [build-push] env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7eba9bd4..7307f365 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ on: jobs: test: - runs-on: arc-runner-set # K8s self hosted runner + runs-on: ubuntu-22.04 # standard (not self-hosted) runner env: DJANGO_SETTINGS_MODULE: hip.settings.dev services: From 9c90c5b223128b565ea0228a6a960763406bfdb5 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 11:07:31 -0400 Subject: [PATCH 25/43] Remove non-existing flag --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c3728060..dd7bcaeb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -39,7 +39,7 @@ jobs: ENV="production" || ENV="staging" echo "env is $ENV" - inv $ENV image.push --verbosity=0 + inv $ENV image.push - uses: act10ns/slack@v1 with: status: ${{ job.status }} From dd44bc487583323b8e2f7d7735694b5400fd8f70 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 11:24:50 -0400 Subject: [PATCH 26/43] Pass tags in between jobs --- .github/workflows/deploy.yml | 39 ++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index dd7bcaeb..2564c0aa 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -32,7 +32,7 @@ jobs: id: docker-login run: | inv aws.docker-login - - name: Build, tag, push, and deploy image + - name: Build, tag, and push image id: build-tag-push run: | [ "$GITHUB_REF" = refs/heads/main ] && @@ -40,12 +40,17 @@ jobs: ENV="staging" echo "env is $ENV" inv $ENV image.push - - uses: act10ns/slack@v1 + - shell: bash + run: | + inv image.tag | grep 'Set config.tag to' | cut -d' ' -f4 > docker-tag.txt + - name: Upload docker tag from build-push job + uses: actions/upload-artifact@v4 with: - status: ${{ job.status }} - steps: ${{ toJson(steps) }} - # always() means to notify regardless of status - if: always() + name: docker_tag + path: docker-tag.txt + + # The deploy needs to run from within the cluster, since the cluster + # is not exposed to the public internet deploy: runs-on: arc-runner-set # K8s self-hosted runner needs: [build-push] @@ -57,6 +62,14 @@ jobs: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} steps: - uses: actions/checkout@v3 + - name: Download docker tag from build-push job + uses: actions/download-artifact@v4 + with: + name: docker_tag + - name: Set variables + run: | + DOCKER_TAG=$(cat docker-tag.txt) + echo "DOCKER_TAG=$DOCKER_TAG" >> $GITHUB_ENV - uses: actions/setup-python@v4 with: python-version: '3.10' @@ -67,3 +80,17 @@ jobs: run: | python -m pip install --upgrade pip wheel pip-tools pip-sync requirements/dev/dev.txt + - name: Deploy the image + id: deploy + run: | + [ "$GITHUB_REF" = refs/heads/main ] && + ENV="production" || + ENV="staging" + echo "env is $ENV" + inv $ENV deploy --tag=${{ env.DOCKER_TAG }} + - uses: act10ns/slack@v1 + with: + status: ${{ job.status }} + steps: ${{ toJson(steps) }} + # always() means to notify regardless of status + if: always() From cff73d822b40d85ffa7a77f2e837483b8d84196a Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 11:34:01 -0400 Subject: [PATCH 27/43] Document and install git --- .github/workflows/deploy.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 2564c0aa..a76ca55c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -50,7 +50,10 @@ jobs: path: docker-tag.txt # The deploy needs to run from within the cluster, since the cluster - # is not exposed to the public internet + # is not exposed to the public internet. This step is split out into + # its own job to reduce the amount of work done on the self-hosted runner + # and avoid the need to run a privileged docker container (with the + # capability of building a docker container itself). deploy: runs-on: arc-runner-set # K8s self-hosted runner needs: [build-push] @@ -70,6 +73,10 @@ jobs: run: | DOCKER_TAG=$(cat docker-tag.txt) echo "DOCKER_TAG=$DOCKER_TAG" >> $GITHUB_ENV + - name: Install apt packages + run: | + sudo apt-get update + sudo apt-get install -y git - uses: actions/setup-python@v4 with: python-version: '3.10' From 2feb319f1ff9ebd25acb140dcb9ef8eb6db198f5 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 11:46:20 -0400 Subject: [PATCH 28/43] Improve deploy --- .github/workflows/deploy.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a76ca55c..49b6f672 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -32,6 +32,13 @@ jobs: id: docker-login run: | inv aws.docker-login + - shell: bash + run: | + inv image.tag | grep 'Set config.tag to' | cut -d' ' -f4 > docker-tag.txt + - name: Set variables + run: | + DOCKER_TAG=$(cat docker-tag.txt) + echo "DOCKER_TAG=$DOCKER_TAG" >> $GITHUB_ENV - name: Build, tag, and push image id: build-tag-push run: | @@ -39,10 +46,7 @@ jobs: ENV="production" || ENV="staging" echo "env is $ENV" - inv $ENV image.push - - shell: bash - run: | - inv image.tag | grep 'Set config.tag to' | cut -d' ' -f4 > docker-tag.txt + inv $ENV image.push --tag=${{ env.DOCKER_TAG }} - name: Upload docker tag from build-push job uses: actions/upload-artifact@v4 with: From b93c55ff3190f30cbbed406ae0b428d6389c0b14 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 11:52:20 -0400 Subject: [PATCH 29/43] Test --- .github/workflows/deploy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 49b6f672..0a753327 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -33,7 +33,9 @@ jobs: run: | inv aws.docker-login - shell: bash + # https://github.com/caktus/invoke-kubesae/blob/main/kubesae/image.py#L24C24-L24C42 run: | + git status --short inv image.tag | grep 'Set config.tag to' | cut -d' ' -f4 > docker-tag.txt - name: Set variables run: | From 5cd3516e2b165ad5a18d3b411766e7ee35b21e38 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 11:58:26 -0400 Subject: [PATCH 30/43] Test --- .github/workflows/deploy.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 0a753327..a9e49fb6 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -32,15 +32,11 @@ jobs: id: docker-login run: | inv aws.docker-login - - shell: bash - # https://github.com/caktus/invoke-kubesae/blob/main/kubesae/image.py#L24C24-L24C42 - run: | - git status --short - inv image.tag | grep 'Set config.tag to' | cut -d' ' -f4 > docker-tag.txt - name: Set variables run: | - DOCKER_TAG=$(cat docker-tag.txt) + DOCKER_TAG=$(inv image.tag | grep 'Set config.tag to' | cut -d' ' -f4) echo "DOCKER_TAG=$DOCKER_TAG" >> $GITHUB_ENV + echo "$DOCKER_TAG" > docker-tag.txt - name: Build, tag, and push image id: build-tag-push run: | From 89f864669870b950710e02fc2796708907aee341 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 12:05:58 -0400 Subject: [PATCH 31/43] Test --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a9e49fb6..d6b7f955 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -32,7 +32,7 @@ jobs: id: docker-login run: | inv aws.docker-login - - name: Set variables + - name: Set DOCKER_TAG and save to file for artifact upload run: | DOCKER_TAG=$(inv image.tag | grep 'Set config.tag to' | cut -d' ' -f4) echo "DOCKER_TAG=$DOCKER_TAG" >> $GITHUB_ENV @@ -44,7 +44,7 @@ jobs: ENV="production" || ENV="staging" echo "env is $ENV" - inv $ENV image.push --tag=${{ env.DOCKER_TAG }} + inv $ENV image.build --tag=${{ env.DOCKER_TAG }} image.push --tag=${{ env.DOCKER_TAG }} - name: Upload docker tag from build-push job uses: actions/upload-artifact@v4 with: From d84f5fb6d379b7f8b19a485b991d190bd4c3488d Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 19 Sep 2024 12:17:19 -0400 Subject: [PATCH 32/43] Remove some verbosity from img creation --- .github/workflows/deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d6b7f955..aa3ea200 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -44,6 +44,7 @@ jobs: ENV="production" || ENV="staging" echo "env is $ENV" + export BUILDKIT_PROGRESS=plain inv $ENV image.build --tag=${{ env.DOCKER_TAG }} image.push --tag=${{ env.DOCKER_TAG }} - name: Upload docker tag from build-push job uses: actions/upload-artifact@v4 From ba22e931cb5c5973ad1c3d30f7375355ea3a6e6b Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 1 Oct 2024 12:11:28 -0400 Subject: [PATCH 33/43] Remove github deploy runner --- deploy/deploy-runner.yml | 9 +++++- deploy/group_vars/all.yml | 6 ---- deploy/remove-runner.yml | 66 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 deploy/remove-runner.yml diff --git a/deploy/deploy-runner.yml b/deploy/deploy-runner.yml index aa773fa8..1c102f09 100644 --- a/deploy/deploy-runner.yml +++ b/deploy/deploy-runner.yml @@ -28,6 +28,8 @@ ansible.builtin.user: name: "{{ github_runner_user }}" comment: Github Actions Runner + state: absent + # Install Docker # https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository - name: Install dependencies @@ -58,6 +60,8 @@ - docker-buildx-plugin - docker-compose-plugin update_cache: yes + state: absent + - name: Task name stat: path: /home/{{ github_runner_user }}/runner @@ -106,10 +110,13 @@ name: "{{ github_runner_user }}" groups: docker append: yes + state: absent + - name: Restart docker service ansible.builtin.service: name: docker - state: restarted + state: stopped + - name: Install the runner [If error, RUNNER_CFG_PAT might be missing or expired! See README.md] ansible.builtin.shell: cmd: > diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index 4e27b524..3faa0078 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -58,12 +58,6 @@ cloudformation_stack: template_parameters: UseAES256Encryption: "true" - AdministratorIPAddress: "{{ administrator_ip_cidrs[0] }}" # Stack allows only single IP here to SSH to bastion - BastionAMI: "ami-0ad554caf874569d2" # https://cloud-images.ubuntu.com/locator/ec2/ [us-east-1 amd64] - BastionKeyName: rluna_hip - # Instance sizes - https://aws.amazon.com/ec2/instance-types/t3/ - BastionInstanceType: t3.small - BastionType: SSH CustomerManagedCmkArn: "" DomainName: "{{ app_name }}-prod.caktus-built.com" DomainNameAlternates: "" diff --git a/deploy/remove-runner.yml b/deploy/remove-runner.yml new file mode 100644 index 00000000..765563c5 --- /dev/null +++ b/deploy/remove-runner.yml @@ -0,0 +1,66 @@ +--- +- name: Remove GitHub Actions Runner + hosts: runner + become: yes + tags: runner_removal + tasks: + - name: Stop the runner service + ansible.builtin.shell: + cmd: > + curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/remove-svc.sh + | bash -s {{ github_scope }} + chdir: /home/{{ github_runner_user }} + environment: + RUNNER_CFG_PAT: "{{ github_pat }}" + ignore_errors: True + + - name: Delete the runner from GitHub (Unregister) + ansible.builtin.shell: + cmd: > + curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/delete.sh + | bash -s {{ github_scope }} {{ github_runner_name }} + chdir: /home/{{ github_runner_user }} + environment: + RUNNER_CFG_PAT: "{{ github_pat }}" + ignore_errors: True + + - name: Remove runner directory and files + ansible.builtin.file: + path: "/home/{{ github_runner_user }}/runner" + state: absent + ignore_errors: True + + - name: Uninstall Docker packages + ansible.builtin.package: + name: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin + state: absent + ignore_errors: True + + - name: Remove Docker GPG key + ansible.builtin.apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + state: absent + ignore_errors: True + + - name: Remove Docker repository + ansible.builtin.apt_repository: + repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable + state: absent + ignore_errors: True + + - name: Remove GitHub runner user + ansible.builtin.user: + name: "{{ github_runner_user }}" + state: absent + ignore_errors: True + + - name: Remove docker group + ansible.builtin.group: + name: docker + state: absent + ignore_errors: True \ No newline at end of file From a78bf0b899691e0614f04505f460f865165737c1 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 1 Oct 2024 12:11:44 -0400 Subject: [PATCH 34/43] Remove github deploy runner --- .github/workflows/deploy.yml | 1 - README.md | 35 +---------------------------------- 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index aa3ea200..efc7203c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,7 +5,6 @@ on: branches: - main - develop - - CU-8689pdzrr-k8s-self-hosted-runner jobs: build-push: diff --git a/README.md b/README.md index 044056b5..79538bd7 100644 --- a/README.md +++ b/README.md @@ -293,37 +293,4 @@ To reset your local database from a deployed environment: As mentioned in the Database setup instructions, you may need to visit [/cms/sites](http://localhost:8000/cms/sites/) and change the first entry's -`Hostname` field to `localhost` to enable page previews in the Wagtail admin. - -### GitHub Actions Runner - -There are [GitHub Actions self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners) deployed on a virtual machine within the same VPC. Other runners may be added in the future, if needed. - -Setup instructions: - -* Obtain a [GitHub PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) with the `admin:org` scope that's valid for one week (it needs to be active only for the initial deployment). Add this to a local environment variable `RUNNER_CFG_PAT`: - -```sh -export RUNNER_CFG_PAT="gh......" -``` - -* Run the playbook to deploy the runner: - -```sh -cd deploy/ -# first time: connect as ubuntu user -ansible-playbook -u ubuntu deploy-runner.yml -# second time and beyond -ansible-playbook deploy-runner.yml -``` - -* The runner can be forcibly reinstalled by passing `-e force_reinstall=yes` or removed by passing `-e force_removal=yes`. - -Run OS updates: - -```sh -cd deploy/ -ansible-playbook run-os-updates.yml -# You may need to specify your username -ansible-playbook -u myusername run-os-updates.yaml -``` \ No newline at end of file +`Hostname` field to `localhost` to enable page previews in the Wagtail admin. \ No newline at end of file From 2048e58efdd26006b58d079be2e89b9589dae135 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 1 Oct 2024 12:14:34 -0400 Subject: [PATCH 35/43] Remove runner playbooks --- deploy/deploy-runner.yml | 132 --------------------------------------- deploy/remove-runner.yml | 66 -------------------- 2 files changed, 198 deletions(-) delete mode 100644 deploy/deploy-runner.yml delete mode 100644 deploy/remove-runner.yml diff --git a/deploy/deploy-runner.yml b/deploy/deploy-runner.yml deleted file mode 100644 index 1c102f09..00000000 --- a/deploy/deploy-runner.yml +++ /dev/null @@ -1,132 +0,0 @@ ---- -- hosts: runner - become: yes - tags: base - roles: - - caktus.hosting_services.users - tasks: - - name: Set hostname - hostname: - name: "{{ inventory_hostname_short }}" - when: inventory_hostname_short is defined and inventory_hostname_short - - name: Add new hostname to /etc/hosts - lineinfile: - path: /etc/hosts - regexp: '^127\.0\.1\.1' - line: '127.0.1.1 {{ inventory_hostname_short }}' - owner: root - group: root - mode: 0644 - when: inventory_hostname_short is defined and inventory_hostname_short - -- name: Install GitHub Actions Runner - hosts: runner - tags: runner - become: yes - tasks: - - name: Create runner user - ansible.builtin.user: - name: "{{ github_runner_user }}" - comment: Github Actions Runner - state: absent - - # Install Docker - # https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository - - name: Install dependencies - ansible.builtin.package: - name: - - jq - - ca-certificates - - curl - - gnupg - - lsb-release - - libpq-dev - - python3.10 - - python3.10-dev - - name: Add Docker's official GPG key - ansible.builtin.apt_key: - url: https://download.docker.com/linux/ubuntu/gpg - state: present - - name: Add Docker repository - ansible.builtin.apt_repository: - repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable - state: present - - name: Install Docker Engine - ansible.builtin.package: - name: - - docker-ce - - docker-ce-cli - - containerd.io - - docker-buildx-plugin - - docker-compose-plugin - update_cache: yes - state: absent - - - name: Task name - stat: - path: /home/{{ github_runner_user }}/runner - register: runner_dir - - name: Set vars - set_fact: - run_removal_tasks: >- - {{ - runner_dir.stat.exists - and ( - (force_reinstall is defined and force_reinstall == "yes") - or (force_removal is defined and force_removal == "yes") - ) - }} - # Various complicated Ansible roles exist, but this just works: - # https://github.com/actions/runner/blob/main/docs/automate.md - - name: Remove the runner - ansible.builtin.shell: - cmd: > - curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/remove-svc.sh - | bash -s {{ github_scope }} - chdir: /home/{{ github_runner_user }} - environment: - RUNNER_CFG_PAT: "{{ github_pat }}" - when: run_removal_tasks - ignore_errors: True - - name: Delete the runner - ansible.builtin.shell: - cmd: > - curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/delete.sh - | bash -s {{ github_scope }} {{ github_runner_name }} - chdir: /home/{{ github_runner_user }} - environment: - RUNNER_CFG_PAT: "{{ github_pat }}" - when: run_removal_tasks - ignore_errors: True - - name: Remove old runner directory and files - ansible.builtin.file: - path: "{{ item }}" - state: absent - loop: - - /home/{{ github_runner_user }}/runner - when: run_removal_tasks - - name: Add user '{{ github_runner_user }}' to group docker - user: - name: "{{ github_runner_user }}" - groups: docker - append: yes - state: absent - - - name: Restart docker service - ansible.builtin.service: - name: docker - state: stopped - - - name: Install the runner [If error, RUNNER_CFG_PAT might be missing or expired! See README.md] - ansible.builtin.shell: - cmd: > - curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/create-latest-svc.sh - | bash -s -- - -s {{ github_scope }} - -n {{ github_runner_name }} - -l {{ github_runner_location }},self-hosted - -u {{ github_runner_user }} - chdir: /home/{{ github_runner_user }} - environment: - RUNNER_CFG_PAT: "{{ github_pat }}" - when: (not runner_dir.stat.exists) or (force_reinstall is defined and force_reinstall=="yes") \ No newline at end of file diff --git a/deploy/remove-runner.yml b/deploy/remove-runner.yml deleted file mode 100644 index 765563c5..00000000 --- a/deploy/remove-runner.yml +++ /dev/null @@ -1,66 +0,0 @@ ---- -- name: Remove GitHub Actions Runner - hosts: runner - become: yes - tags: runner_removal - tasks: - - name: Stop the runner service - ansible.builtin.shell: - cmd: > - curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/remove-svc.sh - | bash -s {{ github_scope }} - chdir: /home/{{ github_runner_user }} - environment: - RUNNER_CFG_PAT: "{{ github_pat }}" - ignore_errors: True - - - name: Delete the runner from GitHub (Unregister) - ansible.builtin.shell: - cmd: > - curl -s https://raw.githubusercontent.com/actions/runner/main/scripts/delete.sh - | bash -s {{ github_scope }} {{ github_runner_name }} - chdir: /home/{{ github_runner_user }} - environment: - RUNNER_CFG_PAT: "{{ github_pat }}" - ignore_errors: True - - - name: Remove runner directory and files - ansible.builtin.file: - path: "/home/{{ github_runner_user }}/runner" - state: absent - ignore_errors: True - - - name: Uninstall Docker packages - ansible.builtin.package: - name: - - docker-ce - - docker-ce-cli - - containerd.io - - docker-buildx-plugin - - docker-compose-plugin - state: absent - ignore_errors: True - - - name: Remove Docker GPG key - ansible.builtin.apt_key: - url: https://download.docker.com/linux/ubuntu/gpg - state: absent - ignore_errors: True - - - name: Remove Docker repository - ansible.builtin.apt_repository: - repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable - state: absent - ignore_errors: True - - - name: Remove GitHub runner user - ansible.builtin.user: - name: "{{ github_runner_user }}" - state: absent - ignore_errors: True - - - name: Remove docker group - ansible.builtin.group: - name: docker - state: absent - ignore_errors: True \ No newline at end of file From 56aa3291980b9b41de82ca49a0d7d33c1376e7d6 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Wed, 2 Oct 2024 14:48:25 -0400 Subject: [PATCH 36/43] Include helm config to deploy runner --- deploy/deploy-runner.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 deploy/deploy-runner.yml diff --git a/deploy/deploy-runner.yml b/deploy/deploy-runner.yml new file mode 100644 index 00000000..4fe6458d --- /dev/null +++ b/deploy/deploy-runner.yml @@ -0,0 +1,31 @@ +--- +- name: Install Actions Runner Controller and configure runner scale set + hosts: cluster + vars: + ansible_connection: local + ansible_python_interpreter: "{{ ansible_playbook_python }}" + gather_facts: false + tasks: + - name: Installing Actions Runner Controller + kubernetes.core.helm: + context: "{{ k8s_context|mandatory }}" + kubeconfig: "{{ k8s_kubeconfig }}" + chart_ref: oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller + release_name: arc + release_namespace: arc-systems + create_namespace: true + wait: yes + + - name: Configuring a runner scale set + kubernetes.core.helm: + context: "{{ k8s_context|mandatory }}" + kubeconfig: "{{ k8s_kubeconfig }}" + chart_ref: oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set + release_name: arc-runner-set + release_namespace: arc-runners + create_namespace: true + release_values: + githubConfigUrl: "https://github.com/" + githubConfigSecret: + github_token: "" + wait: yes From ab9428cc10209bfba04585de3122c8fa10e847b7 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Thu, 24 Oct 2024 17:11:30 -0400 Subject: [PATCH 37/43] Add updated secret to production.yml --- deploy/group_vars/all.yml | 14 +++++++------- deploy/host_vars/production.yml | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index d072bd67..d566699b 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -171,13 +171,13 @@ env_email_host_pass: !vault | azure_client_id: "f0629cf8-f6f4-4142-94c3-11b8beaaa510" azure_tenant_id: "2046864f-68ea-497d-af34-a6629a6cd700" azure_client_secret: !vault | - $ANSIBLE_VAULT;1.1;AES256 - 33333338343036366530346164376430303132653031376264346232383330373730303633623461 - 6662636633373131333362623766346361383533303936340a323336626262653465303733363539 - 35333463623633663836303831663935346234356466626430346639623766383133336664346436 - 3038646535623434390a393965643933373536316264373264303561653063656662373962626136 - 31363866616161303761353436323864383965393763616565626162653936616638626166323738 - 6164633165343265323665336532303538613133653764366231 + $ANSIBLE_VAULT;1.1;AES256 + 33333338343036366530346164376430303132653031376264346232383330373730303633623461 + 6662636633373131333362623766346361383533303936340a323336626262653465303733363539 + 35333463623633663836303831663935346234356466626430346639623766383133336664346436 + 3038646535623434390a393965643933373536316264373264303561653063656662373962626136 + 31363866616161303761353436323864383965393763616565626162653936616638626166323738 + 6164633165343265323665336532303538613133653764366231 k8s_environment_variables: DATABASE_URL: "{{ env_database_url }}" diff --git a/deploy/host_vars/production.yml b/deploy/host_vars/production.yml index ae1de58d..b208a233 100644 --- a/deploy/host_vars/production.yml +++ b/deploy/host_vars/production.yml @@ -70,12 +70,12 @@ database_password: !vault | azure_client_id: "39459c9f-77b3-4fae-942c-7ef9fbf1332c" azure_client_secret: !vault | $ANSIBLE_VAULT;1.1;AES256 - 62383037633362323633303630383031306666613239653333353735653662633265316635346135 - 3439326633363038333432666238396364386165383932320a653231323632393839313966306165 - 66633866646436366264336462636264383232386366636132343337363163343236306661316138 - 3664656261353362630a613966313138373630333935323863376565386364353733343566646639 - 38363430336432343538616536643963613434663734626565626563343764373231653561636364 - 6465343637323033386364356634356132353364336235663264 + 33333338343036366530346164376430303132653031376264346232383330373730303633623461 + 6662636633373131333362623766346361383533303936340a323336626262653465303733363539 + 35333463623633663836303831663935346234356466626430346639623766383133336664346436 + 3038646535623434390a393965643933373536316264373264303561653063656662373962626136 + 31363866616161303761353436323864383965393763616565626162653936616638626166323738 + 6164633165343265323665336532303538613133653764366231 env_django_secret_key: !vault | $ANSIBLE_VAULT;1.1;AES256 From 57d6bcbf93b2a6b1b6c414b7c16b99901ca237f4 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 29 Oct 2024 14:37:39 -0400 Subject: [PATCH 38/43] Update azure_client_id --- deploy/group_vars/all.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index d566699b..a8784c7e 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -168,7 +168,7 @@ env_email_host_pass: !vault | 3561616461636134373033316665613035303736646133613630 # Azure SSO settings -azure_client_id: "f0629cf8-f6f4-4142-94c3-11b8beaaa510" +azure_client_id: "39459c9f-77b3-4fae-942c-7ef9fbf1332c" azure_tenant_id: "2046864f-68ea-497d-af34-a6629a6cd700" azure_client_secret: !vault | $ANSIBLE_VAULT;1.1;AES256 From 6027f817785c077c346e9616c5d3bf0a6a958f82 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Mon, 4 Nov 2024 15:28:29 -0500 Subject: [PATCH 39/43] Update with valid secret --- deploy/group_vars/all.yml | 12 ++++++------ deploy/host_vars/production.yml | 10 ---------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/deploy/group_vars/all.yml b/deploy/group_vars/all.yml index a8784c7e..bcdc7365 100644 --- a/deploy/group_vars/all.yml +++ b/deploy/group_vars/all.yml @@ -172,12 +172,12 @@ azure_client_id: "39459c9f-77b3-4fae-942c-7ef9fbf1332c" azure_tenant_id: "2046864f-68ea-497d-af34-a6629a6cd700" azure_client_secret: !vault | $ANSIBLE_VAULT;1.1;AES256 - 33333338343036366530346164376430303132653031376264346232383330373730303633623461 - 6662636633373131333362623766346361383533303936340a323336626262653465303733363539 - 35333463623633663836303831663935346234356466626430346639623766383133336664346436 - 3038646535623434390a393965643933373536316264373264303561653063656662373962626136 - 31363866616161303761353436323864383965393763616565626162653936616638626166323738 - 6164633165343265323665336532303538613133653764366231 + 66326536666564323330643461346239313738623566666633303934376132393739373862313463 + 6331336437353664366661316631626262643031343736300a313963366537353861633330646463 + 34396633643138313063326434323732343934383535636530646164323930356433666431396362 + 3638303539323239380a333865663734336261343066313361343435376163326661366630633463 + 31343965633836653436653465323438626262333565303034336237646665393661626362333766 + 3130326232336638373737356261616530373138666465653137 k8s_environment_variables: DATABASE_URL: "{{ env_database_url }}" diff --git a/deploy/host_vars/production.yml b/deploy/host_vars/production.yml index b208a233..d68abe14 100644 --- a/deploy/host_vars/production.yml +++ b/deploy/host_vars/production.yml @@ -67,16 +67,6 @@ database_password: !vault | 38653066646362323434626564333166653433663261643465356538386265353239336131633061 3236316135343961646363316531383661623336623564336637 -azure_client_id: "39459c9f-77b3-4fae-942c-7ef9fbf1332c" -azure_client_secret: !vault | - $ANSIBLE_VAULT;1.1;AES256 - 33333338343036366530346164376430303132653031376264346232383330373730303633623461 - 6662636633373131333362623766346361383533303936340a323336626262653465303733363539 - 35333463623633663836303831663935346234356466626430346639623766383133336664346436 - 3038646535623434390a393965643933373536316264373264303561653063656662373962626136 - 31363866616161303761353436323864383965393763616565626162653936616638626166323738 - 6164633165343265323665336532303538613133653764366231 - env_django_secret_key: !vault | $ANSIBLE_VAULT;1.1;AES256 63323239653538366637613837333237633038383531396663616236663436363431306234623962 From f676a6908712d7cb92a4ece2e5663b0db225f506 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 3 Dec 2024 16:13:46 -0500 Subject: [PATCH 40/43] update values & test deploy self-hosted runner --- deploy/deploy-runner.yml | 28 ++++++++++++++++++++++------ deploy/host_vars/runner.yml | 35 ----------------------------------- 2 files changed, 22 insertions(+), 41 deletions(-) delete mode 100644 deploy/host_vars/runner.yml diff --git a/deploy/deploy-runner.yml b/deploy/deploy-runner.yml index 4fe6458d..924a1ad5 100644 --- a/deploy/deploy-runner.yml +++ b/deploy/deploy-runner.yml @@ -4,28 +4,44 @@ vars: ansible_connection: local ansible_python_interpreter: "{{ ansible_playbook_python }}" + runner_namespace: github-runner + chart_version: "0.9.3" gather_facts: false tasks: + # https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners-with-actions-runner-controller/quickstart-for-actions-runner-controller + # + # Ansible task to automate: + # helm install arc \ + # --namespace "${NAMESPACE}" \ + # --create-namespace \ + # oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller - name: Installing Actions Runner Controller kubernetes.core.helm: context: "{{ k8s_context|mandatory }}" - kubeconfig: "{{ k8s_kubeconfig }}" chart_ref: oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller + chart_version: "{{ chart_version }}" release_name: arc - release_namespace: arc-systems + release_namespace: "{{ runner_namespace }}" create_namespace: true wait: yes + # Ansible task to automate: + # helm install "${INSTALLATION_NAME}" \ + # --namespace "${NAMESPACE}" \ + # --create-namespace \ + # --set githubConfigUrl="https://github.com/caktus/philly-hip" \ + # --set githubConfigSecret.github_token="${RUNNER_CFG_PAT}" \ + # oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set - name: Configuring a runner scale set kubernetes.core.helm: context: "{{ k8s_context|mandatory }}" - kubeconfig: "{{ k8s_kubeconfig }}" chart_ref: oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set + chart_version: "{{ chart_version }}" release_name: arc-runner-set - release_namespace: arc-runners + release_namespace: "{{ runner_namespace }}" create_namespace: true release_values: - githubConfigUrl: "https://github.com/" + githubConfigUrl: "https://github.com/caktus/philly-hip" githubConfigSecret: - github_token: "" + github_token: "{{ lookup('env', 'RUNNER_CFG_PAT') }}" wait: yes diff --git a/deploy/host_vars/runner.yml b/deploy/host_vars/runner.yml deleted file mode 100644 index 23c68172..00000000 --- a/deploy/host_vars/runner.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -## users role configuration ## -users_groups: [adm, dialout, docker, sudo] -users_shell: /bin/bash - -# when removing a user, add their username to this list: -users_remove: - # Remove default user installed by Ubuntu. You might need to comment this out - # temporarily when first configuring a server, and possibly even reboot the - # server before the user can be removed. - - ubuntu - -# users to provision on all servers -# find your ssh key with: `cat ~/.ssh/id_*.pub` (should be one line) -# optionally generate password via `mkpasswd -m sha-512 -R 2000000` -users: - # in alphabetical order - - username: copelco - authorized_keys: - - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICMtpiB+QFK/YDEx3qiq62zUcxKOiuIOe1CNmD+NQYKt copelco@caktusgroup.com - - username: ronardlunagerman - authorized_keys: - - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEhNwSFktLJpdP/e04FPZxEwXsZyqTi8URd2IBjuw0Je rluna@caktusgroup.com - - username: tobias - authorized_keys: - - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFti2WxKH5TJh6SN44pkvG2V4268sJfirn00YrKLy+lY tobias@red-ed25519 - -# On GitHub -github_pat: "{{ lookup('env', 'RUNNER_CFG_PAT') }}" -github_scope: caktus - -# On the VM -github_runner_user: runner -github_runner_name: philly-hip-runner -github_runner_location: philly-hip \ No newline at end of file From 6b6e4c5e5596c8b4e8f2d71595aada0353ccd3aa Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 3 Dec 2024 16:22:19 -0500 Subject: [PATCH 41/43] Return runner copy to documentation --- .github/workflows/deploy.yml | 1 + README.md | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index efc7203c..aa3ea200 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,6 +5,7 @@ on: branches: - main - develop + - CU-8689pdzrr-k8s-self-hosted-runner jobs: build-push: diff --git a/README.md b/README.md index 79538bd7..0242c846 100644 --- a/README.md +++ b/README.md @@ -293,4 +293,23 @@ To reset your local database from a deployed environment: As mentioned in the Database setup instructions, you may need to visit [/cms/sites](http://localhost:8000/cms/sites/) and change the first entry's -`Hostname` field to `localhost` to enable page previews in the Wagtail admin. \ No newline at end of file +`Hostname` field to `localhost` to enable page previews in the Wagtail admin. + +### GitHub Actions Runner + +There are [GitHub Actions self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners) deployed in the Kubernetes cluster along side the application. + +Setup instructions: + +* Obtain a [GitHub PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) with the `repo` scope that's valid for one week (it needs to be active only for the initial deployment). Add this to a local environment variable `RUNNER_CFG_PAT`: + +```sh +export RUNNER_CFG_PAT="gh......" +``` + +* Run the playbook to deploy the runner: + +```sh +cd deploy/ +ansible-playbook deploy-runner.yml +``` From 7ebc3b612ff96986f6a77cc7c99fe753ecfd4f16 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 3 Dec 2024 16:40:30 -0500 Subject: [PATCH 42/43] Less verbosity on deploy --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index aa3ea200..3c5548cd 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -96,8 +96,8 @@ jobs: [ "$GITHUB_REF" = refs/heads/main ] && ENV="production" || ENV="staging" - echo "env is $ENV" - inv $ENV deploy --tag=${{ env.DOCKER_TAG }} + echo "env is $ENV" --verbosity=0 + inv $ENV deploy --tag=${{ env.DOCKER_TAG }} --verbosity=0 - uses: act10ns/slack@v1 with: status: ${{ job.status }} From f7ec5409858bef40a49979f77cf5d3fe90a2e022 Mon Sep 17 00:00:00 2001 From: ronardcaktus Date: Tue, 3 Dec 2024 16:52:49 -0500 Subject: [PATCH 43/43] Remove test branch from production deploy --- .github/workflows/deploy.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3c5548cd..4946aa41 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,7 +5,6 @@ on: branches: - main - develop - - CU-8689pdzrr-k8s-self-hosted-runner jobs: build-push: