├── .github └── workflows │ ├── ci.yml │ └── release.yml ├── .yamllint ├── LICENSE ├── README.md ├── defaults └── main.yml ├── handlers └── main.yml ├── meta └── main.yml ├── molecule ├── default │ ├── converge.yml │ ├── molecule.yml │ └── verify.yml └── docker │ ├── Dockerfile.centos7 │ ├── Dockerfile.j2 │ ├── INSTALL.rst │ ├── create.yml │ ├── destroy.yml │ ├── molecule.yml │ ├── playbook.yml │ └── prepare.yml ├── tasks └── main.yml ├── tests ├── inventory └── test.yml └── vars └── main.yml /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 'on': 4 | pull_request: 5 | workflow_dispatch: 6 | push: 7 | branches: 8 | - master 9 | schedule: 10 | - cron: "0 1 * * 3" 11 | 12 | defaults: 13 | run: 14 | working-directory: 'redhatofficial.rhel7-cui' 15 | 16 | jobs: 17 | 18 | lint: 19 | name: Lint 20 | runs-on: ubuntu-latest 21 | steps: 22 | - name: Check out the codebase. 23 | uses: actions/checkout@v2 24 | with: 25 | path: 'redhatofficial.rhel7-cui' 26 | 27 | - name: Set up Python 3. 28 | uses: actions/setup-python@v2 29 | with: 30 | python-version: '3.x' 31 | 32 | - name: Install test dependencies. 33 | run: pip3 install yamllint 34 | 35 | - name: Lint code. 36 | run: | 37 | yamllint . 38 | 39 | molecule: 40 | name: Molecule 41 | runs-on: ubuntu-latest 42 | strategy: 43 | matrix: 44 | distro: 45 | - centos7 46 | 47 | steps: 48 | - name: Check out the codebase. 49 | uses: actions/checkout@v2 50 | with: 51 | path: 'redhatofficial.rhel7-cui' 52 | 53 | - name: Set up Python 3. 54 | uses: actions/setup-python@v2 55 | with: 56 | python-version: '3.x' 57 | 58 | - name: Install test dependencies. 59 | run: pip3 install ansible molecule[docker] docker 60 | 61 | - name: Destroy existing molecule 62 | run: molecule destroy --scenario-name default 63 | 64 | - name: Run Molecule tests. 65 | run: molecule -vvv test --scenario-name default 66 | env: 67 | PY_COLORS: '1' 68 | ANSIBLE_FORCE_COLOR: '1' 69 | MOLECULE_DISTRO: ${{ matrix.distro }} 70 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This workflow requires a GALAXY_API_KEY secret present in the GitHub 3 | # repository or organization. 4 | # 5 | # See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy 6 | # See: https://github.com/ansible/galaxy/issues/46 7 | 8 | name: Release 9 | 'on': 10 | workflow_dispatch: 11 | push: 12 | tags: 13 | - '*' 14 | 15 | defaults: 16 | run: 17 | working-directory: 'redhatofficial.rhel7-cui' 18 | 19 | jobs: 20 | 21 | release: 22 | name: Release 23 | runs-on: ubuntu-latest 24 | steps: 25 | - name: Check out the codebase. 26 | uses: actions/checkout@v2 27 | with: 28 | path: 'redhatofficial.rhel7-cui' 29 | 30 | - name: Set up Python 3. 31 | uses: actions/setup-python@v2 32 | with: 33 | python-version: '3.x' 34 | 35 | - name: Install Ansible. 36 | run: pip3 install ansible-base 37 | 38 | - name: Trigger a new import on Galaxy. 39 | run: ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} --role-name $(echo ${{ github.repository }} | cut -d/ -f2 | sed 's|ansible-role-||') $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) 40 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | # Based on ansible-lint config 3 | extends: default 4 | 5 | rules: 6 | braces: {max-spaces-inside: 1, level: error} 7 | brackets: {max-spaces-inside: 1, level: error} 8 | colons: {max-spaces-after: -1, level: error} 9 | commas: {max-spaces-after: -1, level: error} 10 | comments: disable 11 | comments-indentation: disable 12 | document-start: disable 13 | empty-lines: {max: 3, level: error} 14 | hyphens: {level: error} 15 | indentation: disable 16 | key-duplicates: enable 17 | line-length: disable 18 | new-line-at-end-of-file: disable 19 | new-lines: {type: unix} 20 | trailing-spaces: disable 21 | truthy: disable 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | SPDX license identifier: BSD-3-Clause 2 | Copyright (c) 2012-2017, Red Hat, Inc. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of the Red Hat nor the 13 | names of its contributors may be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Unclassified Information in Non-federal Information Systems and Organizations (NIST 800-171) 2 | ========= 3 | 4 | Ansible Role for Unclassified Information in Non-federal Information Systems and Organizations (NIST 800-171) 5 | 6 | Profile Description: 7 | From NIST 800-171, Section 2.2: 8 | Security requirements for protecting the confidentiality of CUI in non-federal 9 | information systems and organizations have a well-defined structure that 10 | consists of: 11 | (i) a basic security requirements section; 12 | (ii) a derived security requirements section. 13 | The basic security requirements are obtained from FIPS Publication 200, which 14 | provides the high-level and fundamental security requirements for federal 15 | information and information systems. The derived security requirements, which 16 | supplement the basic security requirements, are taken from the security controls 17 | in NIST Special Publication 800-53. 18 | This profile configures Red Hat Enterprise Linux 7 to the NIST Special 19 | Publication 800-53 controls identified for securing Controlled Unclassified 20 | Information (CUI). 21 | 22 | The tasks that are used in this role are generated using OpenSCAP. 23 | See the OpenSCAP project for more details on Ansible playbook generation at [https://github.com/OpenSCAP/openscap](https://github.com/OpenSCAP/openscap) 24 | 25 | To submit a fix or enhancement for an Ansible task that is failing or missing in this role, 26 | see the ComplianceAsCode project at [https://github.com/ComplianceAsCode/content](https://github.com/ComplianceAsCode/content) 27 | 28 | Requirements 29 | ------------ 30 | 31 | - Ansible version 2.9 or higher 32 | 33 | Role Variables 34 | -------------- 35 | 36 | To customize the role to your liking, check out the [list of variables](defaults/main.yml). 37 | 38 | Dependencies 39 | ------------ 40 | 41 | N/A 42 | 43 | Example Role Usage 44 | ---------------- 45 | 46 | Run `ansible-galaxy install RedHatOfficial.rhel7_cui` to 47 | download and install the role. Then, you can use the following playbook snippet to run the Ansible role: 48 | 49 | - hosts: all 50 | roles: 51 | - { role: RedHatOfficial.rhel7_cui } 52 | 53 | Next, check the playbook using (on the localhost) the following example: 54 | 55 | ansible-playbook -i "localhost," -c local --check playbook.yml 56 | 57 | To deploy it, use (this may change configuration of your local machine!): 58 | 59 | ansible-playbook -i "localhost," -c local playbook.yml 60 | 61 | License 62 | ------- 63 | 64 | BSD-3-Clause 65 | 66 | Author Information 67 | ------------------ 68 | 69 | This Ansible remediation role has been generated from the body of security 70 | policies developed by the ComplianceAsCode project. Please see 71 | [https://github.com/complianceascode/content/blob/master/Contributors.md](https://github.com/complianceascode/content/blob/master/Contributors.md) 72 | for an updated list of authors and contributors. 73 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for rhel7_cui 3 | var_password_pam_unix_remember: '5' 4 | var_accounts_passwords_pam_faillock_deny: '3' 5 | var_accounts_passwords_pam_faillock_fail_interval: '900' 6 | var_accounts_passwords_pam_faillock_unlock_time: '0' 7 | var_password_pam_dcredit: '-1' 8 | var_password_pam_difok: '4' 9 | var_password_pam_lcredit: '-1' 10 | var_password_pam_maxclassrepeat: '4' 11 | var_password_pam_maxrepeat: '3' 12 | var_password_pam_minlen: '12' 13 | var_password_pam_ocredit: '-1' 14 | var_password_pam_ucredit: '-1' 15 | var_accounts_max_concurrent_login_sessions: '10' 16 | var_accounts_user_umask: '027' 17 | var_auditd_flush: incremental_async 18 | sysctl_net_ipv6_conf_all_accept_ra_value: '0' 19 | sysctl_net_ipv6_conf_all_accept_redirects_value: '0' 20 | sysctl_net_ipv6_conf_all_accept_source_route_value: '0' 21 | sysctl_net_ipv6_conf_default_accept_ra_value: '0' 22 | sysctl_net_ipv6_conf_default_accept_redirects_value: '0' 23 | sysctl_net_ipv6_conf_default_accept_source_route_value: '0' 24 | sysctl_net_ipv4_conf_all_accept_redirects_value: '0' 25 | sysctl_net_ipv4_conf_all_accept_source_route_value: '0' 26 | sysctl_net_ipv4_conf_all_log_martians_value: '1' 27 | sysctl_net_ipv4_conf_all_rp_filter_value: '1' 28 | sysctl_net_ipv4_conf_all_secure_redirects_value: '0' 29 | sysctl_net_ipv4_conf_default_accept_redirects_value: '0' 30 | sysctl_net_ipv4_conf_default_accept_source_route_value: '0' 31 | sysctl_net_ipv4_conf_default_log_martians_value: '1' 32 | sysctl_net_ipv4_conf_default_rp_filter_value: '1' 33 | sysctl_net_ipv4_conf_default_secure_redirects_value: '0' 34 | sysctl_net_ipv4_icmp_echo_ignore_broadcasts_value: '1' 35 | sysctl_net_ipv4_icmp_ignore_bogus_error_responses_value: '1' 36 | sysctl_net_ipv4_tcp_syncookies_value: '1' 37 | sysctl_kernel_kptr_restrict_value: '1' 38 | var_slub_debug_options: P 39 | var_selinux_policy_name: targeted 40 | var_selinux_state: enforcing 41 | sshd_idle_timeout_value: '600' 42 | sshd_approved_ciphers: aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se 43 | sshd_approved_macs: hmac-sha2-512,hmac-sha2-256,hmac-sha1,hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com 44 | DISA_STIG_RHEL_07_010019: true 45 | DISA_STIG_RHEL_07_010090: true 46 | DISA_STIG_RHEL_07_010120: true 47 | DISA_STIG_RHEL_07_010130: true 48 | DISA_STIG_RHEL_07_010140: true 49 | DISA_STIG_RHEL_07_010150: true 50 | DISA_STIG_RHEL_07_010160: true 51 | DISA_STIG_RHEL_07_010180: true 52 | DISA_STIG_RHEL_07_010190: true 53 | DISA_STIG_RHEL_07_010280: true 54 | DISA_STIG_RHEL_07_010290: true 55 | DISA_STIG_RHEL_07_010300: true 56 | DISA_STIG_RHEL_07_010320: true 57 | DISA_STIG_RHEL_07_010375: true 58 | DISA_STIG_RHEL_07_010470: true 59 | DISA_STIG_RHEL_07_010481: true 60 | DISA_STIG_RHEL_07_020050: true 61 | DISA_STIG_RHEL_07_020060: true 62 | DISA_STIG_RHEL_07_020100: true 63 | DISA_STIG_RHEL_07_020101: true 64 | DISA_STIG_RHEL_07_020110: true 65 | DISA_STIG_RHEL_07_020210: true 66 | DISA_STIG_RHEL_07_020220: true 67 | DISA_STIG_RHEL_07_020230: true 68 | DISA_STIG_RHEL_07_021000: true 69 | DISA_STIG_RHEL_07_021024: true 70 | DISA_STIG_RHEL_07_021300: true 71 | DISA_STIG_RHEL_07_021350: true 72 | DISA_STIG_RHEL_07_030000: true 73 | DISA_STIG_RHEL_07_040000: true 74 | DISA_STIG_RHEL_07_040170: true 75 | DISA_STIG_RHEL_07_040320: true 76 | DISA_STIG_RHEL_07_040330: true 77 | DISA_STIG_RHEL_07_040340: true 78 | DISA_STIG_RHEL_07_040370: true 79 | DISA_STIG_RHEL_07_040430: true 80 | DISA_STIG_RHEL_07_040440: true 81 | DISA_STIG_RHEL_07_040450: true 82 | DISA_STIG_RHEL_07_040520: true 83 | DISA_STIG_RHEL_07_040610: true 84 | DISA_STIG_RHEL_07_040611: true 85 | DISA_STIG_RHEL_07_040612: true 86 | DISA_STIG_RHEL_07_040620: true 87 | DISA_STIG_RHEL_07_040630: true 88 | DISA_STIG_RHEL_07_040640: true 89 | DISA_STIG_RHEL_07_040641: true 90 | DISA_STIG_RHEL_07_040650: true 91 | DISA_STIG_RHEL_07_040660: true 92 | DISA_STIG_RHEL_07_040740: true 93 | DISA_STIG_RHEL_07_040830: true 94 | accounts_max_concurrent_login_sessions: true 95 | accounts_password_pam_dcredit: true 96 | accounts_password_pam_difok: true 97 | accounts_password_pam_lcredit: true 98 | accounts_password_pam_maxclassrepeat: true 99 | accounts_password_pam_maxrepeat: true 100 | accounts_password_pam_minlen: true 101 | accounts_password_pam_ocredit: true 102 | accounts_password_pam_ucredit: true 103 | accounts_password_pam_unix_remember: true 104 | accounts_passwords_pam_faillock_deny: true 105 | accounts_passwords_pam_faillock_interval: true 106 | accounts_passwords_pam_faillock_unlock_time: true 107 | accounts_umask_etc_bashrc: true 108 | accounts_umask_etc_csh_cshrc: true 109 | accounts_umask_etc_profile: true 110 | auditd_data_retention_flush: true 111 | configure_strategy: true 112 | disable_ctrlaltdel_burstaction: true 113 | disable_ctrlaltdel_reboot: true 114 | disable_host_auth: true 115 | disable_strategy: true 116 | disable_users_coredumps: true 117 | enable_strategy: true 118 | ensure_gpgcheck_globally_activated: true 119 | ensure_gpgcheck_local_packages: true 120 | ensure_gpgcheck_never_disabled: true 121 | ensure_redhat_gpgkey_installed: true 122 | grub2_audit_argument: true 123 | grub2_audit_backlog_limit_argument: true 124 | grub2_disable_interactive_boot: true 125 | grub2_enable_fips_mode: true 126 | grub2_page_poison_argument: true 127 | grub2_slub_debug_argument: true 128 | grub2_vsyscall_argument: true 129 | high_complexity: true 130 | high_disruption: true 131 | high_severity: true 132 | kernel_module_bluetooth_disabled: true 133 | kernel_module_cramfs_disabled: true 134 | kernel_module_dccp_disabled: true 135 | kernel_module_sctp_disabled: true 136 | low_complexity: true 137 | low_disruption: true 138 | low_severity: true 139 | medium_complexity: true 140 | medium_disruption: true 141 | medium_severity: true 142 | mount_option_dev_shm_nodev: true 143 | mount_option_dev_shm_noexec: true 144 | mount_option_dev_shm_nosuid: true 145 | mount_option_home_nodev: true 146 | mount_option_home_nosuid: true 147 | mount_option_tmp_nodev: true 148 | mount_option_tmp_noexec: true 149 | mount_option_tmp_nosuid: true 150 | mount_option_var_tmp_nodev: true 151 | mount_option_var_tmp_noexec: true 152 | mount_option_var_tmp_nosuid: true 153 | no_empty_passwords: true 154 | no_reboot_needed: true 155 | package_abrt_removed: true 156 | package_dracut_fips_installed: true 157 | package_screen_installed: true 158 | reboot_required: true 159 | require_singleuser_auth: true 160 | restrict_strategy: true 161 | securetty_root_login_console_only: true 162 | selinux_policytype: true 163 | selinux_state: true 164 | service_auditd_enabled: true 165 | service_autofs_disabled: true 166 | service_debug_shell_disabled: true 167 | service_firewalld_enabled: true 168 | service_kdump_disabled: true 169 | service_rpcbind_disabled: true 170 | sshd_disable_empty_passwords: true 171 | sshd_disable_gssapi_auth: true 172 | sshd_disable_kerb_auth: true 173 | sshd_disable_rhosts_rsa: true 174 | sshd_disable_root_login: true 175 | sshd_enable_strictmodes: true 176 | sshd_enable_warning_banner: true 177 | sshd_set_idle_timeout: true 178 | sshd_set_keepalive_0: true 179 | sshd_use_approved_ciphers: true 180 | sshd_use_approved_macs: true 181 | sysctl_fs_protected_hardlinks: true 182 | sysctl_fs_protected_symlinks: true 183 | sysctl_kernel_dmesg_restrict: true 184 | sysctl_kernel_kexec_load_disabled: true 185 | sysctl_kernel_kptr_restrict: true 186 | sysctl_kernel_yama_ptrace_scope: true 187 | sysctl_net_ipv4_conf_all_accept_redirects: true 188 | sysctl_net_ipv4_conf_all_accept_source_route: true 189 | sysctl_net_ipv4_conf_all_log_martians: true 190 | sysctl_net_ipv4_conf_all_rp_filter: true 191 | sysctl_net_ipv4_conf_all_secure_redirects: true 192 | sysctl_net_ipv4_conf_all_send_redirects: true 193 | sysctl_net_ipv4_conf_default_accept_redirects: true 194 | sysctl_net_ipv4_conf_default_accept_source_route: true 195 | sysctl_net_ipv4_conf_default_log_martians: true 196 | sysctl_net_ipv4_conf_default_rp_filter: true 197 | sysctl_net_ipv4_conf_default_secure_redirects: true 198 | sysctl_net_ipv4_conf_default_send_redirects: true 199 | sysctl_net_ipv4_icmp_echo_ignore_broadcasts: true 200 | sysctl_net_ipv4_icmp_ignore_bogus_error_responses: true 201 | sysctl_net_ipv4_ip_forward: true 202 | sysctl_net_ipv4_tcp_syncookies: true 203 | sysctl_net_ipv6_conf_all_accept_ra: true 204 | sysctl_net_ipv6_conf_all_accept_redirects: true 205 | sysctl_net_ipv6_conf_all_accept_source_route: true 206 | sysctl_net_ipv6_conf_default_accept_ra: true 207 | sysctl_net_ipv6_conf_default_accept_redirects: true 208 | sysctl_net_ipv6_conf_default_accept_source_route: true 209 | unknown_severity: true 210 | unknown_strategy: true 211 | -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for ansible-role-rhel7-cui 3 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | role_name: rhel7_cui 3 | author: ComplianceAsCode development team 4 | description: Unclassified Information in Non-federal Information Systems and Organizations (NIST 800-171) 5 | 6 | issue_tracker_url: https://github.com/ComplianceAsCode/content/issues 7 | 8 | license: BSD-3-Clause 9 | 10 | min_ansible_version: 2.9 11 | 12 | platforms: 13 | - name: EL 14 | versions: 15 | - 7 16 | 17 | galaxy_tags: [system, hardening, openscap, ssg, scap, security, compliance, complianceascode, 18 | redhatofficial, redhat, rhel7, cui] 19 | 20 | 21 | dependencies: [] 22 | -------------------------------------------------------------------------------- /molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | gather_facts: true 5 | become: true 6 | 7 | roles: 8 | - role: redhatofficial.rhel7-cui 9 | -------------------------------------------------------------------------------- /molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: docker 6 | platforms: 7 | - name: instance 8 | image: centos:8 9 | command: /sbin/init 10 | tmpfs: 11 | - /run 12 | - /tmp 13 | volumes: 14 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 15 | privileged: true 16 | pre_build_image: false 17 | provisioner: 18 | name: ansible 19 | config_options: 20 | defaults: 21 | local_tmp: /tmp/ 22 | remote_tmp: /tmp/ 23 | playbooks: 24 | converge: ${MOLECULE_PLAYBOOK:-converge.yml} 25 | scenario: 26 | name: default 27 | test_sequence: 28 | - lint 29 | - cleanup 30 | - destroy 31 | - syntax 32 | - create 33 | - prepare 34 | - converge 35 | # - idempotence 36 | - cleanup 37 | - destroy 38 | -------------------------------------------------------------------------------- /molecule/default/verify.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This is an example playbook to execute Ansible tests. 3 | 4 | - name: Verify 5 | hosts: all 6 | gather_facts: false 7 | tasks: 8 | - name: Example assertion 9 | assert: 10 | that: true 11 | -------------------------------------------------------------------------------- /molecule/docker/Dockerfile.centos7: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | 3 | RUN yum -y install epel-release 4 | RUN yum -y swap -- remove fakesystemd -- install systemd systemd-libs; \ 5 | (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \ 6 | rm -f /lib/systemd/system/multi-user.target.wants/*; \ 7 | rm -f /etc/systemd/system/*.wants/*; \ 8 | rm -f /lib/systemd/system/local-fs.target.wants/*; \ 9 | rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ 10 | rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ 11 | rm -f /lib/systemd/system/basic.target.wants/*; \ 12 | rm -f /lib/systemd/system/anaconda.target.wants/*; 13 | 14 | RUN yum -y install openssh-server audit authconfig initscripts git sudo selinux-policy-targeted cronie firewalld; \ 15 | yum -y update; \ 16 | yum clean all 17 | 18 | # Fix for Travis docker containers 19 | RUN ssh-keygen -f /etc/ssh/ssh_host_ed25519_key -N '' -t ed25519 20 | RUN sed -i "s/disabled/permissive/g" -i /etc/selinux/config 21 | 22 | VOLUME ["/sys/fs/cgroup", "/var/log/audit"] 23 | 24 | CMD ["/usr/sbin/init"] 25 | -------------------------------------------------------------------------------- /molecule/docker/Dockerfile.j2: -------------------------------------------------------------------------------- 1 | # Molecule managed 2 | 3 | {% if item.registry is defined %} 4 | FROM {{ item.registry.url }}/{{ item.image }} 5 | {% else %} 6 | FROM {{ item.image }} 7 | {% endif %} 8 | 9 | RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get upgrade -y && apt-get install -y python sudo bash ca-certificates && apt-get clean; \ 10 | elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python2-dnf bash && dnf clean all; \ 11 | elif [ $(command -v yum) ]; then yum makecache fast && yum update -y && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ 12 | elif [ $(command -v zypper) ]; then zypper refresh && zypper update -y && zypper install -y python sudo bash python-xml && zypper clean -a; \ 13 | elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ 14 | elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates && xbps-remove -O; fi 15 | -------------------------------------------------------------------------------- /molecule/docker/INSTALL.rst: -------------------------------------------------------------------------------- 1 | ******* 2 | Install 3 | ******* 4 | 5 | Requirements 6 | ============ 7 | 8 | * Docker Engine 9 | * docker-py 10 | 11 | Install 12 | ======= 13 | 14 | .. code-block:: bash 15 | 16 | $ sudo pip install docker-py 17 | -------------------------------------------------------------------------------- /molecule/docker/create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}" 7 | tasks: 8 | - name: Log into a Docker registry 9 | docker_login: 10 | username: "{{ item.registry.credentials.username }}" 11 | password: "{{ item.registry.credentials.password }}" 12 | email: "{{ item.registry.credentials.email | default(omit) }}" 13 | registry: "{{ item.registry.url }}" 14 | docker_host: "{{ item.docker_host | default('unix://var/run/docker.sock') }}" 15 | with_items: "{{ molecule_yml.platforms }}" 16 | when: 17 | - item.registry is defined 18 | - item.registry.credentials is defined 19 | - item.registry.credentials.username is defined 20 | 21 | - name: Create Dockerfiles from image names 22 | template: 23 | src: "{{ molecule_scenario_directory }}/Dockerfile.{{ item.image | regex_replace(':', '') }}" 24 | dest: "{{ molecule_ephemeral_directory }}/Dockerfile_{{ item.image | regex_replace('[^a-zA-Z0-9_]', '_') }}" 25 | with_items: "{{ molecule_yml.platforms }}" 26 | register: platforms 27 | 28 | - name: Discover local Docker images 29 | docker_image_facts: 30 | name: "molecule_local/{{ item.item.name }}" 31 | docker_host: "{{ item.item.docker_host | default('unix://var/run/docker.sock') }}" 32 | with_items: "{{ platforms.results }}" 33 | register: docker_images 34 | 35 | - name: Build an Ansible compatible image 36 | docker_image: 37 | path: "{{ molecule_ephemeral_directory }}" 38 | name: "molecule_local/{{ item.item.image }}" 39 | docker_host: "{{ item.item.docker_host | default('unix://var/run/docker.sock') }}" 40 | dockerfile: "{{ item.item.dockerfile | default(item.invocation.module_args.dest) }}" 41 | force: "{{ item.item.force | default(true) }}" 42 | with_items: "{{ platforms.results }}" 43 | when: platforms.changed or docker_images.results | map(attribute='images') | select('equalto', []) | list | count >= 0 44 | 45 | - name: Create docker network(s) 46 | docker_network: 47 | name: "{{ item }}" 48 | docker_host: "{{ item.docker_host | default('unix://var/run/docker.sock') }}" 49 | state: present 50 | with_items: "{{ molecule_yml.platforms | molecule_get_docker_networks }}" 51 | 52 | - name: Create molecule instance(s) 53 | docker_container: 54 | name: "{{ item.name }}" 55 | docker_host: "{{ item.docker_host | default('unix://var/run/docker.sock') }}" 56 | hostname: "{{ item.name }}" 57 | image: "molecule_local/{{ item.image }}" 58 | state: started 59 | recreate: false 60 | log_driver: json-file 61 | command: "{{ item.command | default('bash -c \"while true; do sleep 10000; done\"') }}" 62 | privileged: "{{ item.privileged | default(omit) }}" 63 | volumes: "{{ item.volumes | default(omit) }}" 64 | capabilities: "{{ item.capabilities | default(omit) }}" 65 | exposed_ports: "{{ item.exposed_ports | default(omit) }}" 66 | published_ports: "{{ item.published_ports | default(omit) }}" 67 | ulimits: "{{ item.ulimits | default(omit) }}" 68 | networks: "{{ item.networks | default(omit) }}" 69 | dns_servers: "{{ item.dns_servers | default(omit) }}" 70 | register: server 71 | with_items: "{{ molecule_yml.platforms }}" 72 | async: 7200 73 | poll: 0 74 | 75 | - name: Wait for instance(s) creation to complete 76 | async_status: 77 | jid: "{{ item.ansible_job_id }}" 78 | register: docker_jobs 79 | until: docker_jobs.finished 80 | retries: 300 81 | with_items: "{{ server.results }}" 82 | -------------------------------------------------------------------------------- /molecule/docker/destroy.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Destroy 3 | hosts: localhost 4 | connection: local 5 | gather_facts: false 6 | no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}" 7 | tasks: 8 | - name: Destroy molecule instance(s) 9 | docker_container: 10 | name: "{{ item.name }}" 11 | docker_host: "{{ item.docker_host | default('unix://var/run/docker.sock') }}" 12 | state: absent 13 | force_kill: "{{ item.force_kill | default(true) }}" 14 | register: server 15 | with_items: "{{ molecule_yml.platforms }}" 16 | async: 7200 17 | poll: 0 18 | 19 | - name: Wait for instance(s) deletion to complete 20 | async_status: 21 | jid: "{{ item.ansible_job_id }}" 22 | register: docker_jobs 23 | until: docker_jobs.finished 24 | retries: 300 25 | with_items: "{{ server.results }}" 26 | 27 | - name: Delete docker network(s) 28 | docker_network: 29 | name: "{{ item }}" 30 | docker_host: "{{ item.docker_host | default('unix://var/run/docker.sock') }}" 31 | state: absent 32 | with_items: "{{ molecule_yml.platforms | molecule_get_docker_networks }}" 33 | -------------------------------------------------------------------------------- /molecule/docker/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: docker 6 | lint: 7 | name: yamllint 8 | options: 9 | config-file: .yamllint 10 | platforms: 11 | - name: instance 12 | image: centos:7 13 | volumes: 14 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 15 | command: /usr/sbin/init 16 | capabilities: 17 | - ALL 18 | privileged: true 19 | pull: false 20 | groups: 21 | - docker 22 | provisioner: 23 | name: ansible 24 | log: true 25 | lint: 26 | name: ansible-lint 27 | scenario: 28 | name: docker 29 | test_sequence: 30 | - lint 31 | - destroy 32 | - syntax 33 | - create 34 | - prepare 35 | - converge 36 | # - idempotence 37 | - destroy 38 | verifier: 39 | name: testinfra 40 | lint: 41 | name: flake8 42 | enabled: true 43 | -------------------------------------------------------------------------------- /molecule/docker/playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | roles: 5 | - role: ansible-role-rhel7-cui 6 | -------------------------------------------------------------------------------- /molecule/docker/prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Prepare 3 | hosts: all 4 | gather_facts: false 5 | tasks: [] 6 | -------------------------------------------------------------------------------- /tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | 3 | -------------------------------------------------------------------------------- /tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | connection: local 4 | become: true 5 | roles: 6 | - ansible-role-rhel7-cui 7 | -------------------------------------------------------------------------------- /vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for rhel7_cui 3 | --------------------------------------------------------------------------------