diff options
author | sirkubax <muszynski@so1.net> | 2017-09-27 23:57:45 +0200 |
---|---|---|
committer | sirkubax <muszynski@so1.net> | 2017-09-27 23:57:45 +0200 |
commit | 3c7153633842717cb9de7a96f5cd3da5982ffe50 (patch) | |
tree | bad400a5f21a1e6cf1de422983071d1e87853299 | |
parent | 05892ff7ddd69e5f01e9da6d9d602dd318d0485e (diff) |
test markdown
-rw-r--r-- | ansible.html.markdown | 713 |
1 files changed, 119 insertions, 594 deletions
diff --git a/ansible.html.markdown b/ansible.html.markdown index cadf6301..0023a718 100644 --- a/ansible.html.markdown +++ b/ansible.html.markdown @@ -1,7 +1,3 @@ -# JM inventory dynamic aws ec2 -# vault -# roles - --- category: tool tool: ansible @@ -247,10 +243,14 @@ You can use the jinja in the CLI too ansible -m shell -a 'echo {{ my_variable }}` -e 'my_variable=something, playbook_parameter=twentytwo" localhost ``` - -### Jinja2 and templates -jinja filters - +### Jinja2 filters +Junja is powerfull. It has built-in many usefull functions. +```jinja +# get first item of the list +{{ some_list | first() }} +# if variable is undefined - use default value +{{ some_variable | default('default_value') }} +``` #### ansible-vault To maintain **ifrastructure as a code** you need to store secrets. @@ -295,655 +295,180 @@ $ etc/inv/ec2.py --refresh $ ansible -m ping all -i etc/inv/ec2.py ``` +#### ansible profiling - callback +It is ok that your playbook executes some time. Sometimes you may like to speed things up :) -### ansible profiling - callback - -### facts-cache and ansible-cmdb - -### debugging ansible - -### Infrastructure as a code - what about Ansible -virtualenv - -### ansible - dynamic in AWS - -### create instance in AWS - -### create env in AWS - -### Naming - -## Bonus - -### writing own module - -### Python API - -### Web-UI: Ansible Tower, Jenkins, Rundeck - -#become-user, become - -### Tips and tricks -AND,XOR ---check --diff -tags -meta -no_logs - -## Introduction -Ansible is (one of the many) orchestration tools. It allows you to controll your environment (infrastructure and a code) and automate the manual tasks. -'You can think as simple as writing in bash with python API :) -Of course the rabit hole is way deeper.' - -Ansible have great integration with multiple operating systems (even Windows) and some hardware (switches, Firewalls, etc). It has multiple tools that integrate with the could providers. Almost every worth-notice cloud provider is present in the ecosystem (AWS, Azure, Google, DigitalOcean, OVH, etc...) - - - -## Main cons and pros - -### Cons - -It is an agent-less tool - every agent consumes up to 16MB ram - in some environments, it may be noticable amount. -It is agent-less - you have to verify your environment consistency 'on-demand' - there is no built-in mechanism taht would warn you about some change automatically (this can be achieved with reasonable effort - but it must be known) -Official GUI Tool (web inferface) - Ansible Tower - is more than GUI, but it is expensive. There is no 'small enterprice' payment plan. Easy workaround with Rundeck or Jenkins is possible with reasonable workload. - -### Pros - -It is an agent-less tools :) In most scenarios, it use ssh as a transport layer. -In some way you can use it as 'bash on steroids'. -It is very-very-very easy to start. If you are familiar with ssh concept - you already know ansible :) (almost). My personal record is: 'I did show how to install and use ansible (for simple raspberry pi cluster management) and it tool me 30 seconds to deliver a working tool !!!)' -I do provide a training services - I'm able to teach a production-ready person - in 8 hours (1 training day)! It covers all needed to work aspects! No other tool can match this ease of use! -It executes when you do it - other tools (salt, puppet, chef - might execute in different scenario than you would expect) -Documentation is at the world-class standard! -The comunity (github, stackOverflow) would help you very fast. -Writing own modules and extension is fairly easy. - - -### Neutral -Migration Ansible<->Salt is failrly easy - so if you would need an event-driven agent environment - it would be a good choice to start quick with Ansible, and convert to salt when needed. - -## Basics on ansible - -Ansible uses ssh or paramiko as a transport layer. In a way you can imagine that you are using a ssh with API to perform your action. -In the 'low-level' way you can use it to execute remote command in more controlled way (still using ssh). -On the other hand - in advanced scope - you can use python anible code as a library to your own python scrips! This is awesome! (if you know what you are doing). It is a bit like fabric then. - -But ansible is way more! It provides an execution plans, an API, library, callbacks, not forget to mention - COMUNITY! and great support by developers! - - - - ---- -Github template placeholder - to be removed - -### Centralized Versioning VS Distributed Versioning - -* Centralized version control focuses on synchronizing, tracking, and backing -up files. -* Distributed version control focuses on sharing changes. Every change has a -unique id. -* Distributed systems have no defined structure. You could easily have a SVN -style, centralized system, with git. - -[Additional Information](http://git-scm.com/book/en/Getting-Started-About-Version-Control) - -### Why Use Git? - -* Can work offline. -* Collaborating with others is easy! -* Branching is easy! -* Branching is fast! -* Merging is easy! -* Git is fast. -* Git is flexible. - -## Git Architecture - -### Repository - -A set of files, directories, historical records, commits, and heads. Imagine it -as a source code data structure, with the attribute that each source code -"element" gives you access to its revision history, among other things. - -A git repository is comprised of the .git directory & working tree. - -### .git Directory (component of repository) - -The .git directory contains all the configurations, logs, branches, HEAD, and -more. -[Detailed List.](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html) - -### Working Tree (component of repository) - -This is basically the directories and files in your repository. It is often -referred to as your working directory. - -### Index (component of .git dir) - -The Index is the staging area in git. It's basically a layer that separates -your working tree from the Git repository. This gives developers more power -over what gets sent to the Git repository. - -### Commit - -A git commit is a snapshot of a set of changes, or manipulations to your -Working Tree. For example, if you added 5 files, and removed 2 others, these -changes will be contained in a commit (or snapshot). This commit can then be -pushed to other repositories, or not! - -### Branch - -A branch is essentially a pointer to the last commit you made. As you go on -committing, this pointer will automatically update to point the latest commit. - -### Tag - -A tag is a mark on specific point in history. Typically people use this -functionality to mark release points (v1.0, and so on) - -### HEAD and head (component of .git dir) - -HEAD is a pointer that points to the current branch. A repository only has 1 -*active* HEAD. -head is a pointer that points to any commit. A repository can have any number -of heads. - -### Stages of Git -* Modified - Changes have been made to a file but file has not been committed -to Git Database yet -* Staged - Marks a modified file to go into your next commit snapshot -* Committed - Files have been committed to the Git Database - -### Conceptual Resources - -* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/) -* [Git For Designers](http://hoth.entp.com/output/git_for_designers.html) - -## Commands - -### init - -Create an empty Git repository. The Git repository's settings, stored -information, and more is stored in a directory (a folder) named ".git". - -```bash -$ git init -``` - -### config - -To configure settings. Whether it be for the repository, the system itself, -or global configurations ( global config file is `~/.gitconfig` ). +Since ansible 2.x there is bouilt-in callback for task execution profiling -```bash -# Print & Set Some Basic Config Variables (Global) -$ git config --global user.email "MyEmail@Zoho.com" -$ git config --global user.name "My Name" ``` - -[Learn More About git config.](http://git-scm.com/docs/git-config) - -### help - -To give you quick access to an extremely detailed guide of each command. Or to -just give you a quick reminder of some semantics. - -```bash -# Quickly check available commands -$ git help - -# Check all available commands -$ git help -a - -# Command specific help - user manual -# git help <command_here> -$ git help add -$ git help commit -$ git help init -# or git <command_here> --help -$ git add --help -$ git commit --help -$ git init --help +vi ansible.cfg +#set this to: +callback_whitelist = profile_tasks ``` -### ignore files +#### facts-cache and ansible-cmdb +You can pool some infrmations of you environment from another hosts. +If the informations does not change - you may consider using a facts_cache to speed things up. -To intentionally untrack file(s) & folder(s) from git. Typically meant for -private & temp files which would otherwise be shared in the repository. -```bash -$ echo "temp/" >> .gitignore -$ echo "private_key" >> .gitignore ``` +vi ansible.cfg -### status - -To show differences between the index file (basically your working copy/repo) -and the current HEAD commit. - -```bash -# Will display the branch, untracked files, changes and other differences -$ git status - -# To learn other "tid bits" about git status -$ git help status +# if set to a persistent type (not 'memory', for example 'redis') fact values +# from previous runs in Ansible will be stored. This may be useful when +# wanting to use, for example, IP information from one group of servers +# without having to talk to them in the same playbook run to get their +# current IP information. +fact_caching = jsonfile +fact_caching_connection = ~/facts_cache +fact_caching_timeout = 86400 ``` -### add +I like to use `jsonfile` as my backend. It allows to use another project +`ansible-cmdb` [github] that generates a HTML page of your inventory resources. A nice 'free' addition! -To add files to the staging area/index. If you do not `git add` new files to -the staging area/index, they will not be included in commits! +#### debugging ansible +When your job fails - it is good to be effective with debugging. -```bash -# add a file in your current working directory -$ git add HelloWorld.java - -# add a file in a nested dir -$ git add /path/to/file/HelloWorld.c - -# Regular Expression support! -$ git add ./*.java -``` +1. Increase verbosiy by using multiple -v **[ -vvvvv]** +2. If variable is undefined +3. If variable (dictionary or a list) is undefined +4. Jinja template debug -This only adds a file to the staging area/index, it doesn't commit it to the -working directory/repo. - -### branch - -Manage your branches. You can view, edit, create, delete branches using this -command. +#### Infrastructure as a code - what about Ansible +You already know, that ansible-vault allow you to store your poufne data along with your code (in repository). You can go further - and define your ansible installation and configuration as-a-code. +See `environment.sh` to learn how to install the ansible itself inside a `virtualenv` that is not attached to your operating system (can be changed by non-privilages user), and as additiinal benefit - upgrading version of ansible is as easy as installing new version in new virtualenv. You can have multiple versions of Ansible present in the same time. This is very helpfull! ```bash -# list existing branches & remotes -$ git branch -a - -# create a new branch -$ git branch myNewBranch - -# delete a branch -$ git branch -d myBranch + # recreate ansible 2.x venv +$ rm -rf venv2 +$ source environment2.sh + # execute playbook +(venv2)$ ansible-playbook playbooks/ansible1.9_playbook.yml # would fail - deprecated syntax -# rename a branch -# git branch -m <oldname> <newname> -$ git branch -m myBranchName myNewBranchName + # now lets install ansible 1.9.x next to ansible 2.x +(venv2)$ deactivate +$ source environment.1.9.sh + # execute playbook +(venv1.9)$ ansible-playbook playbooks/ansible1.9_playbook.yml # works! -# edit a branch's description -$ git branch myBranchName --edit-description -``` - -### tag - -Manage your tags - -```bash -# List tags -$ git tag - -# Create a annotated tag -# The -m specifies a tagging message,which is stored with the tag. -# If you don’t specify a message for an annotated tag, -# Git launches your editor so you can type it in. -$ git tag -a v2.0 -m 'my version 2.0' - -# Show info about tag -# That shows the tagger information, the date the commit was tagged, -# and the annotation message before showing the commit information. -$ git show v2.0 - -# Push a single tag to remote -$ git push origin v2.0 - -# Push a lot of tags to remote -$ git push origin --tags -``` - -### checkout - -Updates all files in the working tree to match the version in the index, or -specified tree. - -```bash -# Checkout a repo - defaults to master branch -$ git checkout - -# Checkout a specified branch -$ git checkout branchName - -# Create a new branch & switch to it -# equivalent to "git branch <name>; git checkout <name>" - -$ git checkout -b newBranch -``` - -### clone - -Clones, or copies, an existing repository into a new directory. It also adds -remote-tracking branches for each branch in the cloned repo, which allows you -to push to a remote branch. - -```bash -# Clone learnxinyminutes-docs -$ git clone https://github.com/adambard/learnxinyminutes-docs.git - -# shallow clone - faster cloning that pulls only latest snapshot -$ git clone --depth 1 https://github.com/adambard/learnxinyminutes-docs.git - -# clone only a specific branch -$ git clone -b master-cn https://github.com/adambard/learnxinyminutes-docs.git --single-branch -``` - -### commit - -Stores the current contents of the index in a new "commit." This commit -contains the changes made and a message created by the user. - -```bash -# commit with a message -$ git commit -m "Added multiplyNumbers() function to HelloWorld.c" - -# automatically stage modified or deleted files, except new files, and then commit -$ git commit -a -m "Modified foo.php and removed bar.php" - -# change last commit (this deletes previous commit with a fresh commit) -$ git commit --amend -m "Correct message" -``` - -### diff - -Shows differences between a file in the working directory, index and commits. - -```bash -# Show difference between your working dir and the index -$ git diff - -# Show differences between the index and the most recent commit. -$ git diff --cached - -# Show differences between your working dir and the most recent commit -$ git diff HEAD -``` - -### grep - -Allows you to quickly search a repository. - -Optional Configurations: - -```bash -# Thanks to Travis Jeffery for these -# Set line numbers to be shown in grep search results -$ git config --global grep.lineNumber true - -# Make search results more readable, including grouping -$ git config --global alias.g "grep --break --heading --line-number" -``` - -```bash -# Search for "variableName" in all java files -$ git grep 'variableName' -- '*.java' - -# Search for a line that contains "arrayListName" and, "add" or "remove" -$ git grep -e 'arrayListName' --and \( -e add -e remove \) -``` - -Google is your friend; for more examples -[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja) - -### log - -Display commits to the repository. - -```bash -# Show all commits -$ git log - -# Show only commit message & ref -$ git log --oneline - -# Show merge commits only -$ git log --merges - -# Show all commits represented by an ASCII graph -$ git log --graph -``` - -### merge - -"Merge" in changes from external commits into the current branch. - -```bash -# Merge the specified branch into the current. -$ git merge branchName - -# Always generate a merge commit when merging -$ git merge --no-ff branchName -``` - -### mv - -Rename or move a file - -```bash -# Renaming a file -$ git mv HelloWorld.c HelloNewWorld.c - -# Moving a file -$ git mv HelloWorld.c ./new/path/HelloWorld.c - -# Force rename or move -# "existingFile" already exists in the directory, will be overwritten -$ git mv -f myFile existingFile -``` - -### pull - -Pulls from a repository and merges it with another branch. - -```bash -# Update your local repo, by merging in new changes -# from the remote "origin" and "master" branch. -# git pull <remote> <branch> -$ git pull origin master - -# By default, git pull will update your current branch -# by merging in new changes from its remote-tracking branch -$ git pull - -# Merge in changes from remote branch and rebase -# branch commits onto your local repo, like: "git fetch <remote> <branch>, git -# rebase <remote>/<branch>" -$ git pull origin master --rebase -``` - -### push - -Push and merge changes from a branch to a remote & branch. - -```bash -# Push and merge changes from a local repo to a -# remote named "origin" and "master" branch. -# git push <remote> <branch> -$ git push origin master - -# By default, git push will push and merge changes from -# the current branch to its remote-tracking branch -$ git push - -# To link up current local branch with a remote branch, add -u flag: -$ git push -u origin master -# Now, anytime you want to push from that same local branch, use shortcut: -$ git push + # please note that you have both venv1.9 and venv2 present - you need to (de)activate one - that is all ``` +### Naming -### stash +### Bonus -Stashing takes the dirty state of your working directory and saves it on a -stack of unfinished changes that you can reapply at any time. +### writing own module -Let's say you've been doing some work in your git repo, but you want to pull -from the remote. Since you have dirty (uncommited) changes to some files, you -are not able to run `git pull`. Instead, you can run `git stash` to save your -changes onto a stack! +### Python API -```bash -$ git stash -Saved working directory and index state \ - "WIP on master: 049d078 added the index file" - HEAD is now at 049d078 added the index file - (To restore them type "git stash apply") -``` +### Web-UI: Ansible Tower, Jenkins, Rundeck -Now you can pull! +#### Ansible Tower +Ansible provides a Web User Interface called `Ansible Tower`. +It is a convienient way to run Ansible Playbooks, have proper user management, log retention, and cron (periodic jobs). -```bash -git pull -``` -`...changes apply...` +Personaly I'm not a fan of it - it's to expensive for my cases, and the trial is 10 inventory-hosts only. -Now check that everything is OK +For my usecases I hide the 'pure ansible' commands behind other projects. -```bash -$ git status -# On branch master -nothing to commit, working directory clean -``` +#### Rundeck +This is nice, secure interface, that allows you to execute a jobs of your choice (CLI, script, execution plan). +It can perform roling-deployment (without Ansible), can integrate with clouds, etc. -You can see what "hunks" you've stashed so far using `git stash list`. -Since the "hunks" are stored in a Last-In-First-Out stack, our most recent -change will be at top. +#### Jenkins +For my 'business cases' I use Jenkins - it has a 'cron', jobs can be binded into 'pipelines'. -```bash -$ git stash list -stash@{0}: WIP on master: 049d078 added the index file -stash@{1}: WIP on master: c264051 Revert "added file_size" -stash@{2}: WIP on master: 21d80a5 added number to log -``` - -Now let's apply our dirty changes back by popping them off the stack. - -```bash -$ git stash pop -# On branch master -# Changes not staged for commit: -# (use "git add <file>..." to update what will be committed) -# -# modified: index.html -# modified: lib/simplegit.rb -# -``` +### become-user, become +### ansible - dynamic in AWS +### create instance in AWS +### create env in AWS -`git stash apply` does the same thing +### Tips and tricks -Now you're ready to get back to work on your stuff! +##### --check -C +Always make sure that your playbook can executes in 'dry run' mode (--check), and it's execution is not declaring 'Changed' objects. -[Additional Reading.](http://git-scm.com/book/en/v1/Git-Tools-Stashing) +##### --diff -D +Diff is usefull to see nice detail of the files changed -### rebase (caution) +It compare 'in memory' the files like `diff -BbruN fileA fileB` -Take all changes that were committed on one branch, and replay them onto -another branch. -*Do not rebase commits that you have pushed to a public repo*. +##### Execute hosts with 'regex' ```bash -# Rebase experimentBranch onto master -# git rebase <basebranch> <topicbranch> -$ git rebase master experimentBranch +ansible -m ping web* ``` -[Additional Reading.](http://git-scm.com/book/en/Git-Branching-Rebasing) - -### reset (caution) - -Reset the current HEAD to the specified state. This allows you to undo merges, -pulls, commits, adds, and more. It's a great command but also dangerous if you -don't know what you are doing. +##### +Host groups can be joined, negated, etc ```bash -# Reset the staging area, to match the latest commit (leaves dir unchanged) -$ git reset - -# Reset the staging area, to match the latest commit, and overwrite working dir -$ git reset --hard - -# Moves the current branch tip to the specified commit (leaves dir unchanged) -# all changes still exist in the directory. -$ git reset 31f2bb1 - -# Moves the current branch tip backward to the specified commit -# and makes the working dir match (deletes uncommited changes and all commits -# after the specified commit). -$ git reset --hard 31f2bb1 +ansible -m ping web*:!backend:monitoring:&allow_change ``` -### reflog (caution) +##### Tagging +You should tag some (not all) objects - a task in a playbook, all tasks included form a role, etc. +It allwos you to execute the choosen parts of the playbook. -Reflog will list most of the git commands you have done for a given time period, -default 90 days. +##### no_logs: True +You may see, that some roles print a lot of output in verbose mode. There is also a debug module. +This is the place where credentials may leak. Use `no_log` to hide the output. -This give you the a change to reverse any git commands that have gone wrong -for instance if a rebase is has broken your application. +##### Debug module +allows to print a value to the screen -You can do this: +##### Register the output of a task +You can register the output (stdout), rc (return code), stderr of a task with the `register` command. -1. `git reflog` to list all of the git commands for the rebase -``` -38b323f HEAD@{0}: rebase -i (finish): returning to refs/heads/feature/add_git_reflog -38b323f HEAD@{1}: rebase -i (pick): Clarify inc/dec operators -4fff859 HEAD@{2}: rebase -i (pick): Update java.html.markdown -34ed963 HEAD@{3}: rebase -i (pick): [yaml/en] Add more resources (#1666) -ed8ddf2 HEAD@{4}: rebase -i (pick): pythonstatcomp spanish translation (#1748) -2e6c386 HEAD@{5}: rebase -i (start): checkout 02fb96d -``` -2. Select where to reset to, in our case its `2e6c386`, or `HEAD@{5}` -3. 'git reset --hard HEAD@{5}' this will reset your repo to that head -4. You can start the rebase again or leave it alone. +##### Conditionals: when: -[Additional Reading.](https://git-scm.com/docs/git-reflog) +##### Loop: with, with_items, with_dict, with_together -### revert -Revert can be used to undo a commit. It should not be confused with reset which -restores the state of a project to a previous point. Revert will add a new -commit which is the inverse of the specified commit, thus reverting it. +## Introduction +Ansible is (one of the many) orchestration tools. It allows you to controll your environment (infrastructure and a code) and automate the manual tasks. +'You can think as simple as writing in bash with python API :) +Of course the rabit hole is way deeper.' -```bash -# Revert a specified commit -$ git revert <commit> -``` +Ansible have great integration with multiple operating systems (even Windows) and some hardware (switches, Firewalls, etc). It has multiple tools that integrate with the could providers. Almost every worth-notice cloud provider is present in the ecosystem (AWS, Azure, Google, DigitalOcean, OVH, etc...) -### rm -The opposite of git add, git rm removes files from the current working tree. -```bash -# remove HelloWorld.c -$ git rm HelloWorld.c +## Main cons and pros -# Remove a file from a nested dir -$ git rm /pather/to/the/file/HelloWorld.c -``` +### Cons -## Further Information +It is an agent-less tool - every agent consumes up to 16MB ram - in some environments, it may be noticable amount. +It is agent-less - you have to verify your environment consistency 'on-demand' - there is no built-in mechanism taht would warn you about some change automatically (this can be achieved with reasonable effort - but it must be known) +Official GUI Tool (web inferface) - Ansible Tower - is more than GUI, but it is expensive. There is no 'small enterprice' payment plan. Easy workaround with Rundeck or Jenkins is possible with reasonable workload. -* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1) +### Pros -* [Learn Git Branching - the most visual and interactive way to learn Git on the web](http://learngitbranching.js.org/) +It is an agent-less tools :) In most scenarios, it use ssh as a transport layer. +In some way you can use it as 'bash on steroids'. +It is very-very-very easy to start. If you are familiar with ssh concept - you already know ansible :) (almost). My personal record is: 'I did show how to install and use ansible (for simple raspberry pi cluster management) and it tool me 30 seconds to deliver a working tool !!!)' +I do provide a training services - I'm able to teach a production-ready person - in 8 hours (1 training day)! It covers all needed to work aspects! No other tool can match this ease of use! +It executes when you do it - other tools (salt, puppet, chef - might execute in different scenario than you would expect) +Documentation is at the world-class standard! +The comunity (github, stackOverflow) would help you very fast. +Writing own modules and extension is fairly easy. -* [Udemy Git Tutorial: A Comprehensive Guide](https://blog.udemy.com/git-tutorial-a-comprehensive-guide/) -* [Git Immersion - A Guided tour that walks through the fundamentals of git](http://gitimmersion.com/) +### Neutral +Migration Ansible<->Salt is failrly easy - so if you would need an event-driven agent environment - it would be a good choice to start quick with Ansible, and convert to salt when needed. -* [git-scm - Video Tutorials](http://git-scm.com/videos) +## Basics on ansible -* [git-scm - Documentation](http://git-scm.com/docs) +Ansible uses ssh or paramiko as a transport layer. In a way you can imagine that you are using a ssh with API to perform your action. +In the 'low-level' way you can use it to execute remote command in more controlled way (still using ssh). +On the other hand - in advanced scope - you can use python anible code as a library to your own python scrips! This is awesome! (if you know what you are doing). It is a bit like fabric then. -* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/) +But ansible is way more! It provides an execution plans, an API, library, callbacks, not forget to mention - COMUNITY! and great support by developers! -* [SalesForce Cheat Sheet](http://res.cloudinary.com/hy4kyit2a/image/upload/SF_git_cheatsheet.pdf) -* [GitGuys](http://www.gitguys.com/) -* [Git - the simple guide](http://rogerdudler.github.io/git-guide/index.html) -* [Pro Git](http://www.git-scm.com/book/en/v2) +# JM inventory dynamic aws ec2 +# vault +# roles -* [An introduction to Git and GitHub for Beginners (Tutorial)](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners) |