initial creation
This commit is contained in:
+201
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,2 @@
|
||||
# ansible
|
||||
Ansible Playbooks
|
||||
@@ -0,0 +1,16 @@
|
||||
Inventory Challenge
|
||||
|
||||
1. Create 3 Individual Hosts:
|
||||
⁃ mail.mycorp.local
|
||||
⁃ smtp.mycorp.local
|
||||
⁃ auth.mycorp.local
|
||||
2. Group the Domain Controllers:
|
||||
⁃ dc01.mycorp.local
|
||||
⁃ dc02.mycorp.local
|
||||
3. Group the London App servers:
|
||||
⁃ app01.ldn.mycorp.local
|
||||
⁃ app02.lnd.mycorp.local
|
||||
4. Group the Texas App Servers:
|
||||
⁃ app03.tx.mycorp.local
|
||||
⁃ app04.tx.mycorp.local
|
||||
5. Group the London and Texas servers in a single group called: itlappsrv
|
||||
@@ -0,0 +1,23 @@
|
||||
fruit:
|
||||
red:
|
||||
strawberry
|
||||
tomato
|
||||
orange:
|
||||
- orange
|
||||
yellow:
|
||||
- banana
|
||||
green:
|
||||
- grapes
|
||||
- watermelon
|
||||
total: 6
|
||||
|
||||
veg:
|
||||
yellow:
|
||||
- peppers
|
||||
orange:
|
||||
- carrot
|
||||
green:
|
||||
- broccoli
|
||||
- cabbage
|
||||
- lettuce
|
||||
total: 5
|
||||
@@ -0,0 +1,22 @@
|
||||
# Create a new file 'completed.yaml'
|
||||
|
||||
# Sort the items by catagory and by colour
|
||||
|
||||
# Add a total at the end
|
||||
|
||||
items:
|
||||
- banana
|
||||
- orange
|
||||
- strawberry
|
||||
- broccoli
|
||||
- cabbage
|
||||
- grapes
|
||||
- carrot
|
||||
- tomato
|
||||
- peppers
|
||||
- watermelon
|
||||
- lettuce
|
||||
|
||||
fruit:
|
||||
|
||||
veg:
|
||||
@@ -0,0 +1 @@
|
||||
web ansible_host=ec2-18-130-249-7.eu-west-2.compute.amazonaws.com ansible_port=22 ansible_user=ec2-user ansible_ssh_private_key_file=/Users/Keys/ansible_lnd_key.pem
|
||||
@@ -0,0 +1,7 @@
|
||||
all:
|
||||
hosts:
|
||||
web:
|
||||
ansible_host: ec2-3-8-144-7.eu-west-2.compute.amazonaws.com
|
||||
ansible_port: 22
|
||||
ansible_user: ec2-user
|
||||
ansible_ssh_private_key_file: /Users/Keys/ansible_lnd_key.pem
|
||||
@@ -0,0 +1,17 @@
|
||||
- hosts: localhost
|
||||
#gather_facts: no
|
||||
tasks:
|
||||
- name: Error Handling
|
||||
block:
|
||||
- name: Going to Fail
|
||||
debug:
|
||||
msg: "Running the module"
|
||||
- name: Spanner
|
||||
command: /bin/hsab
|
||||
- name: Never Runs
|
||||
debug:
|
||||
msg: "This Never Runs!"
|
||||
rescue:
|
||||
- name: "Something went wrong..."
|
||||
debug:
|
||||
msg: "The error was caught"
|
||||
@@ -0,0 +1,19 @@
|
||||
mail.mycorp.local
|
||||
smtp.mycorp.local
|
||||
auth.mycorp.local
|
||||
|
||||
[dc]
|
||||
dc01.mycorp.local
|
||||
dc02.mycorp.local
|
||||
|
||||
[ldnappsrv]
|
||||
app01.ldn.mycorp.local
|
||||
app02.lnd.mycorp.local
|
||||
|
||||
[txappsrv]
|
||||
app03.tx.mycorp.local
|
||||
app04.tx.mycorp.local
|
||||
|
||||
[itlappsrv:children]
|
||||
ldnappsrv
|
||||
txappsrv
|
||||
@@ -0,0 +1,20 @@
|
||||
all:
|
||||
hosts:
|
||||
mail.mycorp.local:
|
||||
smtp.mycorp.local:
|
||||
auth.mycorp.local:
|
||||
children:
|
||||
itlappsrv:
|
||||
children:
|
||||
lndappsrv:
|
||||
hosts:
|
||||
app01.ldn.mycorp.local:
|
||||
app02.ldn.mycorp.local:
|
||||
txappsrv:
|
||||
hosts:
|
||||
app03.tx.mycorp.local:
|
||||
app04.tx.mycorp.local:
|
||||
dc:
|
||||
children:
|
||||
dc01.mycorp.local:
|
||||
dc02.mycorp.local:
|
||||
@@ -0,0 +1,32 @@
|
||||
- hosts: web
|
||||
remote_user: root
|
||||
become: yes
|
||||
tasks:
|
||||
- name: Update All Packages
|
||||
yum:
|
||||
name: '*'
|
||||
state: latest
|
||||
- name: Install Apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: installed
|
||||
- name: Create The HTML File
|
||||
shell: echo "Hello From The Ansible Challenge" > /var/www/html/index.html
|
||||
args:
|
||||
executable: /bin/bash
|
||||
notify:
|
||||
- Reload Apache
|
||||
- name: Public IP
|
||||
shell:
|
||||
cmd: curl http://169.254.169.254/latest/meta-data/public-ipv4
|
||||
register: curl
|
||||
- debug: var=curl.stdout_lines
|
||||
- name: Uninstall Apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: removed
|
||||
handlers:
|
||||
- name: Reload Apache
|
||||
service:
|
||||
name: httpd
|
||||
state: reloaded
|
||||
@@ -0,0 +1,38 @@
|
||||
Role Name
|
||||
=========
|
||||
|
||||
A brief description of the role goes here.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
|
||||
|
||||
- hosts: servers
|
||||
roles:
|
||||
- { role: username.rolename, x: 42 }
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
BSD
|
||||
|
||||
Author Information
|
||||
------------------
|
||||
|
||||
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
# defaults file for db
|
||||
db_server: mariadb
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
# handlers file for db
|
||||
- name: Start DB
|
||||
service:
|
||||
name: "{{ db_server }}"
|
||||
state: started
|
||||
@@ -0,0 +1,53 @@
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
|
||||
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||
# - BSD-3-Clause (default)
|
||||
# - MIT
|
||||
# - GPL-2.0-or-later
|
||||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
|
||||
min_ansible_version: 2.9
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
|
||||
#
|
||||
# Provide a list of supported platforms, and for each platform a list of versions.
|
||||
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
|
||||
# To view available platforms and versions (or releases), visit:
|
||||
# https://galaxy.ansible.com/api/v1/platforms/
|
||||
#
|
||||
# platforms:
|
||||
# - name: Fedora
|
||||
# versions:
|
||||
# - all
|
||||
# - 25
|
||||
# - name: SomePlatform
|
||||
# versions:
|
||||
# - all
|
||||
# - 1.0
|
||||
# - 7
|
||||
# - 99.99
|
||||
|
||||
galaxy_tags: []
|
||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||
# remove the '[]' above, if you add tags to this list.
|
||||
#
|
||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||
# Maximum 20 tags per role.
|
||||
|
||||
dependencies: []
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
# tasks file for db
|
||||
- name: Install DB
|
||||
yum:
|
||||
name: "{{ db_server }}"
|
||||
state: installed
|
||||
notify:
|
||||
- Start DB
|
||||
- name: Display DB Installed
|
||||
debug:
|
||||
msg: "{{ db_server }}"
|
||||
@@ -0,0 +1,2 @@
|
||||
localhost
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- db
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
# vars file for db
|
||||
db_server: mysql
|
||||
@@ -0,0 +1,5 @@
|
||||
- hosts: web
|
||||
remote_user: root
|
||||
become: yes
|
||||
roles:
|
||||
- web
|
||||
@@ -0,0 +1,38 @@
|
||||
Role Name
|
||||
=========
|
||||
|
||||
A brief description of the role goes here.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
|
||||
|
||||
- hosts: servers
|
||||
roles:
|
||||
- { role: username.rolename, x: 42 }
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
BSD
|
||||
|
||||
Author Information
|
||||
------------------
|
||||
|
||||
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
|
||||
@@ -0,0 +1,2 @@
|
||||
---
|
||||
# defaults file for web
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
# handlers file for web
|
||||
- name: Start Web
|
||||
service:
|
||||
name: httpd
|
||||
state: started
|
||||
@@ -0,0 +1,54 @@
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
|
||||
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||
# - BSD-3-Clause (default)
|
||||
# - MIT
|
||||
# - GPL-2.0-or-later
|
||||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
|
||||
min_ansible_version: 2.9
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
|
||||
#
|
||||
# Provide a list of supported platforms, and for each platform a list of versions.
|
||||
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
|
||||
# To view available platforms and versions (or releases), visit:
|
||||
# https://galaxy.ansible.com/api/v1/platforms/
|
||||
#
|
||||
# platforms:
|
||||
# - name: Fedora
|
||||
# versions:
|
||||
# - all
|
||||
# - 25
|
||||
# - name: SomePlatform
|
||||
# versions:
|
||||
# - all
|
||||
# - 1.0
|
||||
# - 7
|
||||
# - 99.99
|
||||
|
||||
galaxy_tags: []
|
||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||
# remove the '[]' above, if you add tags to this list.
|
||||
#
|
||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||
# Maximum 20 tags per role.
|
||||
|
||||
dependencies:
|
||||
- db
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
# tasks file for web
|
||||
- name: Install Apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: installed
|
||||
notify:
|
||||
- Start Web
|
||||
@@ -0,0 +1,2 @@
|
||||
localhost
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
remote_user: root
|
||||
roles:
|
||||
- web
|
||||
@@ -0,0 +1,2 @@
|
||||
---
|
||||
# vars file for web
|
||||
@@ -0,0 +1,6 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: Delete EC2 Instance
|
||||
ec2_instance:
|
||||
name: "EC2 From Ansible"
|
||||
state: terminated
|
||||
@@ -0,0 +1,114 @@
|
||||
# Ansible EC2 external inventory script settings
|
||||
#
|
||||
|
||||
[ec2]
|
||||
|
||||
# to talk to a private eucalyptus instance uncomment these lines
|
||||
# and edit edit eucalyptus_host to be the host name of your cloud controller
|
||||
#eucalyptus = True
|
||||
#eucalyptus_host = clc.cloud.domain.org
|
||||
|
||||
# AWS regions to make calls to. Set this to 'all' to make request to all regions
|
||||
# in AWS and merge the results together. Alternatively, set this to a comma
|
||||
# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
|
||||
regions = eu-west-2
|
||||
regions_exclude = us-gov-west-1,cn-north-1
|
||||
|
||||
# When generating inventory, Ansible needs to know how to address a server.
|
||||
# Each EC2 instance has a lot of variables associated with it. Here is the list:
|
||||
# http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
|
||||
# Below are 2 variables that are used as the address of a server:
|
||||
# - destination_variable
|
||||
# - vpc_destination_variable
|
||||
|
||||
# This is the normal destination variable to use. If you are running Ansible
|
||||
# from outside EC2, then 'public_dns_name' makes the most sense. If you are
|
||||
# running Ansible from within EC2, then perhaps you want to use the internal
|
||||
# address, and should set this to 'private_dns_name'. The key of an EC2 tag
|
||||
# may optionally be used; however the boto instance variables hold precedence
|
||||
# in the event of a collision.
|
||||
destination_variable = public_dns_name
|
||||
|
||||
# For server inside a VPC, using DNS names may not make sense. When an instance
|
||||
# has 'subnet_id' set, this variable is used. If the subnet is public, setting
|
||||
# this to 'ip_address' will return the public IP address. For instances in a
|
||||
# private subnet, this should be set to 'private_ip_address', and Ansible must
|
||||
# be run from with EC2. The key of an EC2 tag may optionally be used; however
|
||||
# the boto instance variables hold precedence in the event of a collision.
|
||||
vpc_destination_variable = ip_address
|
||||
|
||||
# To tag instances on EC2 with the resource records that point to them from
|
||||
# Route53, uncomment and set 'route53' to True.
|
||||
route53 = False
|
||||
|
||||
# To exclude RDS instances from the inventory, uncomment and set to False.
|
||||
#rds = False
|
||||
|
||||
# Additionally, you can specify the list of zones to exclude looking up in
|
||||
# 'route53_excluded_zones' as a comma-separated list.
|
||||
# route53_excluded_zones = samplezone1.com, samplezone2.com
|
||||
|
||||
# By default, only EC2 instances in the 'running' state are returned. Set
|
||||
# 'all_instances' to True to return all instances regardless of state.
|
||||
all_instances = False
|
||||
|
||||
# By default, only RDS instances in the 'available' state are returned. Set
|
||||
# 'all_rds_instances' to True return all RDS instances regardless of state.
|
||||
all_rds_instances = False
|
||||
|
||||
# API calls to EC2 are slow. For this reason, we cache the results of an API
|
||||
# call. Set this to the path you want cache files to be written to. Two files
|
||||
# will be written to this directory:
|
||||
# - ansible-ec2.cache
|
||||
# - ansible-ec2.index
|
||||
cache_path = ~/.ansible/tmp
|
||||
|
||||
# The number of seconds a cache file is considered valid. After this many
|
||||
# seconds, a new API call will be made, and the cache file will be updated.
|
||||
# To disable the cache, set this value to 0
|
||||
cache_max_age = 300
|
||||
|
||||
# Organize groups into a nested/hierarchy instead of a flat namespace.
|
||||
nested_groups = False
|
||||
|
||||
# The EC2 inventory output can become very large. To manage its size,
|
||||
# configure which groups should be created.
|
||||
group_by_instance_id = False
|
||||
group_by_region = True
|
||||
group_by_availability_zone = False
|
||||
group_by_ami_id = False
|
||||
group_by_instance_type = True
|
||||
group_by_key_pair = False
|
||||
group_by_vpc_id = True
|
||||
group_by_security_group = False
|
||||
group_by_tag_keys = False
|
||||
group_by_tag_none = False
|
||||
group_by_route53_names = False
|
||||
group_by_rds_engine = False
|
||||
group_by_rds_parameter_group = False
|
||||
|
||||
# If you only want to include hosts that match a certain regular expression
|
||||
# pattern_include = stage-*
|
||||
|
||||
# If you want to exclude any hosts that match a certain regular expression
|
||||
# pattern_exclude = stage-*
|
||||
|
||||
# Instance filters can be used to control which instances are retrieved for
|
||||
# inventory. For the full list of possible filters, please read the EC2 API
|
||||
# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
|
||||
# Filters are key/value pairs separated by '=', to list multiple filters use
|
||||
# a list separated by commas. See examples below.
|
||||
|
||||
# Retrieve only instances with (key=value) env=stage tag
|
||||
# instance_filters = tag:env=stage
|
||||
|
||||
# Retrieve only instances with role=webservers OR role=dbservers tag
|
||||
# instance_filters = tag:role=webservers,tag:role=dbservers
|
||||
|
||||
# Retrieve only t1.micro instances OR instances with tag env=stage
|
||||
# instance_filters = instance-type=t1.micro,tag:env=stage
|
||||
|
||||
# You can use wildcards in filter values also. Below will list instances which
|
||||
# tag Name value matches webservers1*
|
||||
# (ex. webservers15, webservers1a, webservers123 etc)
|
||||
# instance_filters = tag:Name=webservers1*
|
||||
@@ -0,0 +1,803 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
EC2 external inventory script
|
||||
=================================
|
||||
|
||||
Generates inventory that Ansible can understand by making API request to
|
||||
AWS EC2 using the Boto library.
|
||||
|
||||
NOTE: This script assumes Ansible is being executed where the environment
|
||||
variables needed for Boto have already been set:
|
||||
export AWS_ACCESS_KEY_ID='AK123'
|
||||
export AWS_SECRET_ACCESS_KEY='abc123'
|
||||
|
||||
This script also assumes there is an ec2.ini file alongside it. To specify a
|
||||
different path to ec2.ini, define the EC2_INI_PATH environment variable:
|
||||
|
||||
export EC2_INI_PATH=/path/to/my_ec2.ini
|
||||
|
||||
If you're using eucalyptus you need to set the above variables and
|
||||
you need to define:
|
||||
|
||||
export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
|
||||
|
||||
For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
|
||||
|
||||
When run against a specific host, this script returns the following variables:
|
||||
- ec2_ami_launch_index
|
||||
- ec2_architecture
|
||||
- ec2_association
|
||||
- ec2_attachTime
|
||||
- ec2_attachment
|
||||
- ec2_attachmentId
|
||||
- ec2_client_token
|
||||
- ec2_deleteOnTermination
|
||||
- ec2_description
|
||||
- ec2_deviceIndex
|
||||
- ec2_dns_name
|
||||
- ec2_eventsSet
|
||||
- ec2_group_name
|
||||
- ec2_hypervisor
|
||||
- ec2_id
|
||||
- ec2_image_id
|
||||
- ec2_instanceState
|
||||
- ec2_instance_type
|
||||
- ec2_ipOwnerId
|
||||
- ec2_ip_address
|
||||
- ec2_item
|
||||
- ec2_kernel
|
||||
- ec2_key_name
|
||||
- ec2_launch_time
|
||||
- ec2_monitored
|
||||
- ec2_monitoring
|
||||
- ec2_networkInterfaceId
|
||||
- ec2_ownerId
|
||||
- ec2_persistent
|
||||
- ec2_placement
|
||||
- ec2_platform
|
||||
- ec2_previous_state
|
||||
- ec2_private_dns_name
|
||||
- ec2_private_ip_address
|
||||
- ec2_publicIp
|
||||
- ec2_public_dns_name
|
||||
- ec2_ramdisk
|
||||
- ec2_reason
|
||||
- ec2_region
|
||||
- ec2_requester_id
|
||||
- ec2_root_device_name
|
||||
- ec2_root_device_type
|
||||
- ec2_security_group_ids
|
||||
- ec2_security_group_names
|
||||
- ec2_shutdown_state
|
||||
- ec2_sourceDestCheck
|
||||
- ec2_spot_instance_request_id
|
||||
- ec2_state
|
||||
- ec2_state_code
|
||||
- ec2_state_reason
|
||||
- ec2_status
|
||||
- ec2_subnet_id
|
||||
- ec2_tenancy
|
||||
- ec2_virtualization_type
|
||||
- ec2_vpc_id
|
||||
|
||||
These variables are pulled out of a boto.ec2.instance object. There is a lack of
|
||||
consistency with variable spellings (camelCase and underscores) since this
|
||||
just loops through all variables the object exposes. It is preferred to use the
|
||||
ones with underscores when multiple exist.
|
||||
|
||||
In addition, if an instance has AWS Tags associated with it, each tag is a new
|
||||
variable named:
|
||||
- ec2_tag_[Key] = [Value]
|
||||
|
||||
Security groups are comma-separated in 'ec2_security_group_ids' and
|
||||
'ec2_security_group_names'.
|
||||
'''
|
||||
|
||||
# (c) 2012, Peter Sankauskas
|
||||
#
|
||||
# This file is part of Ansible,
|
||||
#
|
||||
# Ansible is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Ansible is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
######################################################################
|
||||
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
import re
|
||||
from time import time
|
||||
import boto
|
||||
from boto import ec2
|
||||
from boto import rds
|
||||
from boto import route53
|
||||
import ConfigParser
|
||||
from collections import defaultdict
|
||||
|
||||
try:
|
||||
import json
|
||||
except ImportError:
|
||||
import simplejson as json
|
||||
|
||||
|
||||
class Ec2Inventory(object):
|
||||
def _empty_inventory(self):
|
||||
return {"_meta" : {"hostvars" : {}}}
|
||||
|
||||
def __init__(self):
|
||||
''' Main execution path '''
|
||||
|
||||
# Inventory grouped by instance IDs, tags, security groups, regions,
|
||||
# and availability zones
|
||||
self.inventory = self._empty_inventory()
|
||||
|
||||
# Index of hostname (address) to instance ID
|
||||
self.index = {}
|
||||
|
||||
# Read settings and parse CLI arguments
|
||||
self.read_settings()
|
||||
self.parse_cli_args()
|
||||
|
||||
# Cache
|
||||
if self.args.refresh_cache:
|
||||
self.do_api_calls_update_cache()
|
||||
elif not self.is_cache_valid():
|
||||
self.do_api_calls_update_cache()
|
||||
|
||||
# Data to print
|
||||
if self.args.host:
|
||||
data_to_print = self.get_host_info()
|
||||
|
||||
elif self.args.list:
|
||||
# Display list of instances for inventory
|
||||
if self.inventory == self._empty_inventory():
|
||||
data_to_print = self.get_inventory_from_cache()
|
||||
else:
|
||||
data_to_print = self.json_format_dict(self.inventory, True)
|
||||
|
||||
print data_to_print
|
||||
|
||||
|
||||
def is_cache_valid(self):
|
||||
''' Determines if the cache files have expired, or if it is still valid '''
|
||||
|
||||
if os.path.isfile(self.cache_path_cache):
|
||||
mod_time = os.path.getmtime(self.cache_path_cache)
|
||||
current_time = time()
|
||||
if (mod_time + self.cache_max_age) > current_time:
|
||||
if os.path.isfile(self.cache_path_index):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def read_settings(self):
|
||||
''' Reads the settings from the ec2.ini file '''
|
||||
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
|
||||
ec2_ini_path = os.environ.get('EC2_INI_PATH', ec2_default_ini_path)
|
||||
config.read(ec2_ini_path)
|
||||
|
||||
# is eucalyptus?
|
||||
self.eucalyptus_host = None
|
||||
self.eucalyptus = False
|
||||
if config.has_option('ec2', 'eucalyptus'):
|
||||
self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
|
||||
if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
|
||||
self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
|
||||
|
||||
# Regions
|
||||
self.regions = []
|
||||
configRegions = config.get('ec2', 'regions')
|
||||
configRegions_exclude = config.get('ec2', 'regions_exclude')
|
||||
if (configRegions == 'all'):
|
||||
if self.eucalyptus_host:
|
||||
self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
|
||||
else:
|
||||
for regionInfo in ec2.regions():
|
||||
if regionInfo.name not in configRegions_exclude:
|
||||
self.regions.append(regionInfo.name)
|
||||
else:
|
||||
self.regions = configRegions.split(",")
|
||||
|
||||
# Destination addresses
|
||||
self.destination_variable = config.get('ec2', 'destination_variable')
|
||||
self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
|
||||
|
||||
# Route53
|
||||
self.route53_enabled = config.getboolean('ec2', 'route53')
|
||||
self.route53_excluded_zones = []
|
||||
if config.has_option('ec2', 'route53_excluded_zones'):
|
||||
self.route53_excluded_zones.extend(
|
||||
config.get('ec2', 'route53_excluded_zones', '').split(','))
|
||||
|
||||
# Include RDS instances?
|
||||
self.rds_enabled = True
|
||||
if config.has_option('ec2', 'rds'):
|
||||
self.rds_enabled = config.getboolean('ec2', 'rds')
|
||||
|
||||
# Return all EC2 and RDS instances (if RDS is enabled)
|
||||
if config.has_option('ec2', 'all_instances'):
|
||||
self.all_instances = config.getboolean('ec2', 'all_instances')
|
||||
else:
|
||||
self.all_instances = False
|
||||
if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
|
||||
self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
|
||||
else:
|
||||
self.all_rds_instances = False
|
||||
|
||||
# Cache related
|
||||
cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
|
||||
if not os.path.exists(cache_dir):
|
||||
os.makedirs(cache_dir)
|
||||
|
||||
self.cache_path_cache = cache_dir + "/ansible-ec2.cache"
|
||||
self.cache_path_index = cache_dir + "/ansible-ec2.index"
|
||||
self.cache_max_age = config.getint('ec2', 'cache_max_age')
|
||||
|
||||
# Configure nested groups instead of flat namespace.
|
||||
if config.has_option('ec2', 'nested_groups'):
|
||||
self.nested_groups = config.getboolean('ec2', 'nested_groups')
|
||||
else:
|
||||
self.nested_groups = False
|
||||
|
||||
# Configure which groups should be created.
|
||||
group_by_options = [
|
||||
'group_by_instance_id',
|
||||
'group_by_region',
|
||||
'group_by_availability_zone',
|
||||
'group_by_ami_id',
|
||||
'group_by_instance_type',
|
||||
'group_by_key_pair',
|
||||
'group_by_vpc_id',
|
||||
'group_by_security_group',
|
||||
'group_by_tag_keys',
|
||||
'group_by_tag_none',
|
||||
'group_by_route53_names',
|
||||
'group_by_rds_engine',
|
||||
'group_by_rds_parameter_group',
|
||||
]
|
||||
for option in group_by_options:
|
||||
if config.has_option('ec2', option):
|
||||
setattr(self, option, config.getboolean('ec2', option))
|
||||
else:
|
||||
setattr(self, option, True)
|
||||
|
||||
# Do we need to just include hosts that match a pattern?
|
||||
try:
|
||||
pattern_include = config.get('ec2', 'pattern_include')
|
||||
if pattern_include and len(pattern_include) > 0:
|
||||
self.pattern_include = re.compile(pattern_include)
|
||||
else:
|
||||
self.pattern_include = None
|
||||
except ConfigParser.NoOptionError, e:
|
||||
self.pattern_include = None
|
||||
|
||||
# Do we need to exclude hosts that match a pattern?
|
||||
try:
|
||||
pattern_exclude = config.get('ec2', 'pattern_exclude');
|
||||
if pattern_exclude and len(pattern_exclude) > 0:
|
||||
self.pattern_exclude = re.compile(pattern_exclude)
|
||||
else:
|
||||
self.pattern_exclude = None
|
||||
except ConfigParser.NoOptionError, e:
|
||||
self.pattern_exclude = None
|
||||
|
||||
# Instance filters (see boto and EC2 API docs). Ignore invalid filters.
|
||||
self.ec2_instance_filters = defaultdict(list)
|
||||
if config.has_option('ec2', 'instance_filters'):
|
||||
for instance_filter in config.get('ec2', 'instance_filters', '').split(','):
|
||||
instance_filter = instance_filter.strip()
|
||||
if not instance_filter or '=' not in instance_filter:
|
||||
continue
|
||||
filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
|
||||
if not filter_key:
|
||||
continue
|
||||
self.ec2_instance_filters[filter_key].append(filter_value)
|
||||
|
||||
def parse_cli_args(self):
|
||||
''' Command line argument processing '''
|
||||
|
||||
parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
|
||||
parser.add_argument('--list', action='store_true', default=True,
|
||||
help='List instances (default: True)')
|
||||
parser.add_argument('--host', action='store',
|
||||
help='Get all the variables about a specific instance')
|
||||
parser.add_argument('--refresh-cache', action='store_true', default=False,
|
||||
help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
|
||||
self.args = parser.parse_args()
|
||||
|
||||
|
||||
def do_api_calls_update_cache(self):
|
||||
''' Do API calls to each region, and save data in cache files '''
|
||||
|
||||
if self.route53_enabled:
|
||||
self.get_route53_records()
|
||||
|
||||
for region in self.regions:
|
||||
self.get_instances_by_region(region)
|
||||
if self.rds_enabled:
|
||||
self.get_rds_instances_by_region(region)
|
||||
|
||||
self.write_to_cache(self.inventory, self.cache_path_cache)
|
||||
self.write_to_cache(self.index, self.cache_path_index)
|
||||
|
||||
def connect(self, region):
|
||||
''' create connection to api server'''
|
||||
if self.eucalyptus:
|
||||
conn = boto.connect_euca(host=self.eucalyptus_host)
|
||||
conn.APIVersion = '2010-08-31'
|
||||
else:
|
||||
conn = ec2.connect_to_region(region)
|
||||
# connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
|
||||
if conn is None:
|
||||
self.fail_with_error("region name: %s likely not supported, or AWS is down. connection to region failed." % region)
|
||||
return conn
|
||||
|
||||
def get_instances_by_region(self, region):
|
||||
''' Makes an AWS EC2 API call to the list of instances in a particular
|
||||
region '''
|
||||
|
||||
try:
|
||||
conn = self.connect(region)
|
||||
reservations = []
|
||||
if self.ec2_instance_filters:
|
||||
for filter_key, filter_values in self.ec2_instance_filters.iteritems():
|
||||
reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
|
||||
else:
|
||||
reservations = conn.get_all_instances()
|
||||
|
||||
for reservation in reservations:
|
||||
for instance in reservation.instances:
|
||||
self.add_instance(instance, region)
|
||||
|
||||
except boto.exception.BotoServerError, e:
|
||||
if e.error_code == 'AuthFailure':
|
||||
error = self.get_auth_error_message()
|
||||
else:
|
||||
backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
|
||||
error = "Error connecting to %s backend.\n%s" % (backend, e.message)
|
||||
self.fail_with_error(error)
|
||||
|
||||
def get_rds_instances_by_region(self, region):
|
||||
''' Makes an AWS API call to the list of RDS instances in a particular
|
||||
region '''
|
||||
|
||||
try:
|
||||
conn = rds.connect_to_region(region)
|
||||
if conn:
|
||||
instances = conn.get_all_dbinstances()
|
||||
for instance in instances:
|
||||
self.add_rds_instance(instance, region)
|
||||
except boto.exception.BotoServerError, e:
|
||||
error = e.message
|
||||
if e.error_code == 'AuthFailure':
|
||||
error = self.get_auth_error_message()
|
||||
if not e.reason == "Forbidden":
|
||||
error = "Looks like AWS RDS is down:\n%s" % e.message
|
||||
self.fail_with_error(error)
|
||||
|
||||
def get_auth_error_message(self):
|
||||
''' create an informative error message if there is an issue authenticating'''
|
||||
errors = ["Authentication error retrieving ec2 inventory."]
|
||||
if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
|
||||
errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
|
||||
else:
|
||||
errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
|
||||
|
||||
boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
|
||||
boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
|
||||
if len(boto_config_found) > 0:
|
||||
errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
|
||||
else:
|
||||
errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
|
||||
|
||||
return '\n'.join(errors)
|
||||
|
||||
def fail_with_error(self, err_msg):
|
||||
'''log an error to std err for ansible-playbook to consume and exit'''
|
||||
sys.stderr.write(err_msg)
|
||||
sys.exit(1)
|
||||
|
||||
def get_instance(self, region, instance_id):
|
||||
conn = self.connect(region)
|
||||
|
||||
reservations = conn.get_all_instances([instance_id])
|
||||
for reservation in reservations:
|
||||
for instance in reservation.instances:
|
||||
return instance
|
||||
|
||||
def add_instance(self, instance, region):
|
||||
''' Adds an instance to the inventory and index, as long as it is
|
||||
addressable '''
|
||||
|
||||
# Only want running instances unless all_instances is True
|
||||
if not self.all_instances and instance.state != 'running':
|
||||
return
|
||||
|
||||
# Select the best destination address
|
||||
if instance.subnet_id:
|
||||
dest = getattr(instance, self.vpc_destination_variable, None)
|
||||
if dest is None:
|
||||
dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
|
||||
else:
|
||||
dest = getattr(instance, self.destination_variable, None)
|
||||
if dest is None:
|
||||
dest = getattr(instance, 'tags').get(self.destination_variable, None)
|
||||
|
||||
if not dest:
|
||||
# Skip instances we cannot address (e.g. private VPC subnet)
|
||||
return
|
||||
|
||||
# if we only want to include hosts that match a pattern, skip those that don't
|
||||
if self.pattern_include and not self.pattern_include.match(dest):
|
||||
return
|
||||
|
||||
# if we need to exclude hosts that match a pattern, skip those
|
||||
if self.pattern_exclude and self.pattern_exclude.match(dest):
|
||||
return
|
||||
|
||||
# Add to index
|
||||
self.index[dest] = [region, instance.id]
|
||||
|
||||
# Inventory: Group by instance ID (always a group of 1)
|
||||
if self.group_by_instance_id:
|
||||
self.inventory[instance.id] = [dest]
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'instances', instance.id)
|
||||
|
||||
# Inventory: Group by region
|
||||
if self.group_by_region:
|
||||
self.push(self.inventory, region, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'regions', region)
|
||||
|
||||
# Inventory: Group by availability zone
|
||||
if self.group_by_availability_zone:
|
||||
self.push(self.inventory, instance.placement, dest)
|
||||
if self.nested_groups:
|
||||
if self.group_by_region:
|
||||
self.push_group(self.inventory, region, instance.placement)
|
||||
self.push_group(self.inventory, 'zones', instance.placement)
|
||||
|
||||
# Inventory: Group by Amazon Machine Image (AMI) ID
|
||||
if self.group_by_ami_id:
|
||||
ami_id = self.to_safe(instance.image_id)
|
||||
self.push(self.inventory, ami_id, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'images', ami_id)
|
||||
|
||||
# Inventory: Group by instance type
|
||||
if self.group_by_instance_type:
|
||||
type_name = self.to_safe('type_' + instance.instance_type)
|
||||
self.push(self.inventory, type_name, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'types', type_name)
|
||||
|
||||
# Inventory: Group by key pair
|
||||
if self.group_by_key_pair and instance.key_name:
|
||||
key_name = self.to_safe('key_' + instance.key_name)
|
||||
self.push(self.inventory, key_name, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'keys', key_name)
|
||||
|
||||
# Inventory: Group by VPC
|
||||
if self.group_by_vpc_id and instance.vpc_id:
|
||||
vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
|
||||
self.push(self.inventory, vpc_id_name, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'vpcs', vpc_id_name)
|
||||
|
||||
# Inventory: Group by security group
|
||||
if self.group_by_security_group:
|
||||
try:
|
||||
for group in instance.groups:
|
||||
key = self.to_safe("security_group_" + group.name)
|
||||
self.push(self.inventory, key, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'security_groups', key)
|
||||
except AttributeError:
|
||||
self.fail_with_error('\n'.join(['Package boto seems a bit older.',
|
||||
'Please upgrade boto >= 2.3.0.']))
|
||||
|
||||
# Inventory: Group by tag keys
|
||||
if self.group_by_tag_keys:
|
||||
for k, v in instance.tags.iteritems():
|
||||
key = self.to_safe("tag_" + k + "=" + v)
|
||||
self.push(self.inventory, key, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
|
||||
self.push_group(self.inventory, self.to_safe("tag_" + k), key)
|
||||
|
||||
# Inventory: Group by Route53 domain names if enabled
|
||||
if self.route53_enabled and self.group_by_route53_names:
|
||||
route53_names = self.get_instance_route53_names(instance)
|
||||
for name in route53_names:
|
||||
self.push(self.inventory, name, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'route53', name)
|
||||
|
||||
# Global Tag: instances without tags
|
||||
if self.group_by_tag_none and len(instance.tags) == 0:
|
||||
self.push(self.inventory, 'tag_none', dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'tags', 'tag_none')
|
||||
|
||||
# Global Tag: tag all EC2 instances
|
||||
self.push(self.inventory, 'ec2', dest)
|
||||
|
||||
self.inventory["_meta"]["hostvars"][dest] = self.get_host_info_dict_from_instance(instance)
|
||||
|
||||
|
||||
def add_rds_instance(self, instance, region):
|
||||
''' Adds an RDS instance to the inventory and index, as long as it is
|
||||
addressable '''
|
||||
|
||||
# Only want available instances unless all_rds_instances is True
|
||||
if not self.all_rds_instances and instance.status != 'available':
|
||||
return
|
||||
|
||||
# Select the best destination address
|
||||
dest = instance.endpoint[0]
|
||||
|
||||
if not dest:
|
||||
# Skip instances we cannot address (e.g. private VPC subnet)
|
||||
return
|
||||
|
||||
# Add to index
|
||||
self.index[dest] = [region, instance.id]
|
||||
|
||||
# Inventory: Group by instance ID (always a group of 1)
|
||||
if self.group_by_instance_id:
|
||||
self.inventory[instance.id] = [dest]
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'instances', instance.id)
|
||||
|
||||
# Inventory: Group by region
|
||||
if self.group_by_region:
|
||||
self.push(self.inventory, region, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'regions', region)
|
||||
|
||||
# Inventory: Group by availability zone
|
||||
if self.group_by_availability_zone:
|
||||
self.push(self.inventory, instance.availability_zone, dest)
|
||||
if self.nested_groups:
|
||||
if self.group_by_region:
|
||||
self.push_group(self.inventory, region, instance.availability_zone)
|
||||
self.push_group(self.inventory, 'zones', instance.availability_zone)
|
||||
|
||||
# Inventory: Group by instance type
|
||||
if self.group_by_instance_type:
|
||||
type_name = self.to_safe('type_' + instance.instance_class)
|
||||
self.push(self.inventory, type_name, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'types', type_name)
|
||||
|
||||
# Inventory: Group by VPC
|
||||
if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
|
||||
vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
|
||||
self.push(self.inventory, vpc_id_name, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'vpcs', vpc_id_name)
|
||||
|
||||
# Inventory: Group by security group
|
||||
if self.group_by_security_group:
|
||||
try:
|
||||
if instance.security_group:
|
||||
key = self.to_safe("security_group_" + instance.security_group.name)
|
||||
self.push(self.inventory, key, dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'security_groups', key)
|
||||
|
||||
except AttributeError:
|
||||
self.fail_with_error('\n'.join(['Package boto seems a bit older.',
|
||||
'Please upgrade boto >= 2.3.0.']))
|
||||
|
||||
|
||||
# Inventory: Group by engine
|
||||
if self.group_by_rds_engine:
|
||||
self.push(self.inventory, self.to_safe("rds_" + instance.engine), dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
|
||||
|
||||
# Inventory: Group by parameter group
|
||||
if self.group_by_rds_parameter_group:
|
||||
self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), dest)
|
||||
if self.nested_groups:
|
||||
self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
|
||||
|
||||
# Global Tag: all RDS instances
|
||||
self.push(self.inventory, 'rds', dest)
|
||||
|
||||
self.inventory["_meta"]["hostvars"][dest] = self.get_host_info_dict_from_instance(instance)
|
||||
|
||||
|
||||
def get_route53_records(self):
|
||||
''' Get and store the map of resource records to domain names that
|
||||
point to them. '''
|
||||
|
||||
r53_conn = route53.Route53Connection()
|
||||
all_zones = r53_conn.get_zones()
|
||||
|
||||
route53_zones = [ zone for zone in all_zones if zone.name[:-1]
|
||||
not in self.route53_excluded_zones ]
|
||||
|
||||
self.route53_records = {}
|
||||
|
||||
for zone in route53_zones:
|
||||
rrsets = r53_conn.get_all_rrsets(zone.id)
|
||||
|
||||
for record_set in rrsets:
|
||||
record_name = record_set.name
|
||||
|
||||
if record_name.endswith('.'):
|
||||
record_name = record_name[:-1]
|
||||
|
||||
for resource in record_set.resource_records:
|
||||
self.route53_records.setdefault(resource, set())
|
||||
self.route53_records[resource].add(record_name)
|
||||
|
||||
|
||||
def get_instance_route53_names(self, instance):
|
||||
''' Check if an instance is referenced in the records we have from
|
||||
Route53. If it is, return the list of domain names pointing to said
|
||||
instance. If nothing points to it, return an empty list. '''
|
||||
|
||||
instance_attributes = [ 'public_dns_name', 'private_dns_name',
|
||||
'ip_address', 'private_ip_address' ]
|
||||
|
||||
name_list = set()
|
||||
|
||||
for attrib in instance_attributes:
|
||||
try:
|
||||
value = getattr(instance, attrib)
|
||||
except AttributeError:
|
||||
continue
|
||||
|
||||
if value in self.route53_records:
|
||||
name_list.update(self.route53_records[value])
|
||||
|
||||
return list(name_list)
|
||||
|
||||
|
||||
def get_host_info_dict_from_instance(self, instance):
|
||||
instance_vars = {}
|
||||
for key in vars(instance):
|
||||
value = getattr(instance, key)
|
||||
key = self.to_safe('ec2_' + key)
|
||||
|
||||
# Handle complex types
|
||||
# state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
|
||||
if key == 'ec2__state':
|
||||
instance_vars['ec2_state'] = instance.state or ''
|
||||
instance_vars['ec2_state_code'] = instance.state_code
|
||||
elif key == 'ec2__previous_state':
|
||||
instance_vars['ec2_previous_state'] = instance.previous_state or ''
|
||||
instance_vars['ec2_previous_state_code'] = instance.previous_state_code
|
||||
elif type(value) in [int, bool]:
|
||||
instance_vars[key] = value
|
||||
elif type(value) in [str, unicode]:
|
||||
instance_vars[key] = value.strip()
|
||||
elif type(value) == type(None):
|
||||
instance_vars[key] = ''
|
||||
elif key == 'ec2_region':
|
||||
instance_vars[key] = value.name
|
||||
elif key == 'ec2__placement':
|
||||
instance_vars['ec2_placement'] = value.zone
|
||||
elif key == 'ec2_tags':
|
||||
for k, v in value.iteritems():
|
||||
key = self.to_safe('ec2_tag_' + k)
|
||||
instance_vars[key] = v
|
||||
elif key == 'ec2_groups':
|
||||
group_ids = []
|
||||
group_names = []
|
||||
for group in value:
|
||||
group_ids.append(group.id)
|
||||
group_names.append(group.name)
|
||||
instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
|
||||
instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
|
||||
else:
|
||||
pass
|
||||
# TODO Product codes if someone finds them useful
|
||||
#print key
|
||||
#print type(value)
|
||||
#print value
|
||||
|
||||
return instance_vars
|
||||
|
||||
def get_host_info(self):
|
||||
''' Get variables about a specific host '''
|
||||
|
||||
if len(self.index) == 0:
|
||||
# Need to load index from cache
|
||||
self.load_index_from_cache()
|
||||
|
||||
if not self.args.host in self.index:
|
||||
# try updating the cache
|
||||
self.do_api_calls_update_cache()
|
||||
if not self.args.host in self.index:
|
||||
# host might not exist anymore
|
||||
return self.json_format_dict({}, True)
|
||||
|
||||
(region, instance_id) = self.index[self.args.host]
|
||||
|
||||
instance = self.get_instance(region, instance_id)
|
||||
return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
|
||||
|
||||
def push(self, my_dict, key, element):
|
||||
''' Push an element onto an array that may not have been defined in
|
||||
the dict '''
|
||||
group_info = my_dict.setdefault(key, [])
|
||||
if isinstance(group_info, dict):
|
||||
host_list = group_info.setdefault('hosts', [])
|
||||
host_list.append(element)
|
||||
else:
|
||||
group_info.append(element)
|
||||
|
||||
def push_group(self, my_dict, key, element):
|
||||
''' Push a group as a child of another group. '''
|
||||
parent_group = my_dict.setdefault(key, {})
|
||||
if not isinstance(parent_group, dict):
|
||||
parent_group = my_dict[key] = {'hosts': parent_group}
|
||||
child_groups = parent_group.setdefault('children', [])
|
||||
if element not in child_groups:
|
||||
child_groups.append(element)
|
||||
|
||||
def get_inventory_from_cache(self):
|
||||
''' Reads the inventory from the cache file and returns it as a JSON
|
||||
object '''
|
||||
|
||||
cache = open(self.cache_path_cache, 'r')
|
||||
json_inventory = cache.read()
|
||||
return json_inventory
|
||||
|
||||
|
||||
def load_index_from_cache(self):
|
||||
''' Reads the index from the cache file sets self.index '''
|
||||
|
||||
cache = open(self.cache_path_index, 'r')
|
||||
json_index = cache.read()
|
||||
self.index = json.loads(json_index)
|
||||
|
||||
|
||||
def write_to_cache(self, data, filename):
|
||||
''' Writes data in JSON format to a file '''
|
||||
|
||||
json_data = self.json_format_dict(data, True)
|
||||
cache = open(filename, 'w')
|
||||
cache.write(json_data)
|
||||
cache.close()
|
||||
|
||||
|
||||
def to_safe(self, word):
|
||||
''' Converts 'bad' characters in a string to underscores so they can be
|
||||
used as Ansible groups '''
|
||||
|
||||
return re.sub("[^A-Za-z0-9\-]", "_", word)
|
||||
|
||||
|
||||
def json_format_dict(self, data, pretty=False):
|
||||
''' Converts a dict to a JSON object and dumps it as a formatted
|
||||
string '''
|
||||
|
||||
if pretty:
|
||||
return json.dumps(data, sort_keys=True, indent=2)
|
||||
else:
|
||||
return json.dumps(data)
|
||||
|
||||
|
||||
# Run the script
|
||||
Ec2Inventory()
|
||||
@@ -0,0 +1,19 @@
|
||||
- hosts: ec2
|
||||
remote_user: root
|
||||
#become: yes
|
||||
strategy: free
|
||||
serial:
|
||||
- "50%"
|
||||
vars:
|
||||
ansible_port: 22
|
||||
ansible_user: ec2-user
|
||||
ansible_ssh_private_key_file: /Users/Keys/ansible_lnd_key.pem
|
||||
tasks:
|
||||
- name: Install Apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: installed
|
||||
- name: Remove Apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: removed
|
||||
@@ -0,0 +1,14 @@
|
||||
- hosts: localhost
|
||||
tasks:
|
||||
- name: Create EC2 Instance
|
||||
ec2_instance:
|
||||
name: "EC2 From Ansible"
|
||||
key_name: "ansible_key"
|
||||
vpc_subnet_id: subnet-33f7f248
|
||||
instance_type: t2.micro
|
||||
security_group: ansible-SG
|
||||
network:
|
||||
assign_public_ip: true
|
||||
image_id: ami-0a13d44dccf1f5cf6
|
||||
tags:
|
||||
Environment: course
|
||||
@@ -0,0 +1,15 @@
|
||||
web.mydomain.local
|
||||
|
||||
[db]
|
||||
db1.mydomain.local
|
||||
db2.mydomain.local
|
||||
db3.mydomain.local
|
||||
|
||||
[web]
|
||||
web1.mydomain.local
|
||||
web2.mydomain.local
|
||||
web3.mydomain.local
|
||||
|
||||
[customer1:children]
|
||||
db
|
||||
web
|
||||
@@ -0,0 +1,13 @@
|
||||
all:
|
||||
hosts:
|
||||
web.mydomain.local:
|
||||
children:
|
||||
customer1:
|
||||
children:
|
||||
db:
|
||||
hosts:
|
||||
db1.mydomain.local:
|
||||
db2.mydomain.local:
|
||||
web:
|
||||
hosts:
|
||||
web1.mydomain.local:
|
||||
@@ -0,0 +1,12 @@
|
||||
- hosts: web
|
||||
remote_user: root
|
||||
become: yes
|
||||
tasks:
|
||||
- name: Install Apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: installed
|
||||
- name: Remove Apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: removed
|
||||
@@ -0,0 +1,9 @@
|
||||
- hosts: web
|
||||
remote_user: root
|
||||
become: yes
|
||||
tasks:
|
||||
- name: Curl AWS
|
||||
shell:
|
||||
cmd: curl http://169.254.169.254/latest/meta-data/public-ipv4
|
||||
register: curl
|
||||
- debug: var=curl.stdout_lines
|
||||
@@ -0,0 +1,40 @@
|
||||
- hosts: web
|
||||
remote_user: root
|
||||
become: yes
|
||||
tasks:
|
||||
- name: Install Apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: installed
|
||||
notify:
|
||||
- Restart Apache
|
||||
- name: Install nano
|
||||
yum:
|
||||
name: nano
|
||||
state: installed
|
||||
notify:
|
||||
- Restart Apache
|
||||
- name: Install MySQL
|
||||
yum:
|
||||
name: mysql
|
||||
state: installed
|
||||
notify:
|
||||
- Restart Apache
|
||||
- name: Remove Apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: removed
|
||||
- name: Remove nano
|
||||
yum:
|
||||
name: nano
|
||||
state: removed
|
||||
- name: Remove MySQL
|
||||
yum:
|
||||
name: httpd
|
||||
state: removed
|
||||
|
||||
handlers:
|
||||
- name: Restart Apache
|
||||
service:
|
||||
name: httpd
|
||||
state: restarted
|
||||
@@ -0,0 +1,16 @@
|
||||
- hosts: web
|
||||
remote_user: root
|
||||
become: yes
|
||||
tasks:
|
||||
- name: Install Apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: installed
|
||||
- name: Restart Apache
|
||||
service:
|
||||
name: httpd
|
||||
state: restarted
|
||||
- name: Remove Apache
|
||||
yum:
|
||||
name: httpd
|
||||
state: removed
|
||||
@@ -0,0 +1,754 @@
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"name": ".",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": ".yamllint",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "ea9c022c870d63c602c98b0b8a974f3e6df7c8598ed50a17a6f843236e3b6c55",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": ".github",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": ".github/FUNDING.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "79668fbcce7748a95cecebf6f35cfc297d5ffb733aff93c4d82164ee8e967504",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "molecule",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "molecule/test-manifests",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "molecule/test-manifests/converge.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "e108714d4d02df6baf5b1221b992f975467d3b8766aa5f6f614a7a2103759cfa",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "molecule/test-manifests/molecule.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "93f518730c4d3e009541ef78757da0b10c7e3af6166540bf3d6c083a8dcafbae",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "molecule/test-manifests/asserts.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "f8ee48d77d8128e2ed9ce3c1761511c48bc36790dea371a0d801c0b6d59070fc",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "molecule/test-manifests/prepare.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "0b87913e75935090db08ed033d3b536889dff9532c342155ebae2bb176977d58",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "molecule/default",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "molecule/default/converge.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "9f6663b4aaa20ab52410d1f85514de6919347bbcbbd684e121ac8ab6abac4dc4",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "molecule/default/molecule.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "48c7705819bfd476512513c35066cf1cbbb5df689d27984c5175a5c0b2762f37",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "molecule/default/asserts.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "d39f4ef4ff8b9d484806950abca2fbfc57a80203933fead56185f1fae02fcc2a",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "molecule/default/prepare.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "ed92dda245eae11ed01d92b01119b9a85de9d31f48873864c9b531cf39764a7f",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "README.md",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "516bf6f2077c7719805158531e383b84baef29a0dae4cd1afe335b17bbb491d2",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": ".gitignore",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "eae89391a86cb13a7c95f9ba1add1c34bef2952e1905a8716df48bae3c529cdf",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "scripts",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "scripts/templates",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "scripts/templates/galaxy.yml.j2",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "145622277ffa73288bec3e68485dc2fd4a73e2fc32f39b61bd7344193dd8409b",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "scripts/deploy.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "9c6cc713d631428a541e49859704ce170a028fe5e971ac95b7a7dcee9ff5fcbe",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": ".dpl",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": ".travis.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "3530916e685c7c8978fc70d068ad5af9014a993097e8951e1fb7771b556248c3",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/.yamllint",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "3254c2ae6aaffcb2c25db3a791e0dbcde9e2ce3a648cf49eb063e282e404f72a",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/tasks",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/tasks/deploy-manifest.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "38eeb6ef535cbe5d9d40b5c3dcb70591391cef78c547813b6b29e8751502c21b",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/tasks/main.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "0f14788ff585b03c39f03a816e1056d17437ad1e488ff8c00f20e369c1afbc1d",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/.github",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/.github/stale.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "7cc3fcc887d4929ca0421ca13bbb31d03b2c502e41a913d18158bffbee9f7bee",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/.github/FUNDING.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "79668fbcce7748a95cecebf6f35cfc297d5ffb733aff93c4d82164ee8e967504",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/molecule",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/molecule/default",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/molecule/default/converge.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "9118a5ec853b0f67824e79e6da69f37e817c0fe96cb06a618792ad7052b3e69a",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/molecule/default/molecule.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "02cf56b0d7038605e8524ca6963311dfb52b8b6cb6e85133bc9c665bb3e52fe9",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/README.md",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "60834f55e33f10414af1c0d0ff262634121808f058cecad65bc4acca3dbd7b91",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/k8s-manifests",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/k8s-manifests/README.md",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "3a16f73e75b85324a7ae61e584c89babdb9d1116b038e10470296fd6d19f1247",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/k8s-manifests/storageclass",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/k8s-manifests/storageclass/vars.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "b6f0c3ca0ab9ecb572cbc3d372a5054bcc854866386ea79f70faeb3340784be0",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/k8s-manifests/storageclass/manifest.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "1060421ceeef207051439bf6cf7bb6ca739c44e2b9b293398f938eefd46b5464",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/defaults",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/defaults/main.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "e7eb524eab7fcde17f85a72415c4a7ce27a02ba30a4abb7fde9d94ceffbba67e",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/.travis.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "082e60a441c570863a113532af45ac8a44312c6b29601f30d4162809b3945821",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/.git",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "c3c3193400f2b187b0088935e84666b345513e74ace518ffc3e2a34bc939d759",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/LICENSE",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "18ac8c568f83a3420a1464ac6bb781fdf8af36a4028cbc2646a7cc517c6250ed",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/meta",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/k8s_manifests/meta/main.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "ed967f1680dc478e8343cd7042920c738f89fa6be4d6e3b8d59422232945d6fe",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/.yamllint",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "46f7d2d60930cbc676554897e84a5a721eee195add39a821aa7f5ab9601369ee",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/tasks",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/tasks/kubelet-setup.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "45fd7d2a5c6a6798cb2423dab4616bd4c76e4e99d84f772bad629665f859cfc8",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/tasks/setup-RedHat.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "84cc021fcdda8aa7b6d1dab88da4914f1428383d3b7847eb42e9a64dea671589",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/tasks/setup-Debian.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "6610b5d244d40c0c637e2cfdf310eb10f24975f8fc83d47975e9535e3b020a11",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/tasks/main.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "5d2790d1ba2c6c8b777297c44899113e10104c3e127ab0cf9f2b2f6f2ccf3040",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/tasks/node-setup.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "e500e50dae7e909002c5e8f8570272057b544bedd18c22cf2e31c4513141ae75",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/tasks/master-setup.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "7b653639e38efa1fd0922869506bf593ba4be3b708070d1081c8252c5735dcb6",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/.github",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/.github/stale.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "7cc3fcc887d4929ca0421ca13bbb31d03b2c502e41a913d18158bffbee9f7bee",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/.github/FUNDING.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "79668fbcce7748a95cecebf6f35cfc297d5ffb733aff93c4d82164ee8e967504",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/handlers",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/handlers/main.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "d521381661812b6a286567ec3f1907072c41c040ccdfb02fe2bec7110ad36d44",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/molecule",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/molecule/default",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/molecule/default/playbook-calico.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "c7a8a2a38beab1dad60d2cc49c884484fb0c9e8c6ce2c4cf5c3bb25fca009527",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/molecule/default/converge.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "455e49ba404360e9fdcd2cfdf02d7e0046010d094f639e4ec8f95afc13e062d5",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/molecule/default/molecule.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "e0b7388d112efaf8834c3b3e6bd93ec61dbcd690efccfa271e829f2b21d628a8",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/molecule/default/requirements.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "cd060eef08692731d163e15650ee3188c238bfb4362f526d58a92c3767f1b311",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/README.md",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "bf0bbf49d913ba83accc379d54e060edb2cf688831538ce22a8324bcb9e044e0",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/templates",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/templates/apt-preferences-kubernetes.j2",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "df32074640b46025477657d3321e2d8e3054cfbe1db2c95d282dbc959f6bb130",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/.gitignore",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "515a0e077dd4e6f58a53b676d5f30c91321197f1f8de671d5ef74760abcbd1a3",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/defaults",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/defaults/main.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "6d3a3e5393eb66a7b5467ec6a8ea819e4aa72b8218bbe9d7bb7a5f6c9ba23bf0",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/.travis.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "4c5c9f8166ac0baf468c006c9c281ed58b43e74f649d1284f57353f8bb85ee49",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/vars",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/vars/Debian.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "bcd0e265e5a81a86b358a725f121026081dbe975b0765acafeb4c824e1e2e574",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/vars/RedHat.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "1a99231a3d393ab1f4d96375a3e98f249cd30f45f0866db035234c027b3e6526",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/.git",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "bc1bdb45dc76cb8f8f5ed1ee114b1ab221948a2de2877cf9147d282854863b03",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/LICENSE",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "18ac8c568f83a3420a1464ac6bb781fdf8af36a4028cbc2646a7cc517c6250ed",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/.ansible-lint",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "6f10e1d56628fc16fef6b0d982050aa86be30ef8daa64db76d1328ced3526b11",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/meta",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/kubernetes/meta/main.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "09bbd4f8d280c8dc3d3141ea6e1d93a2182e35d4c91d95904345d965e6ac8b06",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/.yamllint",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "35f4560713b00048070a781811c50a7d3c207dada2dc98e44e182ee550517f9f",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/tasks",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/tasks/main.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "af9fbaba952b120c6e2f1d7973252aeb8fd4a07da1b30ae90d69c8c2a76241da",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/.github",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/.github/stale.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "7cc3fcc887d4929ca0421ca13bbb31d03b2c502e41a913d18158bffbee9f7bee",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/.github/FUNDING.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "79668fbcce7748a95cecebf6f35cfc297d5ffb733aff93c4d82164ee8e967504",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/molecule",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/molecule/default",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/molecule/default/converge.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "2075e9724a3afa9bf029941876c9aaedb378e4b36d14adde90071da8e4e7f0c7",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/molecule/default/molecule.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "505b9f83556e6a40ceb9255cc041e7232da5f3ff5ed421a7826c4780f180c6a5",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/molecule/default/verify.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "7dcca61dd24e4a806c423aa110efd47db2470c0a28f25e585ef6687307563c44",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/README.md",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "59d20a88e78f80749c4913b3e5a34b7cc4e8422dbfec2b6c4b59610a3849dec9",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/.gitignore",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "515a0e077dd4e6f58a53b676d5f30c91321197f1f8de671d5ef74760abcbd1a3",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/defaults",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/defaults/main.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "5ddea14d078f069c2964277b198ca65d072f178f99387c8f2f92b2b63bff75f0",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/.travis.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "781012541239ba0ffb019ac2fbf36b9cc694f4bb7aa738091e0d34148be7bc99",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/.git",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "a6c7e74772634b52664bf576ad99af7a428b86208340038c59fc684dd9cfe53d",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/LICENSE",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "7fd504840df9d5e3e34c2e2b2c6c471df010ae723bb2527b6cbe40dd3b2dfdfd",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/meta",
|
||||
"ftype": "dir",
|
||||
"chksum_type": null,
|
||||
"chksum_sha256": null,
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": "roles/helm/meta/main.yml",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "7061885e5eafc225f6bccea3093ac8929137999ee8aa5d5be4cbc8415fa6bf77",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": ".ansible-lint",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "46531e6d2938566e8295b7fdc2cb610e286d0ec7a6eed795ea6d815b95e23bdf",
|
||||
"format": 1
|
||||
},
|
||||
{
|
||||
"name": ".gitmodules",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "06c5d51f914f1cd344001cea0071a8a8c3e3fe7cf0a5239d7333d5db944eec7c",
|
||||
"format": 1
|
||||
}
|
||||
],
|
||||
"format": 1
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"collection_info": {
|
||||
"namespace": "geerlingguy",
|
||||
"name": "k8s",
|
||||
"version": "0.10.0",
|
||||
"authors": [
|
||||
"geerlingguy (https://www.jeffgeerling.com/)"
|
||||
],
|
||||
"readme": "README.md",
|
||||
"tags": [
|
||||
"kubernetes",
|
||||
"k8s",
|
||||
"infrastructure",
|
||||
"cloud",
|
||||
"containers",
|
||||
"eks",
|
||||
"aks",
|
||||
"gke",
|
||||
"digitalocean",
|
||||
"docker",
|
||||
"debian",
|
||||
"redhat",
|
||||
"ubuntu",
|
||||
"amazon",
|
||||
"linux",
|
||||
"native"
|
||||
],
|
||||
"description": "An elegant collection of Kuberenetes automation tools.",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"license_file": null,
|
||||
"dependencies": {},
|
||||
"repository": "https://github.com/geerlingguy/ansible-collection-k8s",
|
||||
"documentation": "https://github.com/geerlingguy/ansible-collection-k8s",
|
||||
"homepage": null,
|
||||
"issues": "https://github.com/geerlingguy/ansible-collection-k8s/issues"
|
||||
},
|
||||
"file_manifest_file": {
|
||||
"name": "FILES.json",
|
||||
"ftype": "file",
|
||||
"chksum_type": "sha256",
|
||||
"chksum_sha256": "a58316b86ac6df72143ed495141cc7bbe5d3cb61df99b08effe87bed366ef9df",
|
||||
"format": 1
|
||||
},
|
||||
"format": 1
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
# Kubernetes Collection for Ansible
|
||||
|
||||
[](https://travis-ci.com/geerlingguy/ansible-collection-k8s)
|
||||
|
||||
This collection contains Kubernetes-related roles and Ansible plugins and modules maintained by Jeff Geerling (geerlingguy).
|
||||
|
||||
It includes:
|
||||
|
||||
- [geerlingguy.kubernetes](https://github.com/geerlingguy/ansible-role-kubernetes)
|
||||
- [geerlingguy.k8s_manifests](https://github.com/geerlingguy/ansible-role-k8s_manifests)
|
||||
- [geerlingguy.helm](https://github.com/geerlingguy/ansible-role-helm)
|
||||
|
||||
## Usage
|
||||
|
||||
Install this collection locally:
|
||||
|
||||
ansible-galaxy collection install geerlingguy.k8s -p ./collections
|
||||
|
||||
Then you can use the roles from the collection in your playbooks:
|
||||
|
||||
---
|
||||
- hosts: all
|
||||
|
||||
collections:
|
||||
- geerlingguy.k8s
|
||||
|
||||
roles:
|
||||
- kubernetes
|
||||
- helm
|
||||
- role: k8s_manifests
|
||||
vars:
|
||||
k8s_manifests_base_dir: ''
|
||||
k8s_manifests:
|
||||
- monitoring/prometheus
|
||||
- dir: docker-registry
|
||||
namespace: registry
|
||||
|
||||
> If you want to be more explicit, you can use the fully-qualified role name when referring to a role in this collection, like `geerlingguy.k8s.kubernetes` instead of just `kubernetes`. This could be helpful if, for example, you maintain a separate `kubernetes` role in another place on your local workstation.
|
||||
|
||||
## Development
|
||||
|
||||
Currently, all the Kubernetes roles (inside `roles/`) are Git submodules, and work on the roles themselves should take place in the upstream Role repository. At some point, the roles might move into this repository for their canonical home.
|
||||
|
||||
This collection has some integration tests (inside `molecule/`), however, which pull all the roles together and ensure they work in tandem on the latest supported platforms.
|
||||
|
||||
To run a particular test scenario, you need to install molecule and the OpenShift Python client (`pip install molecule openshift`), then you can run:
|
||||
|
||||
molecule test -s [scenario]
|
||||
|
||||
For example, to run the k8s_manifests role test scenario:
|
||||
|
||||
molecule test -s test-manifests
|
||||
|
||||
If you would like to develop the collection or leave a scenario running for debugging, use `molecule converge` to run the scenario but not tear down the local test environment.
|
||||
|
||||
### Pushing a new version
|
||||
|
||||
Before tagging a new version, make sure all the git submodules are up to date:
|
||||
|
||||
git submodule update --recursive --remote
|
||||
|
||||
Then commit and push all changes, and make sure all tests are passing.
|
||||
|
||||
Then tag the new version of the collection and push the tag.
|
||||
|
||||
Once pushed, if tests pass, Travis CI will deploy the new collection version using the playbook in `scripts/deploy.yml`. That directory also contains the `galaxy.yml` template that will be used to build the collection metadata.
|
||||
|
||||
## Author
|
||||
|
||||
This collection was created in 2019 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/) and [Ansible for Kubernetes](https://www.ansibleforkubernetes.com).
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Verify
|
||||
hosts: k8s
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
deploy_dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/deploy"
|
||||
custom_resource: "{{ lookup('file', '/'.join([deploy_dir, 'crds/drupal_v1alpha1_drupal_cr.yaml'])) | from_yaml }}"
|
||||
|
||||
tasks:
|
||||
- name: Don't do much here.
|
||||
debug:
|
||||
msg: "Not implemented at this time."
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: localhost
|
||||
connection: local
|
||||
|
||||
vars:
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
|
||||
roles:
|
||||
- helm
|
||||
- k8s_manifests
|
||||
|
||||
- import_playbook: '{{ playbook_dir }}/asserts.yml'
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
---
|
||||
dependency:
|
||||
name: galaxy
|
||||
driver:
|
||||
name: docker
|
||||
lint: |
|
||||
set -e
|
||||
yamllint .
|
||||
ansible-lint
|
||||
platforms:
|
||||
- name: kind-default
|
||||
groups:
|
||||
- k8s
|
||||
image: bsycorp/kind:latest-1.15
|
||||
privileged: True
|
||||
override_command: no
|
||||
exposed_ports:
|
||||
- 8443/tcp
|
||||
- 10080/tcp
|
||||
published_ports:
|
||||
- 0.0.0.0:${TEST_CLUSTER_PORT:-9443}:8443/tcp
|
||||
pre_build_image: yes
|
||||
provisioner:
|
||||
name: ansible
|
||||
log: True
|
||||
inventory:
|
||||
group_vars:
|
||||
all:
|
||||
test_namespace: ${TEST_NAMESPACE:-default}
|
||||
env:
|
||||
K8S_AUTH_KUBECONFIG: /tmp/molecule/kind-default/kubeconfig
|
||||
KUBECONFIG: /tmp/molecule/kind-default/kubeconfig
|
||||
ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/roles
|
||||
KIND_PORT: '${TEST_CLUSTER_PORT:-9443}'
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
- name: Prepare
|
||||
hosts: k8s
|
||||
gather_facts: no
|
||||
|
||||
vars:
|
||||
kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}"
|
||||
|
||||
tasks:
|
||||
- name: delete the kubeconfig if present
|
||||
file:
|
||||
path: '{{ kubeconfig }}'
|
||||
state: absent
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Fetch the kubeconfig
|
||||
fetch:
|
||||
dest: '{{ kubeconfig }}'
|
||||
flat: yes
|
||||
src: /root/.kube/config
|
||||
|
||||
- name: Change the kubeconfig port to the proper value
|
||||
replace:
|
||||
regexp: "8443"
|
||||
replace: "{{ lookup('env', 'KIND_PORT') }}"
|
||||
path: '{{ kubeconfig }}'
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Wait for the Kubernetes API to become available (this could take a minute)
|
||||
uri:
|
||||
url: "http://localhost:10080/kubernetes-ready"
|
||||
status_code: 200
|
||||
validate_certs: no
|
||||
register: result
|
||||
until: (result.status|default(-1)) == 200
|
||||
retries: 60
|
||||
delay: 5
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
---
|
||||
- name: Verify
|
||||
hosts: k8s
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
deploy_dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/deploy"
|
||||
custom_resource: "{{ lookup('file', '/'.join([deploy_dir, 'crds/drupal_v1alpha1_drupal_cr.yaml'])) | from_yaml }}"
|
||||
|
||||
tasks:
|
||||
- name: Get all StorageClass objects.
|
||||
k8s_info:
|
||||
api_version: v1
|
||||
kind: StorageClass
|
||||
namespace: '{{ default_namespace }}'
|
||||
register: storageclass
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Verify the custom EBS StorageClass is present.
|
||||
assert:
|
||||
that: "{{ 'kubernetes.io/aws-ebs' in storageclass | to_nice_json }}"
|
||||
|
||||
- name: Get all namespaces.
|
||||
k8s_info:
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
register: all_namespaces
|
||||
delegate_to: localhost
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: localhost
|
||||
connection: local
|
||||
|
||||
collections:
|
||||
- geerlingguy.k8s
|
||||
|
||||
vars:
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
k8s_manifests_base_dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/roles/k8s_manifests/k8s-manifests/"
|
||||
k8s_kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}"
|
||||
k8s_no_log: false
|
||||
|
||||
tasks:
|
||||
- name: Test k8s_manifests role.
|
||||
import_role:
|
||||
name: k8s_manifests
|
||||
vars:
|
||||
k8s_manage_namespace: false
|
||||
k8s_manifests:
|
||||
- dir: storageclass
|
||||
namespace: default
|
||||
|
||||
- import_playbook: '{{ playbook_dir }}/asserts.yml'
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
dependency:
|
||||
name: galaxy
|
||||
driver:
|
||||
name: docker
|
||||
lint: |
|
||||
set -e
|
||||
yamllint .
|
||||
ansible-lint
|
||||
platforms:
|
||||
- name: kind-test-local
|
||||
groups:
|
||||
- k8s
|
||||
image: bsycorp/kind:latest-1.15
|
||||
privileged: True
|
||||
override_command: no
|
||||
exposed_ports:
|
||||
- 8443/tcp
|
||||
- 10080/tcp
|
||||
published_ports:
|
||||
- 0.0.0.0:${TEST_CLUSTER_PORT:-10443}:8443/tcp
|
||||
pre_build_image: yes
|
||||
volumes:
|
||||
- ${MOLECULE_PROJECT_DIRECTORY}:/build:Z
|
||||
provisioner:
|
||||
name: ansible
|
||||
log: True
|
||||
inventory:
|
||||
group_vars:
|
||||
all:
|
||||
default_namespace: ${TEST_NAMESPACE:-default}
|
||||
env:
|
||||
K8S_AUTH_KUBECONFIG: /tmp/molecule/kind-test-local/kubeconfig
|
||||
KUBECONFIG: /tmp/molecule/kind-test-local/kubeconfig
|
||||
ANSIBLE_ROLES_PATH: ${MOLECULE_PROJECT_DIRECTORY}/roles
|
||||
ANSIBLE_COLLECTIONS_PATHS: "/home/travis/build/geerlingguy:~/.ansible/collections"
|
||||
KIND_PORT: '${TEST_CLUSTER_PORT:-10443}'
|
||||
scenario:
|
||||
test_sequence:
|
||||
- lint
|
||||
- destroy
|
||||
- dependency
|
||||
- syntax
|
||||
- create
|
||||
- prepare
|
||||
- converge
|
||||
- side_effect
|
||||
- verify
|
||||
- destroy
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
---
|
||||
- import_playbook: ../default/prepare.yml
|
||||
|
||||
- name: Prepare operator resources
|
||||
hosts: localhost
|
||||
connection: local
|
||||
|
||||
vars:
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
deploy_dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/deploy"
|
||||
|
||||
tasks:
|
||||
- name: Ensure default namespace is present
|
||||
k8s:
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: '{{ default_namespace }}'
|
||||
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2020 Jeff Geerling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,41 @@
|
||||
# Ansible Role: Helm
|
||||
|
||||
[](https://travis-ci.com/geerlingguy/ansible-role-helm)
|
||||
|
||||
This role installs the [Helm](https://helm.sh) binary on any supported host.
|
||||
|
||||
## Requirements
|
||||
|
||||
N/A
|
||||
|
||||
## Role Variables
|
||||
|
||||
Available variables are listed below, along with default values (see `defaults/main.yml`):
|
||||
|
||||
helm_version: 'v3.2.1'
|
||||
helm_platform: linux
|
||||
helm_arch: amd64
|
||||
|
||||
Controls for the version of Helm to be installed. See [available Helm releases](https://github.com/helm/helm/releases/). You can upgrade or downgrade versions by changing the `helm_version`.
|
||||
|
||||
helm_bin_path: /usr/local/bin/helm
|
||||
|
||||
The location where the Helm binary will be installed.
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Example Playbook
|
||||
|
||||
- hosts: all
|
||||
roles:
|
||||
- role: geerlingguy.helm
|
||||
|
||||
## License
|
||||
|
||||
MIT / BSD
|
||||
|
||||
## Author Information
|
||||
|
||||
This role was created in 2020 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/).
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
# See available releases: https://github.com/helm/helm/releases/
|
||||
helm_version: 'v3.2.1'
|
||||
helm_platform: linux
|
||||
helm_arch: amd64
|
||||
|
||||
helm_bin_path: /usr/local/bin/helm
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
dependencies: []
|
||||
galaxy_info:
|
||||
author: Jeff Geerling
|
||||
role_name: helm
|
||||
description: Helm for Kubernetes.
|
||||
company: Midwestern Mac, LLC
|
||||
license: license (MIT)
|
||||
min_ansible_version: 2.7
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- all
|
||||
- name: GenericUNIX
|
||||
versions:
|
||||
- all
|
||||
- name: Fedora
|
||||
versions:
|
||||
- all
|
||||
- name: opensuse
|
||||
versions:
|
||||
- all
|
||||
- name: GenericBSD
|
||||
versions:
|
||||
- all
|
||||
- name: FreeBSD
|
||||
versions:
|
||||
- all
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- all
|
||||
- name: SLES
|
||||
versions:
|
||||
- all
|
||||
- name: GenericLinux
|
||||
versions:
|
||||
- all
|
||||
- name: Debian
|
||||
versions:
|
||||
- all
|
||||
galaxy_tags:
|
||||
- kubernetes
|
||||
- k8s
|
||||
- cloud
|
||||
- containers
|
||||
- helm
|
||||
- deployment
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
become: true
|
||||
|
||||
pre_tasks:
|
||||
- name: Update apt cache.
|
||||
apt: update_cache=yes cache_valid_time=600
|
||||
when: ansible_os_family == 'Debian'
|
||||
changed_when: false
|
||||
|
||||
roles:
|
||||
- role: geerlingguy.helm
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
---
|
||||
dependency:
|
||||
name: galaxy
|
||||
driver:
|
||||
name: docker
|
||||
lint: |
|
||||
set -e
|
||||
yamllint .
|
||||
ansible-lint
|
||||
platforms:
|
||||
- name: instance
|
||||
image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos8}-ansible:latest"
|
||||
command: ${MOLECULE_DOCKER_COMMAND:-""}
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
privileged: true
|
||||
pre_build_image: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
converge: ${MOLECULE_PLAYBOOK:-converge.yml}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
---
|
||||
- name: Verify
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
|
||||
vars_files:
|
||||
- ../../defaults/main.yml
|
||||
|
||||
tasks:
|
||||
- name: Check Helm version.
|
||||
command: "{{ helm_bin_path }} version"
|
||||
changed_when: false
|
||||
register: helm_verify_version
|
||||
|
||||
- name: Verify Helm's version is {{ helm_version }}.
|
||||
assert:
|
||||
that:
|
||||
- helm_version in helm_verify_version.stdout
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
- name: Check if Helm binary exists.
|
||||
stat:
|
||||
path: "{{ helm_bin_path }}"
|
||||
register: helm_check
|
||||
|
||||
- name: Check Helm version.
|
||||
command: "{{ helm_bin_path }} version"
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
register: helm_existing_version
|
||||
|
||||
- name: Download helm.
|
||||
unarchive:
|
||||
src: https://get.helm.sh/helm-{{ helm_version }}-{{ helm_platform }}-{{ helm_arch }}.tar.gz
|
||||
dest: /tmp
|
||||
remote_src: true
|
||||
register: helm_download
|
||||
when: >
|
||||
not helm_check.stat.exists
|
||||
or helm_version not in helm_existing_version.stdout
|
||||
|
||||
- name: Copy helm binary into place.
|
||||
copy:
|
||||
src: "/tmp/{{ helm_platform }}-{{ helm_arch }}/helm"
|
||||
dest: "{{ helm_bin_path }}"
|
||||
mode: 0755
|
||||
remote_src: true
|
||||
become: true
|
||||
when: helm_download is changed
|
||||
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Jeff Geerling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
# Ansible Role: K8s Manifests
|
||||
|
||||
[](https://travis-ci.org/geerlingguy/ansible-role-k8s_manifests)
|
||||
|
||||
An Ansible Role that applies Kubernetes manifests (either templated, or directly) to Kubernetes clusters.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Pip package: `openshift`
|
||||
- If running on localhost (e.g. with `connection: local`), you may need to set `ansible_python_interpreter: "{{ ansible_playbook_python }}"` for the role to work correctly.
|
||||
|
||||
## Role Variables
|
||||
|
||||
Available variables are listed below, along with default values (see `defaults/main.yml`):
|
||||
|
||||
k8s_manifests:
|
||||
# Can be a path inside the `k8s_manifests_base_dir`.
|
||||
- monitoring/prometheus
|
||||
|
||||
# Use a `file` lookup if you don't want to template the manifest file.
|
||||
- dir: monitoring/grafana-configmap
|
||||
lookup_type: 'file'
|
||||
|
||||
# You can set a namespace per manifest (templated to `manifest_namespace`).
|
||||
- dir: docker-registry
|
||||
namespace: registry
|
||||
|
||||
A list of Kubernetes manifest directories to apply to a Kubernetes cluster. This list can either be raw directory paths or folder names, or can be a dict with `dir` (the directory path/folder name), optional `lookup_type` (the Ansible lookup type used for the `manifest.yml` file), and optional `namespace` (templated to `manifest_namespace`).
|
||||
|
||||
This role then looks inside the specified directory for each manifest, and applies a `manifest.yml` file (and all it's contents) using the Ansible `k8s` module.
|
||||
|
||||
If you need to template the file, this role templates the `manifest.yml` file by default (and automatically adds any variables in a `vars.yml` file alongside the `manifest.yml` file). But you can also disable templating and have the manifest applied directly by setting `lookup_type: file`.
|
||||
|
||||
k8s_manifests_base_dir: '' # include trailing /, e.g. 'base_dir/'
|
||||
|
||||
If set, this string will be prepended to each manifest `dir`/path specified in `k8s_manifests`. This is useful if you store all your Kubernetes manifests in a directory outside the Ansible playbook directory, so you don't have to include the full path in each defined `k8s_manifests` list item.
|
||||
|
||||
k8s_manifests_state: present
|
||||
|
||||
Whether the `state` for the `k8s` module should be `present` or `absent`. Note that using `absent` doesn't _always_ delete all Kubernetes resources defined in a manifest.
|
||||
|
||||
k8s_force: false
|
||||
|
||||
If set to `true`, and `k8s_manifests_state` is set to `present`, an existing object will be replaced. Otherwise the default behavior for Ansible's `k8s` module and Kubernetes itself (e.g. if using `apply`) is to _patch_ the resource.
|
||||
|
||||
k8s_kubeconfig: ~/.kube/config
|
||||
|
||||
The path to the `kubeconfig` file to use to connect to the Kubernetes cluster.
|
||||
|
||||
k8s_resource_namespace: ''
|
||||
k8s_manage_namespace: true
|
||||
|
||||
By default, this role assumes you will be deploying resources into a particular namespace. So if you set `k8s_resource_namespace` to the namespace you are operating on, the role will ensure that namespace exists before applying any manifests. You can disable this role's namespace management (e.g. if the manifest you're applying should not be namespaced, or if you are applying namespaces per-manifest) by setting `k8s_manage_namespace: false`.
|
||||
|
||||
k8s_no_log: true
|
||||
|
||||
Whether to log the details of each manifest's application to the cluster in the Ansible output. Secrets and other sensitive data could be part of a manifest, so this is set to be secure by default. Set to `false` for debugging purposes.
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Example Playbooks
|
||||
|
||||
### Simple example - running on localhost
|
||||
|
||||
---
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
gather_facts: no
|
||||
|
||||
vars:
|
||||
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
||||
k8s_kubeconfig: ~/.kube/config-my-cluster
|
||||
k8s_manifests_base_dir: k8s-manifests/
|
||||
k8s_manifests:
|
||||
- storageclass
|
||||
|
||||
roles:
|
||||
- role: geerlingguy.k8s_manifests
|
||||
|
||||
See the `k8s-manifests` directory and it's README for an example templated manifest layout with a vars file defined alongside it.
|
||||
|
||||
### Running as part of a larger play
|
||||
|
||||
---
|
||||
- hosts: k8s_cluster
|
||||
become: true
|
||||
|
||||
vars:
|
||||
ansible_python_interpreter: python
|
||||
k8s_manage_namespace: false
|
||||
k8s_no_log: false
|
||||
k8s_manifests_base_dir: k8s-manifests/
|
||||
k8s_manifests:
|
||||
- storageclass
|
||||
- dir: docker-registry
|
||||
namespace: registry
|
||||
|
||||
tasks:
|
||||
- name: Set the python interpreter appropriately.
|
||||
set_fact:
|
||||
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
||||
|
||||
- import_role:
|
||||
name: geerlingguy.k8s_manifests
|
||||
tags: ['kubernetes', 'nfs', 'drupal', 'registry']
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
|
||||
## License
|
||||
|
||||
MIT / BSD
|
||||
|
||||
## Author Information
|
||||
|
||||
This role was created in 2018 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/).
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
---
|
||||
k8s_manifests: []
|
||||
# - monitoring/prometheus
|
||||
# - dir: monitoring/grafana-configmap
|
||||
# lookup_type: 'file'
|
||||
k8s_manifests_base_dir: ''
|
||||
k8s_manifests_state: present
|
||||
k8s_force: false
|
||||
|
||||
k8s_kubeconfig: ~/.kube/config
|
||||
|
||||
k8s_resource_namespace: ''
|
||||
k8s_manage_namespace: true
|
||||
k8s_no_log: true
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# K8s Manifest Example Directory
|
||||
|
||||
The 'storageclass' example in this directory illustrates the structure of Kubernetes manifest files as consumed by the `geerlingguy.k8s_manifests` role.
|
||||
|
||||
To apply the `storageclass` manifest, you would call this role with the variable:
|
||||
|
||||
k8s_manifests:
|
||||
- k8s-manifests/storageclass
|
||||
|
||||
When the role runs, it will template the `manifest.yml` file inside the manifest directory, and apply any variables defined in an optional `vars.yml` file alongside the manifest (along with any other variables the Ansible playbook has already loaded, e.g. from inventory or dynamically).
|
||||
|
||||
You can also apply a manifest directly, with no templating, using:
|
||||
|
||||
k8s_manifests:
|
||||
- dir: k8s-manifests/storageclass
|
||||
lookup_type: file
|
||||
|
||||
This can be useful for raw manifests which do not need any templating, or manifest files which contain Jinja-like syntax which is hard to escape properly.
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
---
|
||||
kind: StorageClass
|
||||
apiVersion: storage.k8s.io/v1
|
||||
metadata:
|
||||
name: "{{ storageclass_name }}"
|
||||
annotations:
|
||||
storageclass.beta.kubernetes.io/is-default-class: "true"
|
||||
provisioner: kubernetes.io/aws-ebs
|
||||
parameters:
|
||||
type: gp2
|
||||
reclaimPolicy: Delete
|
||||
mountOptions:
|
||||
- debug
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
---
|
||||
storageclass_name: gp2
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
---
|
||||
dependencies: []
|
||||
|
||||
galaxy_info:
|
||||
author: geerlingguy
|
||||
role_name: k8s_manifests
|
||||
description: Kubernetes manifest management role.
|
||||
company: "Midwestern Mac, LLC"
|
||||
license: "license (BSD, MIT)"
|
||||
min_ansible_version: 2.7
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- all
|
||||
- name: Fedora
|
||||
versions:
|
||||
- all
|
||||
- name: Debian
|
||||
versions:
|
||||
- all
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- all
|
||||
- name: GenericUNIX
|
||||
versions:
|
||||
- all
|
||||
galaxy_tags:
|
||||
- k8s
|
||||
- kubernetes
|
||||
- infrastructure
|
||||
- eks
|
||||
- aks
|
||||
- gks
|
||||
- minikube
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
become: true
|
||||
|
||||
roles:
|
||||
- role: geerlingguy.k8s_manifests
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
---
|
||||
dependency:
|
||||
name: galaxy
|
||||
driver:
|
||||
name: docker
|
||||
lint: |
|
||||
set -e
|
||||
yamllint .
|
||||
ansible-lint
|
||||
platforms:
|
||||
- name: instance
|
||||
image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest"
|
||||
command: ${MOLECULE_DOCKER_COMMAND:-""}
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
privileged: true
|
||||
pre_build_image: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
converge: ${MOLECULE_PLAYBOOK:-converge.yml}
|
||||
scenario:
|
||||
test_sequence:
|
||||
- lint
|
||||
- syntax
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
---
|
||||
- name: Set variables for this iteration of the loop.
|
||||
set_fact:
|
||||
manifest_directory: "{{ k8s_manifests_base_dir }}{{ outer_item.dir | default(outer_item) }}"
|
||||
manifest_lookup_type: "{{ outer_item.lookup_type | default('template') }}"
|
||||
manifest_namespace: "{{ outer_item.namespace | default('') }}"
|
||||
|
||||
- name: Print current manifest directory.
|
||||
debug: var=manifest_directory
|
||||
|
||||
- name: Ensure manifest-specific namespace exists.
|
||||
k8s:
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: "{{ manifest_namespace }}"
|
||||
state: present
|
||||
kubeconfig: "{{ k8s_kubeconfig }}"
|
||||
when: manifest_namespace | default(false)
|
||||
|
||||
- name: Include vars specific to this manifest.
|
||||
include_vars: "{{ item }}"
|
||||
with_first_found:
|
||||
- files:
|
||||
- "{{ manifest_directory }}/vars.yml"
|
||||
skip: true
|
||||
|
||||
- name: Deploy the resources defined inside the manifest.
|
||||
k8s:
|
||||
definition: "{{ item }}"
|
||||
kubeconfig: "{{ k8s_kubeconfig }}"
|
||||
state: "{{ k8s_manifests_state }}"
|
||||
force: "{{ k8s_force }}"
|
||||
loop: "{{ lookup(manifest_lookup_type, manifest_directory + '/manifest.yml') | from_yaml_all | list }}"
|
||||
register: k8s_result
|
||||
until: k8s_result is success
|
||||
retries: 10
|
||||
delay: 2
|
||||
no_log: "{{ k8s_no_log }}"
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
---
|
||||
- name: Ensure at least one manifest is in the list.
|
||||
fail:
|
||||
msg: "Please supply one or more k8s_manifests to apply."
|
||||
when: k8s_manifests == []
|
||||
|
||||
- name: Ensure a namespace is set.
|
||||
fail:
|
||||
msg: "The k8s_resource_namespace variable is not set."
|
||||
when:
|
||||
- k8s_manage_namespace
|
||||
- k8s_resource_namespace | default(true)
|
||||
|
||||
- name: Ensure namespace exists.
|
||||
k8s:
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: "{{ k8s_resource_namespace }}"
|
||||
state: present
|
||||
kubeconfig: "{{ k8s_kubeconfig }}"
|
||||
when: k8s_manage_namespace
|
||||
|
||||
- name: Deploy manifests defined in k8s_manifests.
|
||||
include_tasks: deploy-manifest.yml
|
||||
loop: "{{ k8s_manifests }}"
|
||||
loop_control:
|
||||
loop_var: outer_item
|
||||
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Jeff Geerling
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,148 @@
|
||||
# Ansible Role: Kubernetes
|
||||
|
||||
[](https://travis-ci.org/geerlingguy/ansible-role-kubernetes)
|
||||
|
||||
An Ansible Role that installs [Kubernetes](https://kubernetes.io) on Linux.
|
||||
|
||||
## Requirements
|
||||
|
||||
Requires Docker; recommended role for Docker installation: `geerlingguy.docker`.
|
||||
|
||||
## Role Variables
|
||||
|
||||
Available variables are listed below, along with default values (see `defaults/main.yml`):
|
||||
|
||||
kubernetes_packages:
|
||||
- name: kubelet
|
||||
state: present
|
||||
- name: kubectl
|
||||
state: present
|
||||
- name: kubeadm
|
||||
state: present
|
||||
- name: kubernetes-cni
|
||||
state: present
|
||||
|
||||
Kubernetes packages to be installed on the server. You can either provide a list of package names, or set `name` and `state` to have more control over whether the package is `present`, `absent`, `latest`, etc.
|
||||
|
||||
kubernetes_version: '1.17'
|
||||
kubernetes_version_rhel_package: '1.17.2'
|
||||
|
||||
The minor version of Kubernetes to install. The plain `kubernetes_version` is used to pin an apt package version on Debian, and as the Kubernetes version passed into the `kubeadm init` command (see `kubernetes_version_kubeadm`). The `kubernetes_version_rhel_package` variable must be a specific Kubernetes release, and is used to pin the version on Red Hat / CentOS servers.
|
||||
|
||||
kubernetes_role: master
|
||||
|
||||
Whether the particular server will serve as a Kubernetes `master` (default) or `node`. The master will have `kubeadm init` run on it to intialize the entire K8s control plane, while `node`s will have `kubeadm join` run on them to join them to the `master`.
|
||||
|
||||
kubernetes_kubelet_extra_args: ""
|
||||
kubernetes_kubelet_extra_args_config_file: /etc/default/kubelet
|
||||
|
||||
Extra args to pass to `kubelet` during startup. E.g. to allow `kubelet` to start up even if there is swap is enabled on your server, set this to: `"--fail-swap-on=false"`. Or to specify the node-ip advertised by `kubelet`, set this to `"--node-ip={{ ansible_host }}"`.
|
||||
|
||||
kubernetes_kubeadm_init_extra_opts: ""
|
||||
|
||||
Extra args to pass to `kubeadm init` during K8s control plane initialization. E.g. to specify extra Subject Alternative Names for API server certificate, set this to: `"--apiserver-cert-extra-sans my-custom.host"`
|
||||
|
||||
kubernetes_join_command_extra_opts: ""
|
||||
|
||||
Extra args to pass to the generated `kubeadm join` command during K8s node initialization. E.g. to ignore certain preflight errors like swap being enabled, set this to: `--ignore-preflight-errors=Swap`
|
||||
|
||||
kubernetes_allow_pods_on_master: true
|
||||
|
||||
Whether to remove the taint that denies pods from being deployed to the Kubernetes master. If you have a single-node cluster, this should definitely be `True`. Otherwise, set to `False` if you want a dedicated Kubernetes master which doesn't run any other pods.
|
||||
|
||||
kubernetes_enable_web_ui: false
|
||||
kubernetes_web_ui_manifest_file: https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
|
||||
|
||||
Whether to enable the Kubernetes web dashboard UI (only accessible on the master itself, or proxied), and the file containing the web dashboard UI manifest.
|
||||
|
||||
kubernetes_pod_network:
|
||||
# Flannel CNI.
|
||||
cni: 'flannel'
|
||||
cidr: '10.244.0.0/16'
|
||||
#
|
||||
# Calico CNI.
|
||||
# cni: 'calico'
|
||||
# cidr: '192.168.0.0/16'
|
||||
#
|
||||
# Weave CNI.
|
||||
# cni: 'weave'
|
||||
# cidr: '192.168.0.0/16'
|
||||
|
||||
This role currently supports `flannel` (default), `calico` or `weave` for cluster pod networking. Choose only one for your cluster; converting between them is not done automatically and could result in broken networking; if you need to switch from one to another, it should be done outside of this role.
|
||||
|
||||
kubernetes_apiserver_advertise_address: ''
|
||||
kubernetes_version_kubeadm: 'stable-{{ kubernetes_version }}'
|
||||
kubernetes_ignore_preflight_errors: 'all'
|
||||
|
||||
Options passed to `kubeadm init` when initializing the Kubernetes master. The `kubernetes_apiserver_advertise_address` defaults to `ansible_default_ipv4.address` if it's left empty.
|
||||
|
||||
kubernetes_apt_release_channel: main
|
||||
kubernetes_apt_repository: "deb http://apt.kubernetes.io/ kubernetes-xenial {{ kubernetes_apt_release_channel }}"
|
||||
kubernetes_apt_ignore_key_error: false
|
||||
|
||||
Apt repository options for Kubernetes installation.
|
||||
|
||||
kubernetes_yum_arch: x86_64
|
||||
|
||||
Yum repository options for Kubernetes installation.
|
||||
|
||||
kubernetes_flannel_manifest_file_rbac: https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml
|
||||
kubernetes_flannel_manifest_file: https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
|
||||
|
||||
Flannel manifest files to apply to the Kubernetes cluster to enable networking. You can copy your own files to your server and apply them instead, if you need to customize the Flannel networking configuration.
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Example Playbooks
|
||||
|
||||
### Single node (master-only) cluster
|
||||
|
||||
```yaml
|
||||
- hosts: all
|
||||
|
||||
vars:
|
||||
kubernetes_allow_pods_on_master: true
|
||||
|
||||
roles:
|
||||
- geerlingguy.docker
|
||||
- geerlingguy.kubernetes
|
||||
```
|
||||
|
||||
### Two or more nodes (single master) cluster
|
||||
|
||||
Master inventory vars:
|
||||
|
||||
```yaml
|
||||
kubernetes_role: "master"
|
||||
```
|
||||
|
||||
Node(s) inventory vars:
|
||||
|
||||
```yaml
|
||||
kubernetes_role: "node"
|
||||
```
|
||||
|
||||
Playbook:
|
||||
|
||||
```yaml
|
||||
- hosts: all
|
||||
|
||||
vars:
|
||||
kubernetes_allow_pods_on_master: true
|
||||
|
||||
roles:
|
||||
- geerlingguy.docker
|
||||
- geerlingguy.kubernetes
|
||||
```
|
||||
|
||||
Then, log into the Kubernetes master, and run `kubectl get nodes` as root, and you should see a list of all the servers.
|
||||
|
||||
## License
|
||||
|
||||
MIT / BSD
|
||||
|
||||
## Author Information
|
||||
|
||||
This role was created in 2018 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/).
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
kubernetes_packages:
|
||||
- name: kubelet
|
||||
state: present
|
||||
- name: kubectl
|
||||
state: present
|
||||
- name: kubeadm
|
||||
state: present
|
||||
- name: kubernetes-cni
|
||||
state: present
|
||||
|
||||
kubernetes_version: '1.17'
|
||||
kubernetes_version_rhel_package: '1.17.2'
|
||||
|
||||
kubernetes_role: master
|
||||
|
||||
kubernetes_kubelet_extra_args: ""
|
||||
kubernetes_kubeadm_init_extra_opts: ""
|
||||
kubernetes_join_command_extra_opts: ""
|
||||
|
||||
kubernetes_allow_pods_on_master: true
|
||||
kubernetes_enable_web_ui: true
|
||||
kubernetes_web_ui_manifest_file: https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
|
||||
|
||||
kubernetes_pod_network:
|
||||
# Flannel CNI.
|
||||
cni: 'flannel'
|
||||
cidr: '10.244.0.0/16'
|
||||
# Calico CNI.
|
||||
# cni: 'calico'
|
||||
# cidr: '192.168.0.0/16'
|
||||
|
||||
kubernetes_apiserver_advertise_address: ''
|
||||
kubernetes_version_kubeadm: 'stable-{{ kubernetes_version }}'
|
||||
kubernetes_ignore_preflight_errors: 'all'
|
||||
|
||||
kubernetes_apt_release_channel: main
|
||||
# Note that xenial repo is used for all Debian derivatives at this time.
|
||||
kubernetes_apt_repository: "deb http://apt.kubernetes.io/ kubernetes-xenial {{ kubernetes_apt_release_channel }}"
|
||||
kubernetes_apt_ignore_key_error: false
|
||||
|
||||
kubernetes_yum_arch: x86_64
|
||||
|
||||
# Flannel config files.
|
||||
kubernetes_flannel_manifest_file_rbac: https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml
|
||||
kubernetes_flannel_manifest_file: https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
|
||||
|
||||
# Calico config files
|
||||
kubernetes_calico_manifest_file: https://docs.projectcalico.org/v3.10/manifests/calico.yaml
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
---
|
||||
- name: restart kubelet
|
||||
service: name=kubelet state=restarted
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
---
|
||||
dependencies: []
|
||||
|
||||
galaxy_info:
|
||||
author: geerlingguy
|
||||
description: Kubernetes for Linux.
|
||||
company: "Midwestern Mac, LLC"
|
||||
license: "license (BSD, MIT)"
|
||||
min_ansible_version: 2.4
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 7
|
||||
- 8
|
||||
- name: Debian
|
||||
versions:
|
||||
- stretch
|
||||
- buster
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- xenial
|
||||
- bionic
|
||||
galaxy_tags:
|
||||
- system
|
||||
- containers
|
||||
- docker
|
||||
- rkt
|
||||
- orchestration
|
||||
- kubernetes
|
||||
- k8s
|
||||
- paas
|
||||
- saas
|
||||
- hosting
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
become: true
|
||||
|
||||
vars:
|
||||
# Allow swap in test environments (hard to control in some Docker envs).
|
||||
kubernetes_kubelet_extra_args: "--fail-swap-on=false --cgroup-driver=cgroupfs"
|
||||
docker_install_compose: false
|
||||
|
||||
pre_tasks:
|
||||
- name: Update apt cache.
|
||||
apt: update_cache=true cache_valid_time=600
|
||||
when: ansible_os_family == 'Debian'
|
||||
|
||||
- name: Ensure test dependencies are installed (RedHat).
|
||||
package: name=iproute state=present
|
||||
when: ansible_os_family == 'RedHat'
|
||||
|
||||
- name: Ensure test dependencies are installed (Debian).
|
||||
package: name=iproute2 state=present
|
||||
when: ansible_os_family == 'Debian'
|
||||
|
||||
- name: Gather facts.
|
||||
action: setup
|
||||
|
||||
roles:
|
||||
- role: geerlingguy.docker
|
||||
- role: geerlingguy.kubernetes
|
||||
|
||||
post_tasks:
|
||||
- name: Get cluster info.
|
||||
command: kubectl cluster-info
|
||||
changed_when: false
|
||||
register: kubernetes_info
|
||||
|
||||
- name: Print cluster info.
|
||||
debug: var=kubernetes_info.stdout
|
||||
|
||||
- name: Get all running pods.
|
||||
command: kubectl get pods --all-namespaces
|
||||
changed_when: false
|
||||
register: kubernetes_pods
|
||||
|
||||
- name: Print list of running pods.
|
||||
debug: var=kubernetes_pods.stdout
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
---
|
||||
dependency:
|
||||
name: galaxy
|
||||
driver:
|
||||
name: docker
|
||||
lint: |
|
||||
set -e
|
||||
yamllint .
|
||||
ansible-lint
|
||||
platforms:
|
||||
- name: instance
|
||||
image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest"
|
||||
command: ${MOLECULE_DOCKER_COMMAND:-""}
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
- /var/lib/docker
|
||||
privileged: true
|
||||
pre_build_image: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
converge: ${MOLECULE_PLAYBOOK:-converge.yml}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
become: true
|
||||
|
||||
vars:
|
||||
kubernetes_pod_network:
|
||||
cni: 'calico'
|
||||
cidr: '192.168.0.0/16'
|
||||
|
||||
# Allow swap in test environments (hard to control in some Docker envs).
|
||||
kubernetes_kubelet_extra_args: "--fail-swap-on=false --cgroup-driver=cgroupfs"
|
||||
docker_install_compose: false
|
||||
|
||||
pre_tasks:
|
||||
- name: Update apt cache.
|
||||
apt: update_cache=true cache_valid_time=600
|
||||
when: ansible_os_family == 'Debian'
|
||||
|
||||
- name: Ensure test dependencies are installed (RedHat).
|
||||
package: name=iproute state=present
|
||||
when: ansible_os_family == 'RedHat'
|
||||
|
||||
- name: Ensure test dependencies are installed (Debian).
|
||||
package: name=iproute2 state=present
|
||||
when: ansible_os_family == 'Debian'
|
||||
|
||||
- name: Gather facts.
|
||||
action: setup
|
||||
|
||||
roles:
|
||||
- role: geerlingguy.docker
|
||||
- role: geerlingguy.kubernetes
|
||||
|
||||
post_tasks:
|
||||
- name: Get cluster info.
|
||||
command: kubectl cluster-info
|
||||
changed_when: false
|
||||
register: kubernetes_info
|
||||
|
||||
- name: Print cluster info.
|
||||
debug: var=kubernetes_info.stdout
|
||||
|
||||
- name: Get all running pods.
|
||||
command: kubectl get pods --all-namespaces
|
||||
changed_when: false
|
||||
register: kubernetes_pods
|
||||
|
||||
- name: Print list of running pods.
|
||||
debug: var=kubernetes_pods.stdout
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
---
|
||||
- src: geerlingguy.docker
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
---
|
||||
- name: Check for existence of kubelet environment file.
|
||||
stat:
|
||||
path: '{{ kubelet_environment_file_path }}'
|
||||
register: kubelet_environment_file
|
||||
|
||||
- name: Set facts for KUBELET_EXTRA_ARGS task if environment file exists.
|
||||
set_fact:
|
||||
kubelet_args_path: '{{ kubelet_environment_file_path }}'
|
||||
kubelet_args_line: "{{ 'KUBELET_EXTRA_ARGS=' + kubernetes_kubelet_extra_args }}"
|
||||
kubelet_args_regexp: '^KUBELET_EXTRA_ARGS='
|
||||
when: kubelet_environment_file.stat.exists
|
||||
|
||||
- name: Set facts for KUBELET_EXTRA_ARGS task if environment file doesn't exist.
|
||||
set_fact:
|
||||
kubelet_args_path: '/etc/systemd/system/kubelet.service.d/10-kubeadm.conf'
|
||||
kubelet_args_line: "{{ 'Environment=\"KUBELET_EXTRA_ARGS=' + kubernetes_kubelet_extra_args + '\"' }}"
|
||||
kubelet_args_regexp: '^Environment="KUBELET_EXTRA_ARGS='
|
||||
when: not kubelet_environment_file.stat.exists
|
||||
|
||||
- name: Configure KUBELET_EXTRA_ARGS.
|
||||
lineinfile:
|
||||
path: '{{ kubelet_args_path }}'
|
||||
line: '{{ kubelet_args_line }}'
|
||||
regexp: '{{ kubelet_args_regexp }}'
|
||||
state: present
|
||||
register: kubelet_config_file
|
||||
|
||||
- name: Reload systemd unit if args were changed.
|
||||
systemd:
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
name: kubelet
|
||||
when: kubelet_config_file is changed
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
---
|
||||
- name: Include OS-specific variables.
|
||||
include_vars: "{{ ansible_os_family }}.yml"
|
||||
|
||||
- include_tasks: setup-RedHat.yml
|
||||
when: ansible_os_family == 'RedHat'
|
||||
|
||||
- include_tasks: setup-Debian.yml
|
||||
when: ansible_os_family == 'Debian'
|
||||
|
||||
- name: Ensure dependencies are installed.
|
||||
package: name=curl state=present
|
||||
|
||||
- name: Install Kubernetes packages.
|
||||
package:
|
||||
name: "{{ item.name | default(item) }}"
|
||||
state: "{{ item.state | default('present') }}"
|
||||
notify: restart kubelet
|
||||
with_items: "{{ kubernetes_packages }}"
|
||||
|
||||
- include_tasks: kubelet-setup.yml
|
||||
|
||||
- name: Ensure kubelet is started and enabled at boot.
|
||||
service:
|
||||
name: kubelet
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Check if Kubernetes has already been initialized.
|
||||
stat:
|
||||
path: /etc/kubernetes/admin.conf
|
||||
register: kubernetes_init_stat
|
||||
|
||||
# Set up master.
|
||||
- include_tasks: master-setup.yml
|
||||
when: kubernetes_role == 'master'
|
||||
|
||||
# Set up nodes.
|
||||
- name: Get the kubeadm join command from the Kubernetes master.
|
||||
command: kubeadm token create --print-join-command
|
||||
changed_when: false
|
||||
when: kubernetes_role == 'master'
|
||||
register: kubernetes_join_command_result
|
||||
|
||||
- name: Set the kubeadm join command globally.
|
||||
set_fact:
|
||||
kubernetes_join_command: >
|
||||
{{ kubernetes_join_command_result.stdout }}
|
||||
{{ kubernetes_join_command_extra_opts }}
|
||||
when: kubernetes_join_command_result.stdout is defined
|
||||
delegate_to: "{{ item }}"
|
||||
delegate_facts: true
|
||||
with_items: "{{ groups['all'] }}"
|
||||
|
||||
- include_tasks: node-setup.yml
|
||||
when: kubernetes_role == 'node'
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
---
|
||||
- name: Initialize Kubernetes master with kubeadm init.
|
||||
command: >
|
||||
kubeadm init
|
||||
--pod-network-cidr={{ kubernetes_pod_network.cidr }}
|
||||
--apiserver-advertise-address={{ kubernetes_apiserver_advertise_address | default(ansible_default_ipv4.address, true) }}
|
||||
--kubernetes-version {{ kubernetes_version_kubeadm }}
|
||||
--ignore-preflight-errors={{ kubernetes_ignore_preflight_errors }}
|
||||
{{ kubernetes_kubeadm_init_extra_opts }}
|
||||
register: kubeadmin_init
|
||||
when: not kubernetes_init_stat.stat.exists
|
||||
|
||||
- name: Print the init output to screen.
|
||||
debug:
|
||||
var: kubeadmin_init.stdout
|
||||
verbosity: 2
|
||||
when: not kubernetes_init_stat.stat.exists
|
||||
|
||||
- name: Ensure .kube directory exists.
|
||||
file:
|
||||
path: ~/.kube
|
||||
state: directory
|
||||
|
||||
- name: Symlink the kubectl admin.conf to ~/.kube/conf.
|
||||
file:
|
||||
src: /etc/kubernetes/admin.conf
|
||||
dest: ~/.kube/config
|
||||
state: link
|
||||
|
||||
- name: Configure Flannel networking.
|
||||
command: "{{ item }}"
|
||||
with_items:
|
||||
- kubectl apply -f {{ kubernetes_flannel_manifest_file_rbac }}
|
||||
- kubectl apply -f {{ kubernetes_flannel_manifest_file }}
|
||||
register: flannel_result
|
||||
changed_when: "'created' in flannel_result.stdout"
|
||||
when: kubernetes_pod_network.cni == 'flannel'
|
||||
|
||||
- name: Configure Calico networking.
|
||||
command: "{{ item }}"
|
||||
with_items:
|
||||
- kubectl apply -f {{ kubernetes_calico_manifest_file }}
|
||||
register: calico_result
|
||||
changed_when: "'created' in calico_result.stdout"
|
||||
when: kubernetes_pod_network.cni == 'calico'
|
||||
|
||||
- name: Get Kubernetes version for Weave installation.
|
||||
shell: kubectl version | base64 | tr -d '\n'
|
||||
changed_when: false
|
||||
register: kubectl_version
|
||||
when: kubernetes_pod_network.cni == 'weave'
|
||||
|
||||
- name: Configure Weave networking.
|
||||
command: "{{ item }}"
|
||||
with_items:
|
||||
- "kubectl apply -f https://cloud.weave.works/k8s/net?k8s-version={{ kubectl_version.stdout_lines[0] }}"
|
||||
register: weave_result
|
||||
changed_when: "'created' in weave_result.stdout"
|
||||
when: kubernetes_pod_network.cni == 'weave'
|
||||
|
||||
# TODO: Check if taint exists with something like `kubectl describe nodes`
|
||||
# instead of using kubernetes_init_stat.stat.exists check.
|
||||
- name: Allow pods on master node (if configured).
|
||||
command: "kubectl taint nodes --all node-role.kubernetes.io/master-"
|
||||
when:
|
||||
- kubernetes_allow_pods_on_master | bool
|
||||
- not kubernetes_init_stat.stat.exists
|
||||
|
||||
- name: Check if Kubernetes Dashboard UI service already exists.
|
||||
shell: kubectl get services --namespace kube-system | grep -q kubernetes-dashboard
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
register: kubernetes_dashboard_service
|
||||
when: kubernetes_enable_web_ui | bool
|
||||
|
||||
- name: Enable the Kubernetes Web Dashboard UI (if configured).
|
||||
command: "kubectl create -f {{ kubernetes_web_ui_manifest_file }}"
|
||||
when:
|
||||
- kubernetes_enable_web_ui | bool
|
||||
- kubernetes_dashboard_service is failed
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: Join node to Kubernetes master
|
||||
shell: >
|
||||
{{ kubernetes_join_command }}
|
||||
creates=/etc/kubernetes/kubelet.conf
|
||||
tags: ['skip_ansible_lint']
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
---
|
||||
- name: Ensure dependencies are installed.
|
||||
apt:
|
||||
name:
|
||||
- apt-transport-https
|
||||
- ca-certificates
|
||||
state: present
|
||||
|
||||
- name: Add Kubernetes apt key.
|
||||
apt_key:
|
||||
url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
|
||||
state: present
|
||||
register: add_repository_key
|
||||
ignore_errors: "{{ kubernetes_apt_ignore_key_error }}"
|
||||
|
||||
- name: Add Kubernetes repository.
|
||||
apt_repository:
|
||||
repo: "{{ kubernetes_apt_repository }}"
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: Add Kubernetes apt preferences file to pin a version.
|
||||
template:
|
||||
src: apt-preferences-kubernetes.j2
|
||||
dest: /etc/apt/preferences.d/kubernetes
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
---
|
||||
- name: Ensure Kubernetes repository exists.
|
||||
yum_repository:
|
||||
name: kubernetes
|
||||
description: Kubernetes
|
||||
enabled: true
|
||||
gpgcheck: true
|
||||
repo_gpgcheck: true
|
||||
baseurl: https://packages.cloud.google.com/yum/repos/kubernetes-el7-{{ kubernetes_yum_arch }}
|
||||
gpgkey:
|
||||
- https://packages.cloud.google.com/yum/doc/yum-key.gpg
|
||||
- https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
|
||||
|
||||
- name: Add Kubernetes GPG keys.
|
||||
rpm_key:
|
||||
key: "{{ item }}"
|
||||
state: present
|
||||
register: kubernetes_rpm_key
|
||||
with_items:
|
||||
- https://packages.cloud.google.com/yum/doc/yum-key.gpg
|
||||
- https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
|
||||
|
||||
- name: Make cache if Kubernetes GPG key changed.
|
||||
command: "yum -q makecache -y --disablerepo='*' --enablerepo='kubernetes'"
|
||||
when: kubernetes_rpm_key is changed
|
||||
args:
|
||||
warn: false
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
Package: kubectl
|
||||
Pin: version {{ kubernetes_version }}.*
|
||||
Pin-Priority: 1000
|
||||
|
||||
Package: kubeadm
|
||||
Pin: version {{ kubernetes_version }}.*
|
||||
Pin-Priority: 1000
|
||||
|
||||
Package: kubelet
|
||||
Pin: version {{ kubernetes_version }}.*
|
||||
Pin-Priority: 1000
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
---
|
||||
kubelet_environment_file_path: /etc/default/kubelet
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
---
|
||||
kubelet_environment_file_path: /etc/sysconfig/kubelet
|
||||
kubernetes_packages:
|
||||
- name: kubelet-{{ kubernetes_version_rhel_package }}-0
|
||||
state: present
|
||||
- name: kubectl-{{ kubernetes_version_rhel_package }}-0
|
||||
state: present
|
||||
- name: kubeadm-{{ kubernetes_version_rhel_package }}-0
|
||||
state: present
|
||||
- name: kubernetes-cni
|
||||
state: present
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
# This should be set via the command line at runtime.
|
||||
tag: ''
|
||||
|
||||
pre_tasks:
|
||||
- name: Verify none of the git submodules need updates.
|
||||
command: >
|
||||
git submodule update --recursive --remote
|
||||
chdir=../
|
||||
register: git_update
|
||||
failed_when: git_update.stdout != ''
|
||||
|
||||
- name: Ensure the ANSIBLE_GALAXY_TOKEN environment variable is set.
|
||||
fail:
|
||||
msg: ANSIBLE_GALAXY_TOKEN is not set.
|
||||
when: "lookup('env','ANSIBLE_GALAXY_TOKEN') == ''"
|
||||
|
||||
- name: Ensure the ~/.ansible directory exists.
|
||||
file:
|
||||
path: ~/.ansible
|
||||
state: directory
|
||||
|
||||
- name: Write the Galaxy token to ~/.ansible/galaxy_token
|
||||
copy:
|
||||
content: |
|
||||
token: {{ lookup('env','ANSIBLE_GALAXY_TOKEN') }}
|
||||
dest: ~/.ansible/galaxy_token
|
||||
|
||||
tasks:
|
||||
- name: Template out the galaxy.yml file.
|
||||
template:
|
||||
src: templates/galaxy.yml.j2
|
||||
dest: ../galaxy.yml
|
||||
|
||||
- name: Build the collection.
|
||||
command: >
|
||||
ansible-galaxy collection build
|
||||
chdir=../
|
||||
|
||||
- name: Publish the collection.
|
||||
command: >
|
||||
ansible-galaxy collection publish ./geerlingguy-k8s-{{ tag }}.tar.gz
|
||||
chdir=../
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
---
|
||||
namespace: geerlingguy
|
||||
name: k8s
|
||||
description: An elegant collection of Kuberenetes automation tools.
|
||||
version: "{{ tag }}"
|
||||
readme: README.md
|
||||
authors:
|
||||
- geerlingguy (https://www.jeffgeerling.com/)
|
||||
dependencies: { }
|
||||
license:
|
||||
- MIT
|
||||
tags:
|
||||
- kubernetes
|
||||
- k8s
|
||||
- infrastructure
|
||||
- cloud
|
||||
- containers
|
||||
- eks
|
||||
- aks
|
||||
- gke
|
||||
- digitalocean
|
||||
- docker
|
||||
- debian
|
||||
- redhat
|
||||
- ubuntu
|
||||
- amazon
|
||||
- linux
|
||||
- native
|
||||
repository: https://github.com/geerlingguy/ansible-collection-k8s
|
||||
documentation: https://github.com/geerlingguy/ansible-collection-k8s
|
||||
# homepage: ""
|
||||
issues: https://github.com/geerlingguy/ansible-collection-k8s/issues
|
||||
build_ignore:
|
||||
- scripts
|
||||
- molecule
|
||||
- .DS_Store
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Crown Copyright (Companies House)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,45 @@
|
||||
Ansible Role: Apache
|
||||
====================
|
||||
|
||||
An ansible role for installing Apache and ModPerl on EL6.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
This role requires epel repo to be set up prior to run. This can easily be accomplished by using a role like [geerlingguy.repo-epel](https://galaxy.ansible.com/geerlingguy/repo-epel/) or another equivalent.
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
Variable |Default | Description
|
||||
----------------|:-------:|-------------
|
||||
apache_version |`2.2.15` |The Apache version to install
|
||||
install_modperl |`true` |Install ModPerl as well?
|
||||
modperl_version |`2.0.4` |The ModPerl version to install
|
||||
apache_user |`apache` |Create an apache user that can be configured for use in your httpd.conf
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
None.
|
||||
|
||||
Example Requirements File
|
||||
-------------------------
|
||||
```
|
||||
- src: https://github.com/companieshouse/ansible-role-apache
|
||||
name: apache
|
||||
```
|
||||
Example Playbook
|
||||
----------------
|
||||
```
|
||||
- hosts: servers
|
||||
roles:
|
||||
- role: apache
|
||||
apache_version: 2.2.15
|
||||
modperl_version: 2.0.4
|
||||
```
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
|
||||
apache_version: 2.2.15
|
||||
|
||||
install_modperl: true
|
||||
modperl_version: 2.0.4
|
||||
|
||||
apache_user: apache
|
||||
@@ -0,0 +1,20 @@
|
||||
galaxy_info:
|
||||
author: Companies House
|
||||
description: Installs Apache and ModPerl rpms on EL6 systems.
|
||||
license: MIT
|
||||
|
||||
min_ansible_version: 2.0
|
||||
|
||||
github_branch: master
|
||||
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- 6
|
||||
|
||||
galaxy_tags:
|
||||
- apache
|
||||
- modperl
|
||||
- mod_perl
|
||||
|
||||
dependencies: []
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
|
||||
driver:
|
||||
name: docker
|
||||
|
||||
ansible:
|
||||
playbook: tests/test.yml
|
||||
|
||||
docker:
|
||||
containers:
|
||||
- name: apache_centos6
|
||||
image: centos
|
||||
image_version: 6
|
||||
privileged: true
|
||||
ansible_groups:
|
||||
- all
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
|
||||
- name: Create a user for apache
|
||||
user:
|
||||
name: "{{ apache_user }}"
|
||||
state: present
|
||||
|
||||
- name: Install apache and mod_perl
|
||||
yum:
|
||||
name: "httpd-{{ apache_version }}"
|
||||
state: present
|
||||
|
||||
- name: Install ModPerl
|
||||
yum:
|
||||
name: "mod_perl-{{ modperl_version }}"
|
||||
state: present
|
||||
when: install_modperl
|
||||
|
||||
- name: Disable the 'main' apache
|
||||
service:
|
||||
name: httpd
|
||||
state: stopped
|
||||
enabled: no
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
- hosts: all
|
||||
roles:
|
||||
- role: ansible-role-apache
|
||||
@@ -0,0 +1,38 @@
|
||||
Role Name
|
||||
=========
|
||||
|
||||
A brief description of the role goes here.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
|
||||
|
||||
- hosts: servers
|
||||
roles:
|
||||
- { role: username.rolename, x: 42 }
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
BSD
|
||||
|
||||
Author Information
|
||||
------------------
|
||||
|
||||
An optional section for the role authors to include contact information, or a website (HTML is not allowed).
|
||||
@@ -0,0 +1,2 @@
|
||||
---
|
||||
# defaults file for apache
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
# handlers file for apache
|
||||
- name: Reload Apache
|
||||
service:
|
||||
name: httpd
|
||||
state: reloaded
|
||||
@@ -0,0 +1,54 @@
|
||||
galaxy_info:
|
||||
author: your name
|
||||
description: your role description
|
||||
company: your company (optional)
|
||||
|
||||
# If the issue tracker for your role is not on github, uncomment the
|
||||
# next line and provide a value
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
|
||||
# Choose a valid license ID from https://spdx.org - some suggested licenses:
|
||||
# - BSD-3-Clause (default)
|
||||
# - MIT
|
||||
# - GPL-2.0-or-later
|
||||
# - GPL-3.0-only
|
||||
# - Apache-2.0
|
||||
# - CC-BY-4.0
|
||||
license: license (GPL-2.0-or-later, MIT, etc)
|
||||
|
||||
min_ansible_version: 2.9
|
||||
|
||||
# If this a Container Enabled role, provide the minimum Ansible Container version.
|
||||
# min_ansible_container_version:
|
||||
|
||||
#
|
||||
# Provide a list of supported platforms, and for each platform a list of versions.
|
||||
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
|
||||
# To view available platforms and versions (or releases), visit:
|
||||
# https://galaxy.ansible.com/api/v1/platforms/
|
||||
#
|
||||
# platforms:
|
||||
# - name: Fedora
|
||||
# versions:
|
||||
# - all
|
||||
# - 25
|
||||
# - name: SomePlatform
|
||||
# versions:
|
||||
# - all
|
||||
# - 1.0
|
||||
# - 7
|
||||
# - 99.99
|
||||
|
||||
galaxy_tags: []
|
||||
# List tags for your role here, one per line. A tag is a keyword that describes
|
||||
# and categorizes the role. Users find roles by searching for tags. Be sure to
|
||||
# remove the '[]' above, if you add tags to this list.
|
||||
#
|
||||
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
|
||||
# Maximum 20 tags per role.
|
||||
|
||||
dependencies:
|
||||
# - cleaner
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user