Authoring Policy Tools & Workflow
There are several ways to approach authoring promises and ensuring they are copied into and then deployed properly from the masterfiles
directory:
- Create or modify files directly in the
masterfiles
directory. - Copy new or modified files into the
masterfiles
directory (e.g. local file copy usingcp
,scp
overssh
). - Utilize a version control system (e.g. Git) to push/pull changes or add new files to the
masterfiles
directory. - Utilize CFEngine Enterprise's integrated Git respository. The CFEngine Enterprise Guide contains more information.
Authoring on a Workstation and Pushing to the Hub Using Git + GitHub
General Summary
- The "masterfiles" directory contains the promises and other related files (this is true in all situations).
- Replace the out of the box setup with an initialized
git
repository and remote to a clone hosted on GitHub. - Add a promise to
masterfiles
that tells CFEngine to check thatgit
repository for changes, and if there are any to merge them intomasterfiles
. - When an author wants to create a new promise, or modify an existing one, they clone the same repository on GitHub so that they have a local copy on their own computer.
- The author will make their edits or additions in their local version of the
masterfiles
repository. - After the author is done making their changes commit them using
git commit
. - After the changes are committed they are then pushed back to the remote repository on GitHub.
- As described in step 3, CFEngine will pull any new changes that were pushed to GitHub (sometime within a five minute time interval).
- Those changes will first exist in
masterfiles
, and then afterwards will be deployed to CFEngine hosts that are bootstrapped to the hub.
Create a Repository on GitHub for Masterfiles
There are two methods possible with GitHub: one is to use the web interface at GitHub.com; the second is to use the GitHub application.
Method One: Create Masterfiles Repository Using GitHub Web Interface
1a. In the GitHub web interface, click on the New repository
button.
1b. Or from the +
drop down menu on the top right hand side of the screen select New repository
.
2. Fill in a value in the Repository name
text entry (e.g. cfengine-masterfiles).
3. Select private
for the type of privacy desired (public
is also possible, but is not recommended in most situations).
4. Optionally, check the Initialize this repository with a README
box. (not required):""
Method Two: Create Masterfiles Repository Using the GitHub Application
- Open the GitHub app and click on the "+ Create" sign to create a new repository.
- Fill in a value in the
Repository name
text entry (e.g. cfengine-masterfiles). - Select
private
for the type of privacy desired (public
is also possible, but is not recommended in most situations). - Select one of your "Accounts" where you want the new repository to be created.
- Click on the "Create" button at the bottom of the screen. A new repository will be created in your local GitHub folder.
Initialize Git Repository in Masterfiles on the Hub
> cd /var/cfengine/masterfiles
> echo cf_promises_validated >> .gitignore
> echo cf_promises_release_id >> .gitignore
> git init
> git commit -m "First commit"
> git remote add origin https://github.com/GitUserName/cfengine-masterfiles.git
> git push -u origin master
Note: cf_promises_validated
and cf_promises_release_id
should be explicitly excluded from VCS as shown above. They are generated files and involved in controlling policy updates. If these files are checked into the repository it can create issues with policy distribution.
Using the above steps on a private repository will fail with a 403 error. There are different approaches to deal with this:
A) Generate a key pair and add it to GitHub
- As root, type
ssh-keygen -t rsa
. - Hit enter when prompted to
Enter file in which to save the key (/root/.ssh/id_rsa):
. - Hit enter again when prompted to
Enter passphrase (empty for no passphrase):
. - Type
ssh-agent bash
and then the enter key. - Type
ssh-add /root/.ssh/id_rsa
. - Type
exit
to leavessh-agent bash
. - To test, type
ssh -T git@github.com
. - Open the generated key file (e.g.
vi /root/.ssh/id_rsa.pub
). - Copy the contents of the file to the clipboard (e.g. Ctrl+Shift+C).
- In the GitHub web interface, click the user account settings button (the icon with the two tools in the top right hand corner).
- On the next screen, on the left hand side, click
SSH keys
. - Click
Add SSH key
on the next screen. - Provide a
Title
for the label (e.g. CFEngine). - Paste the key contents from the clipboard into the
Key
textarea. - Click
Add key
. - If prompted to do so, provide your GitHub password, and then click the
Confirm
button.
B) Or, change the remote url to https://GitUserName@password:github.com/GitUserName/cfengine-masterfiles.git
. This is not safe in a production environment and should only be used for basic testing purposes (if at all).
Create a Remote in Masterfiles on the Hub to Masterfiles on GitHub
- Change back to the
masterfiles
directory, if not already there:> cd /var/cfengine/masterfiles
- Create the remote using the following pattern:
> git remote add upstream ssh://git@github.com/GitUserName/cfengine-masterfiles.git
.
- Verify the remote was registered properly by typing
git remote -v
and pressing enter.- You will see the remote definition in a list alongside any other previously defined remote entries.
Add a Promise that Pulls Changes to Masterfiles on the Hub from Masterfiles on GitHub
- Create a new file in
/var/cfengine/masterfiles
with a unique filename (e.g.vcs_update.cf
) - Add the following text to the
vcs_update.cf
file:
bundle agent vcs_update
{
commands:
"/usr/bin/git"
args => "pull --ff-only upstream master",
contain => masterfiles_contain;
}
body contain masterfiles_contain
{
chdir => "/var/cfengine/masterfiles";
}
- Save the file.
- Add bundle and file information to
/var/cfengine/masterfiles/promises.cf
. Example (where...
represents existing text in the file, omitted for clarity):
body common control
{
bundlesequence => {
...
vcs_update,
};
inputs => {
...
"vcs_update.cf",
};
- Save the file.