diff --git a/install.sh b/install.sh index 0776988a7..94fc15548 100755 --- a/install.sh +++ b/install.sh @@ -161,7 +161,9 @@ if [ ! -d "/home/$CONTROLLER_USER/ce-provision" ]; then /usr/bin/su - "$CONTROLLER_USER" -c "git clone --branch $CONFIG_REPO_BRANCH $CONFIG_REPO /home/$CONTROLLER_USER/ce-provision/config" /usr/bin/su - "$CONTROLLER_USER" -c "/usr/bin/ln -s /home/$CONTROLLER_USER/ce-provision/config/ansible.cfg /home/$CONTROLLER_USER/ce-provision/ansible.cfg" else - /usr/bin/echo "ce-provision directory at /home/$CONTROLLER_USER/ce-provision already exists. Skipping." + /usr/bin/echo "ce-provision directory at /home/$CONTROLLER_USER/ce-provision already exists. Updating." + /usr/bin/su - "$CONTROLLER_USER" -c "cd /home/$CONTROLLER_USER/ce-provision && git pull origin $VERSION" + /usr/bin/su - "$CONTROLLER_USER" -c "cd /home/$CONTROLLER_USER/ce-provision/config && git pull origin $CONFIG_REPO_BRANCH" /usr/bin/echo "-------------------------------------------------" fi /usr/bin/mkdir -p "/home/$CONTROLLER_USER/ce-provision/galaxy/roles" diff --git a/plays/aws_account/README.md b/plays/aws_account/README.md new file mode 100644 index 000000000..b47a9d428 --- /dev/null +++ b/plays/aws_account/README.md @@ -0,0 +1,3 @@ +# Base playbook for configuring an AWS account. + +@TODO provide example infra repo for use with the AWS EC2 inventory plugin. diff --git a/plays/aws_account/aws_account.yml b/plays/aws_account/aws_account.yml new file mode 100644 index 000000000..f6184b34c --- /dev/null +++ b/plays/aws_account/aws_account.yml @@ -0,0 +1,16 @@ +--- +# Global infra setup. +- hosts: localhost + connection: local + become: false + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + # used for tagging + _profile: core + _env_type: core + roles: + - _init + - _meta/aws_account + - _exit diff --git a/plays/aws_asg/README.md b/plays/aws_asg/README.md new file mode 100644 index 000000000..9ee9b5757 --- /dev/null +++ b/plays/aws_asg/README.md @@ -0,0 +1,14 @@ +# Base playbooks for creating a new AWS ASG. +For a standard ASG build just add `cluster.yml` to your environment play, like this: + +```yaml +- import_playbook: "{{ _ce_provision_base_dir }}/plays/aws_asg/cluster.yml" + vars: + _aws_region: eu-west-1 + _env_type: dev + _aws_resource_name: cluster-acme-com +``` + +If you have specific requirements for your AMIs you can copy these plays to your infra repository and alter them accordingly. Don't forget to copy/include `launch.yml` from the `_ec2_standalone` plays or orchestration of brand new clusters will fail. + +@TODO provide example infra repo for use with the AWS EC2 inventory plugin. diff --git a/plays/aws_asg/ami.yml b/plays/aws_asg/ami.yml new file mode 100644 index 000000000..5a82deac5 --- /dev/null +++ b/plays/aws_asg/ami.yml @@ -0,0 +1,35 @@ +--- +# This is the provisioning for the AMI and will run inside a temporary instance using Packer. +- hosts: default + become: true + + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/_common" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/{{ _env_type }}" + - "{{ _ce_provision_build_dir }}/vars/{{ _aws_resource_name }}" + _profile: asg + + tasks: + - name: Upgrade the system and update cache + ansible.builtin.apt: + upgrade: dist + update_cache: true + - ansible.builtin.import_role: + name: _init + - ansible.builtin.import_role: + name: _meta/aws_client_instance + - ansible.builtin.import_role: + name: _meta/webserver + - ansible.builtin.import_role: + name: debian/aws_efs_client + - ansible.builtin.import_role: + name: debian/squashfs + - ansible.builtin.import_role: + name: debian/mount_sync + - ansible.builtin.import_role: + name: debian/swap + - ansible.builtin.import_role: + name: _exit diff --git a/plays/aws_asg/asg.yml b/plays/aws_asg/asg.yml new file mode 100644 index 000000000..9a1367869 --- /dev/null +++ b/plays/aws_asg/asg.yml @@ -0,0 +1,25 @@ +--- +# Common ASG infra. +- hosts: "_{{ _aws_resource_name | regex_replace('-', '_') }}" + connection: local + become: false + + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/_common" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/{{ _env_type }}" + - "{{ _ce_provision_build_dir }}/vars/{{ _aws_resource_name }}" + _profile: asg + + tasks: + - ansible.builtin.import_role: + name: _init + run_once: true + - ansible.builtin.import_role: + name: aws/aws_ec2_autoscale_cluster + run_once: true + - ansible.builtin.import_role: + name: _exit + run_once: true diff --git a/plays/aws_asg/cluster.yml b/plays/aws_asg/cluster.yml new file mode 100644 index 000000000..9a2f93f03 --- /dev/null +++ b/plays/aws_asg/cluster.yml @@ -0,0 +1,5 @@ +--- +# Creates hosts entry so play isn't skipped. +- ansible.builtin.import_playbook: ../aws_ec2_standalone/launch.yml +# Spins up the cluster. +- ansible.builtin.import_playbook: asg.yml diff --git a/plays/aws_ec2_standalone/README.md b/plays/aws_ec2_standalone/README.md new file mode 100644 index 000000000..7c7872193 --- /dev/null +++ b/plays/aws_ec2_standalone/README.md @@ -0,0 +1,8 @@ +# Base playbook for setting up a standalone EC2 instance. +IMPORTANT: these plays deliberately exclude the `_init._profile` variable because it usually needs to be set at runtime or in a separate infrastructure config repo. + +The `server.yml` file is the 'main' play, to customise we suggest this is copied to an infra repo and renamed as `hostname.yml` e.g. `acme-dev1.yml`. You also need to copy `provision.yml` so you can control what is provisioned. The `provision.yml` file is intended only as a model. + +If you want a separate RDS instance to pair with your EC2 instance then uncomment the last two play import lines in `server.yml`, however note you do need to sort out outbound firewall ports in iptables and a Security Group for inbound traffic to the RDS instance - usually port `3306` outbound from the EC2 instance in `firewall_config` and an SG that allows `3306` inbound to RDS. + +@TODO provide example infra repo for use with the AWS EC2 inventory plugin. diff --git a/plays/aws_ec2_standalone/ami.yml b/plays/aws_ec2_standalone/ami.yml new file mode 100644 index 000000000..e2fa4297d --- /dev/null +++ b/plays/aws_ec2_standalone/ami.yml @@ -0,0 +1,20 @@ +--- +# This is the bare provisioning for the AMI. +- hosts: default + become: true + + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/_common" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/{{ _env_type }}" + - "{{ _ce_provision_build_dir }}/vars/{{ _aws_resource_name }}" + + tasks: + - ansible.builtin.import_role: + name: _init + - ansible.builtin.import_role: + name: debian/user_provision + - ansible.builtin.import_role: + name: _exit diff --git a/plays/aws_ec2_standalone/ec2.yml b/plays/aws_ec2_standalone/ec2.yml new file mode 100644 index 000000000..84b2bcfbc --- /dev/null +++ b/plays/aws_ec2_standalone/ec2.yml @@ -0,0 +1,24 @@ +--- +# First step. Spin up a "blank" instance from a fresh AMI. +- hosts: "_{{ _aws_resource_name | regex_replace('-', '_') }}" + connection: local + become: false + + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/_common" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/{{ _env_type }}" + - "{{ _ce_provision_build_dir }}/vars/{{ _aws_resource_name }}" + + tasks: + - ansible.builtin.import_role: + name: _init + - ansible.builtin.import_role: + name: aws/aws_ami + - ansible.builtin.import_role: + name: aws/aws_ec2_with_eip + - ansible.builtin.import_role: + name: _exit + - ansible.builtin.meta: refresh_inventory diff --git a/plays/aws_ec2_standalone/launch.yml b/plays/aws_ec2_standalone/launch.yml new file mode 100644 index 000000000..2d9f13ac6 --- /dev/null +++ b/plays/aws_ec2_standalone/launch.yml @@ -0,0 +1,38 @@ +--- +# Prepare the ground for a new EC2 machine +- hosts: localhost + connection: local + become: false + + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/_common" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/{{ _env_type }}" + - "{{ _ce_provision_build_dir }}/vars/{{ _aws_resource_name }}" + # copied from aws_ami.yml in group_vars/all because we do not want to load aws_ami vars yet + ami_groups: + - "all" + - "_{{ _aws_resource_name | regex_replace('-', '_') }}" + - "_{{ _infra_name | regex_replace('-', '_') }}" + - "_{{ _env_type | regex_replace('-', '_') }}" + + tasks: + - ansible.builtin.import_role: + name: _init + - name: Blank the _aws_hostname variable. + ansible.builtin.set_fact: + _aws_hostname: "" + - name: Check to see if an Ansible host exists. + ansible.builtin.set_fact: + _aws_hostname: "{{ item }}" + with_inventory_hostnames: + - "_{{ _aws_resource_name | regex_replace('-', '_') }}" + - name: If an Ansible host is not found, create it so we can execute EC2 orchestration. + ansible.builtin.add_host: + name: "_{{ _aws_resource_name | regex_replace('-', '_') }}" + groups: "{{ ami_groups }}" + when: _aws_hostname | length == 0 + - ansible.builtin.import_role: + name: _exit diff --git a/plays/aws_ec2_standalone/mysql_client.yml b/plays/aws_ec2_standalone/mysql_client.yml new file mode 100644 index 000000000..b39135fbc --- /dev/null +++ b/plays/aws_ec2_standalone/mysql_client.yml @@ -0,0 +1,32 @@ +--- +- hosts: "_{{ _aws_resource_name | regex_replace('-', '_') }}" + become: true + + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/_common" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/{{ _env_type }}" + - "{{ _ce_provision_build_dir }}/vars/{{ _aws_resource_name }}" + + tasks: + - ansible.builtin.import_role: + name: _init + - ansible.builtin.import_role: + name: debian/user_deploy + # Look up RDS hostname + - name: Get information about an instance + community.aws.rds_instance_info: + region: "{{ _aws_region }}" + profile: "{{ _aws_profile }}" + db_instance_identifier: "{{ _aws_resource_name }}" + become: true + become_user: "{{ user_provision.username }}" + delegate_to: localhost # needs to run on controller + register: _database_info + # Install MySQL client + - ansible.builtin.import_role: + name: debian/mysql_client + - ansible.builtin.import_role: + name: _exit diff --git a/plays/aws_ec2_standalone/provision.yml b/plays/aws_ec2_standalone/provision.yml new file mode 100644 index 000000000..bbe70e8dd --- /dev/null +++ b/plays/aws_ec2_standalone/provision.yml @@ -0,0 +1,29 @@ +--- +- hosts: "_{{ _aws_resource_name | regex_replace('-', '_') }}" + become: true + + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/_common" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/{{ _env_type }}" + - "{{ _ce_provision_build_dir }}/vars/{{ _aws_resource_name }}" + + tasks: + - ansible.builtin.import_role: + name: _init + - ansible.builtin.import_role: + name: ce_ldap_safelist + - ansible.builtin.import_role: + name: _meta/common_base + - ansible.builtin.import_role: + name: _meta/aws_client_instance + - ansible.builtin.import_role: + name: debian/ssh_server + - ansible.builtin.import_role: + name: debian/firewall_config + - ansible.builtin.import_role: + name: debian/swap + - ansible.builtin.import_role: + name: _exit diff --git a/plays/aws_ec2_standalone/rds.yml b/plays/aws_ec2_standalone/rds.yml new file mode 100644 index 000000000..5815bb2dd --- /dev/null +++ b/plays/aws_ec2_standalone/rds.yml @@ -0,0 +1,56 @@ +--- +# Create an RDS instance. +- hosts: "_{{ _aws_resource_name | regex_replace('-', '_') }}" + connection: local + become: false + + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/_common" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/{{ _env_type }}" + - "{{ _ce_provision_build_dir }}/vars/{{ _aws_resource_name }}" + + tasks: + - ansible.builtin.import_role: + name: _init + + # Automate subnet fetching + - name: Create empty var to hold subnet IDs. + ansible.builtin.set_fact: + _aws_rds_vpc_subnet_ids: [] + + - name: Gather VPC information. + amazon.aws.ec2_vpc_net_info: + profile: "{{ aws_rds.aws_profile }}" + region: "{{ aws_rds.region }}" + filters: + "tag:Name": "{{ _infra_name }}" + register: _aws_rds_vpc + + - name: Set the VPC id from name. + ansible.builtin.set_fact: + _aws_rds_vpc_id: "{{ _aws_rds_vpc.vpcs[0].vpc_id }}" + + - name: Gather public subnet information. + amazon.aws.ec2_vpc_subnet_info: + profile: "{{ aws_rds.aws_profile }}" + region: "{{ aws_rds.region }}" + filters: + vpc-id: "{{ _aws_rds_vpc_id }}" + tag:Env: "{{ _env_type }}" + tag:Profile: "core" + register: _aws_rds_vpc_subnets + + - name: Place subnet IDs in a list. + ansible.builtin.set_fact: + _aws_rds_vpc_subnet_ids: "{{ _aws_rds_vpc_subnet_ids + [item.subnet_id] }}" + loop: "{{ _aws_rds_vpc_subnets.subnets }}" + + # Build the RDS instance. + - ansible.builtin.import_role: + name: aws/aws_rds + + - ansible.builtin.import_role: + name: _exit diff --git a/plays/aws_ec2_standalone/server.yml b/plays/aws_ec2_standalone/server.yml new file mode 100644 index 000000000..282a73f16 --- /dev/null +++ b/plays/aws_ec2_standalone/server.yml @@ -0,0 +1,11 @@ +# Prepares a host entry so the ec2.yml play succeeds. +- ansible.builtin.import_playbook: "{{ _ce_provision_base_dir }}/plays/aws_ec2_standalone/launch.yml" +# Spins up the instance. +# We use the central _deploy role to provision the EC2 instance to avoid duplication. +- ansible.builtin.import_playbook: "{{ _ce_provision_base_dir }}/plays/aws_ec2_standalone/ec2.yml" +# Actual provisioning +- ansible.builtin.import_playbook: provision.yml +# RDS instance +#- ansible.builtin.import_playbook: "{{ _ce_provision_base_dir }}/plays/aws_ec2_standalone/rds.yml" +# MySQL client - needs to happen after RDS instance is created +#- ansible.builtin.import_playbook: "{{ _ce_provision_base_dir }}/plays/aws_ec2_standalone/mysql_client.yml" diff --git a/plays/aws_region/README.md b/plays/aws_region/README.md new file mode 100644 index 000000000..8073b43fc --- /dev/null +++ b/plays/aws_region/README.md @@ -0,0 +1,3 @@ +# Base playbook for configuring an AWS region. + +@TODO provide example infra repo for use with the AWS EC2 inventory plugin. diff --git a/plays/aws_region/aws_region.yml b/plays/aws_region/aws_region.yml new file mode 100644 index 000000000..38974eeda --- /dev/null +++ b/plays/aws_region/aws_region.yml @@ -0,0 +1,17 @@ +--- +# Global infra setup. +- hosts: localhost + connection: local + become: false + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/_common" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/{{ _env_type }}" + # used for tagging + _profile: core + roles: + - _init + - _meta/aws_region + - _exit diff --git a/plays/controller/README.md b/plays/controller/README.md new file mode 100644 index 000000000..f27e06a85 --- /dev/null +++ b/plays/controller/README.md @@ -0,0 +1,31 @@ +# Base playbook for setting up an infra controller. +This playbook provides a model for managing an Ansible infra controller with ce-provision based at AWS. + +If your server is not in AWS or you are not using the AWS EC2 inventory plugin, you must ensure your server's hostname is in your Ansible hosts file (`config/hosts/hosts` or `hosts.yml`) and provide the same hostname in the `_provision_host` variable. Then call `provision.yml` directly, for example: + +```yaml +--- +- name: Configure my controller server. + ansible.builtin.import_playbook: "{{ _ce_provision_base_dir }}/plays/controller/provision.yml" + vars: + _env_type: util + _provision_host: controller.acme.com + _profile: controller +``` + +If you are using the AWS EC2 inventory plugin and the Code Enigme recommended set-up, you must provide the `_aws_resource_name` variable - note, this is hyphenated, no dots - and call `aws_controller.yml`, for example: + +```yaml +--- +- name: Configure my controller server at AWS. + ansible.builtin.import_playbook: "{{ _ce_provision_base_dir }}/plays/controller/aws_controller.yml" + vars: + _env_type: util + _aws_region: eu-west-1 + _aws_resource_name: controller-acme-com + _profile: controller +``` + +This will create or find an EC2 instance with the AWS tag of `Name: controller-acme-com` which will be in an inventory group called `_controller_acme_com`. + +@TODO provide example infra repo for use with the AWS EC2 inventory plugin. diff --git a/plays/controller/aws_controller.yml b/plays/controller/aws_controller.yml new file mode 100644 index 000000000..2c3380008 --- /dev/null +++ b/plays/controller/aws_controller.yml @@ -0,0 +1,7 @@ +--- +# Creates hosts entry so play isn't skipped. +- ansible.builtin.import_playbook: ../aws_ec2_standalone/launch.yml +# Spins up the instance. +- ansible.builtin.import_playbook: ../aws_ec2_standalone/ec2.yml +# Actual provisioning +- ansible.builtin.import_playbook: provision.yml diff --git a/plays/controller/provision.yml b/plays/controller/provision.yml new file mode 100644 index 000000000..7ef6c54ea --- /dev/null +++ b/plays/controller/provision.yml @@ -0,0 +1,22 @@ +--- +- hosts: "{{ _provision_host | default('_' + _aws_resource_name | regex_replace('-', '_')) }}" + become: true + + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/_common" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/{{ _env_type }}" + - "{{ _ce_provision_build_dir }}/vars/{{ _aws_resource_name }}" + _profile: controller + + tasks: + - ansible.builtin.import_role: + name: _init + - ansible.builtin.import_role: + name: _meta/aws_client_instance + - ansible.builtin.import_role: + name: _meta/controller + - ansible.builtin.import_role: + name: _exit diff --git a/plays/deploy/README.md b/plays/deploy/README.md new file mode 100644 index 000000000..498355b3e --- /dev/null +++ b/plays/deploy/README.md @@ -0,0 +1,31 @@ +# Base playbook for setting up a deploy server. +This playbook provides a model for managing an Ansible application deployment server with ce-deploy based at AWS. + +If your server is not in AWS or you are not using the AWS EC2 inventory plugin, you must ensure your server's hostname is in your Ansible hosts file (`config/hosts/hosts` or `hosts.yml`) and provide the same hostname in the `_provision_host` variable. Then call `provision.yml` directly, for example: + +```yaml +--- +- name: Configure my deploy server. + ansible.builtin.import_playbook: "{{ _ce_provision_base_dir }}/plays/deploy/provision.yml" + vars: + _env_type: util + _provision_host: deploy.acme.com + _profile: deploy +``` + +If you are using the AWS EC2 inventory plugin and the Code Enigme recommended set-up, you must provide the `_aws_resource_name` variable - note, this is hyphenated, no dots - and call `aws_deploy.yml`, for example: + +```yaml +--- +- name: Configure my deploy server at AWS. + ansible.builtin.import_playbook: "{{ _ce_provision_base_dir }}/plays/deploy/aws_deploy.yml" + vars: + _env_type: util + _aws_region: eu-west-1 + _aws_resource_name: deploy-acme-com + _profile: deploy +``` + +This will create or find an EC2 instance with the AWS tag of `Name: deploy-acme-com` which will be in an inventory group called `_deploy_acme_com`. + +@TODO provide example infra repo for use with the AWS EC2 inventory plugin. diff --git a/plays/deploy/aws_deploy.yml b/plays/deploy/aws_deploy.yml new file mode 100644 index 000000000..2c3380008 --- /dev/null +++ b/plays/deploy/aws_deploy.yml @@ -0,0 +1,7 @@ +--- +# Creates hosts entry so play isn't skipped. +- ansible.builtin.import_playbook: ../aws_ec2_standalone/launch.yml +# Spins up the instance. +- ansible.builtin.import_playbook: ../aws_ec2_standalone/ec2.yml +# Actual provisioning +- ansible.builtin.import_playbook: provision.yml diff --git a/plays/deploy/provision.yml b/plays/deploy/provision.yml new file mode 100644 index 000000000..4d4baac7e --- /dev/null +++ b/plays/deploy/provision.yml @@ -0,0 +1,22 @@ +--- +- hosts: "{{ _provision_host | default('_' + _aws_resource_name | regex_replace('-', '_')) }}" + become: true + + vars: + _init: + vars_dirs: + - "{{ _ce_provision_build_dir }}/vars/_global" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/_common" + - "{{ _ce_provision_build_dir }}/vars/_regions/{{ _aws_region }}/{{ _env_type }}" + - "{{ _ce_provision_build_dir }}/vars/{{ _aws_resource_name }}" + _profile: deploy + + tasks: + - ansible.builtin.import_role: + name: _init + - ansible.builtin.import_role: + name: _meta/aws_client_instance + - ansible.builtin.import_role: + name: _meta/deploy + - ansible.builtin.import_role: + name: _exit diff --git a/roles/_init/defaults/main.yml b/roles/_init/defaults/main.yml index 5c2d85d42..5a106ce4c 100644 --- a/roles/_init/defaults/main.yml +++ b/roles/_init/defaults/main.yml @@ -13,6 +13,12 @@ _ce_ansible_timer_name: upgrade_ansible #_aws_profile: example # boto profile name #_aws_region: eu-west-1 +# AWS tags +_aws_resource_name: "" # Name +# _profile: web_server # Profile +# _env_type: dev # Env +# _infra_name: acme # Infra + _init: # A list of var directories to include. We only support .yml extensions. # This is used to detect if the playbook must re-run or not. diff --git a/roles/debian/firewall_config/defaults/main.yml b/roles/debian/firewall_config/defaults/main.yml index 7c9193af6..4ccc5600f 100644 --- a/roles/debian/firewall_config/defaults/main.yml +++ b/roles/debian/firewall_config/defaults/main.yml @@ -13,6 +13,7 @@ firewall_config: rulesets: - ssh_open - web_open + - common_network # rule always needs to be last so the DROP rules in the OUTPUT chain get applied at the end # Ruleset definitions # Permitted rule lists @@ -43,6 +44,29 @@ firewall_config: letsencrypt: firewall_allowed_tcp_ports: - "80" + # Standard ports for Prometheus outbound rules to allow scraping of exporters + prometheus_server_scraping: + firewall_additional_rules: + - "iptables -A OUTPUT -p tcp --dport 9100 -j ACCEPT" # allow scraping node exporter + - "iptables -A OUTPUT -p tcp --dport 9101 -j ACCEPT" # allow scraping process exporter + - "iptables -A OUTPUT -p tcp --dport 9093 -j ACCEPT" # allow posting to alertmanager + - "iptables -A OUTPUT -p tcp --dport 9115 -j ACCEPT" # allow scraping blackbox exporter + # Commonly required outbound ports for PHP web servers + common_web: + firewall_additional_rules: + - "iptables -A OUTPUT -p tcp --dport 2049 -j ACCEPT" # allow NFS + - "iptables -A OUTPUT -p udp --dport 2049 -j ACCEPT" # allow NFS + - "iptables -A OUTPUT -p tcp --dport 3306 -j ACCEPT" # allow MySQL + # Recommended general firewall settings + common_network: + firewall_additional_rules: + - "iptables -A INPUT -p icmp --icmp-type 8 -s 0/0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT" # ICMP ping in + - "iptables -A INPUT -p icmp --icmp-type 128 -s 0/0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT" # ICMP ping in + - "iptables -A OUTPUT -p icmp --icmp-type 0 -d 0/0 -m state --state ESTABLISHED,RELATED -j ACCEPT" # ICMP ping out + - "iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT" # established connections out + - "iptables -A OUTPUT -o lo -j ACCEPT" # allow all local traffic + - "iptables -A OUTPUT -p tcp --dport 1025:65535 -j DROP" # block high port tcp traffic outbound + - "iptables -A OUTPUT -p udp --dport 1025:65535 -j DROP" # block high port udp traffic outbound ossec: firewall_allowed_udp_ports: - "1514"