This repository corresponds to the controller layer and is used to deploy projects. This is the top layer and is responsible to manage and deploy projects. After setting up this layer, you can start deploying projects, according to the projects defined in the main environment repositoryā .
The deployment of a specific project is done by the cloud layer, which uses the variablesā generated in the preparation stepā of this layer (controller).
A default implementation of the cloud layer is located at http://github.com/lucasbasquerotto/cloudā .
Before start using this layer, it's easier to see it in action. Below is a simple demo used to deploy a project. The demo uses pre-defined variables generated by the controller layerā so that this layer is not needed to execute, and then execute the cloud layerā directly to deploy a project.
To execute the demo you will need a container engine (like docker or podman).
Create an empty directory somewhere in your filesystem, let's say, /var/demo.
Create 2 directories in it: env and data (the names could be different, just remember to use these directories when mapping volumes to the container).
Create a demo.yml file inside env with the data needed to deploy the project:
# Enter the data here (see the demo examples)
docker run -it --rm -v /var/demo/env:/env -v /var/demo/data:/lrd local/demo
The above commands in a shell script:
mkdir -p /var/demo/env /var/demo/data
cat <<'SHELL' > /var/demo/env/demo.yml
# Enter the data here (see the demo examples)
SHELL
docker run -it --rm -v /var/demo/env:/env -v /var/demo/data:/lrd local/demo
That's it. The project was deployed.
š You can see examples of project deployment demos hereā .
The demos are great for what they are meant to be: demos, prototypes. They shouldn't be used for development (bad DX if you need real time changes without having to push and pull newer versions of repositories, furthermore you are unable to clone repositories in specific locations defined by you in the project folder). They also shouldn't be used in production environments due to bad security (the vault value used for decryption is 123456, and changes to the project environment repositoryā may be lost if you forget to push them).
The root folder is the base directory in which the projects managed by the controller are defined. It's the parent of the controller repository (ctl) and contains:
The secrets directory: has the vault files to decrypt the ssh files to clone the projects environment repositoriesā ).
The projects directory: has the project files, secrets and repositories.
The users directory: has the users home directories (when use_subuserā is true).
The data directory: used mainly in local development environments to contain project deployment data (like logs, databases and uploaded files).
The following instructions assume that they are being run from the <root> folder, which will contain the data generated from all projects.
The machine that will deploy the projects should have the following tools:
To be able to deploy the projects, the controller will need to know which projects to deploy. That information is declared in the main environment repositoryā . You can manually clone the repository with git at the folder ctl/env-main (or point a symlink located at ctl/env-main to another location on you machine) or run the following command that will do that for you:
./ctl/run setup
The above command will ask you to enter the repository which willl be cloned (git clone <git_env_main_repository>). An alternative is to enter the repository directly like the following:
./ctl/run setup <git_env_main_repository>
If you have a symlink at ctl/env-main pointing to an empty directory, the git repository will be cloned at that target repository.
To make things more practical, you can create a repository to become the root folder of your environment and then make an instruction that runs the entire setup step in a more straightforward way, with just a simple command like ./setup.
This repositoryā does that, and you can fork it and change only the env.sh file, defining in it the controller repository and branch, your main environment repository, and optionally the location of this repository relatively to the root directory (a symlink will be created at ctl/env-main).
The main environment repository will be a hub containing information about the projects to deploy. It will be located at ctl/env-main and must have the following files:
env.shFile that will be sourced during launchā to know which container engine should run the projects and also which container image it will run. It also has other useful optionsā and examplesā explained below.
vars.ymlFile that contains the specifications for all projects. It will be used during launchā to deploy the project specified in the launch command. See its structureā and the exampleā below.
| Option | Default | Description |
|---|---|---|
container | The container repository (and tag) that will run the Controller Preparation Stepā . | |
container_type | docker | The container engine CLI used when running the container. The command to run the container is the value of this option. The commands accepted by the CLI are assumed to be compatible with the ones from the docker CLI. |
root | false | When true, runs the container in the Controller Preparation Stepā as root (with sudo). |
use_subuser | false | When true, runs the container in the Controller Preparation Stepā , as well as the container to run the steps in the next layer, with the username <subuser_prefix><project_name> (the user will be created if it doesn't exists already, and the home directory will be users/<username>). |
subuser_prefix | The prefix used to create the user that will run the containers. The username will be <subuser_prefix><project_name>. For example, if subuser_prefix is project- and project_name is my-demo, the username will be project-my-demo. When use_subuser is true, this option is required and cannot be empty. |
An example of the file for a development environment is as follows:
export container=lucasbasquerotto/ansible:0.0.2
export container_type=podman
Another example:
export container=lucasbasquerotto/ansible:0.0.2
export root=true
The above example will use docker as the container engine (container_type).
An example of the file for a production environment is as follows:
export container=lucasbasquerotto/ansible:0.0.2
export container_type=podman
export use_subuser=true
export subuser_prefix=project-
| Option | Default | Description |
|---|---|---|
dev | false | When true, defines that the project will run in a development environment. If the value is false, the project can't be launched with the --devā option. |
init | {} | Define a dictionary in which the value of each key is an object of the type specified in the Initā section. |
repo | {} | Define a dictionary in which the value of each key is an object of the type specified in the Repoā section. |
repo_vault | {} | Define a dictionary in which the value of each key is an object of the type specified in the Repo Vaultā section. |
env_params | {} | Define a dictionary in which the value of each key is an object of the type specified in the Env Paramsā section. |
path_params | {} | Define a dictionary in which the value of each key is an object of the type specified in the Path Paramsā section. |
| TODO |
This object contains data about the container in which the step after the Controller Preparation Stepā will run.
| Option | Default | Description |
|---|---|---|
container | The container repository (and tag) that will run the steps after the Controller Preparation Stepā . | |
container_type | docker | The container engine CLI used when running the container. The command to run the container is the value of this option. The commands accepted by the CLI are assumed to be compatible with the ones from the docker CLI. |
root | false | When true, runs the container as root (with sudo). |
run_file | /usr/local/bin/run | The executable file to run inside the container after the Controller Preparation Stepā ends. See details.ā |
This object contains data about the project environment repositoryā .
| Option | Default | Description |
|---|---|---|
src | The repository source (URL). | |
version | master | The repository branch or tag. |
ssh_file | (Optional) The location (relative to the main environment repositoryā ) of the ssh file needed to clone the repository. The file can be in an encrypted with ansible-vaultā (the key to decrypt the file should be in the Main Vault Fileā ). |
This object contains the location to the project vault fileā .
| Option | Default | Description |
|---|---|---|
file | The project vault file (relative to the project environment repositoryā ). | |
force | false | Will ask for the vault passphrase whenever the vault value should be used. This option is only considered if file is empty. |
This object contains project specific variables. It's expected that the next layer is able to handle this option, merging the options defined here with the options defined in the project environment fileā . Specifying options here can be convenient to deploy multiple similar projects without having to create a different project environment fileā for each case, achieving a more DRY approach. To make staging and production environments more predictable, it's advisable to not use this option for such projects.
There are no pre-established properties for this option (they are project specific).
Using the cloud layer defined at http://github.com/lucasbasquerotto/cloudā , the variables defined in this option will be accessible through the params object in the project environment fileā .
This object could be considered a special case of the Env Paramsā section. It contains paths to repositories, to be mapped to different locations than they would be otherwise. The paths are relative to the root repository.
Repositories mapped this way will be cloned the first time (when the directory is empty) and ignored from then on, allowing the deployment of projects along with real-time changes to the deployment code, if the code is inside one of the mapped repositories.
Mapped repositories can be shared accross different projects as long as the mapped locations are the same.
Using the cloud layer defined at http://github.com/lucasbasquerotto/cloudā , this option will be ignored when not running in a development environment (dev: falseā ). In this case, it accepts the following options:
| Option | Default | Description |
|---|---|---|
path_env | Path in which the project environment repositoryā will be cloned. | |
path_env_base | Path in which the environment base repository, defined in the env option inside project environment fileā , will be cloned. | |
path_map_repos | {} | Dictionary with objects in the form [repo]: string, in which repositories defined in the project environment fileā are mapped to the specified paths. |
dev: true
init:
default:
container: "lucasbasquerotto/cloud:1.3.6"
root: true
other:
container: "lucasbasquerotto/cloud:1.3.6"
container_type: "podman"
other2:
container: "lucasbasquerotto/cloud"
container_type: "podman"
root: true
repo:
default:
src: "ssh://[email protected]/lucasbasquerotto/project-env-demo.git"
version: "master"
ssh_file: "ssh/repo.encrypted.key"
other:
src: "ssh://[email protected]/lucasbasquerotto/other-project-env-demo.git"
version: "master"
ssh_file: "ssh/repo.encrypted.key"
repo_vault:
default:
file: "vault/main"
other:
force: true
env_params:
local:
pod_custom_dir_sync: true
named_volumes: true
custom:
name: "my-custom-project"
path_params:
default:
path_env: "repos/env"
path_env_base: "repos/env-base"
path_map_repos:
env_base: "repos/env-base"
cloud: "repos/cloud"
ext_cloud: "repos/ext-cloud"
pod: "repos/pod"
ext_pod: "repos/ext-pod"
app: "repos/app"
# TODO
This step is the first and only step executed in the controller layer to launch the project (deployment). The main environment repositoryā must be present at ctl/env-main so that this step can be run.
This step generates the Controller Output Varsā , as well as the project ssh key fileā and the project vault fileā to be used by the next layerā .
The main vault file for a project is located at secrets/projects/<project_name>/vault and contains the value to decrypt:
The project ssh key fileā to clone the project environment repositoryā .
The project vault fileā to decrypt the contents of the project environment fileā .
The SSH file used to clone the project environment repositoryā . This file is optional and isn't needed for public repositories, but it's very important that this ssh file is specified if the aforementioned repository has secrets in it (and the repository should be private).
The vault file used to decrypt the project environment fileā in the project environment repositoryā . This file is optional, but recommended to be used if the environment file has secrets in it. It's also recommended to make the repository private. The encryption should be done with ansible-vaultā .
The launch command deploys a project. It is executed like ctl/launch ... (or alternatively ctl/run launch ..., or even ctl/run l ...) and is responsible to run the Controller Preparation Stepā and call the command to run the subsequent steps (in the next layers). Below you can see the optionsā that can be used with it as well as examplesā of running this step.
Below are the options that can be used to launchā a project:
| Option | Description |
|---|---|
-c--clear | Clears the project directory and ends the execution (may be used to clear the directory when the mapping to the project repositories (during development) changes (with the path_params property), which could cause issues with symlinks). If the project was deployed with the --dev option, it should be cleared with this option too, like ./ctl/launch -dc <project_name>. |
-d--dev | Runs the project in a development environment. It allows to map paths to repositories to share the repository across multiple projects and avoid cleaning live changes made to the repository that were still not commited (will not update the repository to the version specified, which allows to develop and test changes without the need to push those changes). |
-e--enter | Enters the container that runs the preparation step in the controller layer, instead of executing it. The command that would be executed can be seen by running (inside the container) cat tmp/cmd. This command doesn't work with the --inside option. |
-f--force | Force the execution even if the commit of the project environment repositoryā is the same as the last time it was executed. |
-i--inside | Considers that the current environment is already inside an environment that has the necessary stuff to run the project, without the need to run it inside a container (the environment may already be a container). See Running Inside a Containerā and Running Without Containersā for more information. |
-n--next | The deployment will use parameters passed after the project name to be used by the next steps. How those parameters will be used depends on what the next step expects them to be. Using the cloud layer defined at http://github.com/lucasbasquerotto/cloudā , this will expect the parameters specified hereā . |
-p--prepare | Only runs the preparation step and expects that the subsequent layers accept this option so as to run only the preparation step in that layer, and forwards the option to subsequent layers, if needed. This has a particular feature that allows to pass arguments to each step that will handle it (as long as subsequent layers handle it). For example, passing the args -vv after the project name would generally be used only by the last step (Cloud Context Main Stepā ), but in this case it will be used as args to run the Controller Preparation Stepā and no args to subsequent steps.You can pass -- to indicate the end of the arguments for a given step, so the following args -a -b -- -c -- -d will pass the args -a -b to the Controller Preparation Stepā , and -c -- -d to the next step. You can use --skip to skip a given step (you shouldn't pass -- in this case). For example, --skip -c -- -d will skip the Controller Preparation Stepā and pass -c -- -d to the next step.Using the cloud layer defined at http://github.com/lucasbasquerotto/cloudā , this will run the steps Controller Preparation Stepā , Cloud Preparation Stepā and Cloud Context Preparation Stepā , but won't run the Cloud Context Main Stepā . You will have 3 steps in this case, so if you run ctl/run launch <project_name> -- --skip -vv, the Controller Preparation Stepā will run without args, the Cloud Preparation Stepā will be skipped and the Cloud Context Preparation Stepā will run in verbose modeā |
-P--no-prompt | By default, the launch expects an unencrypted vault fileā at secrets/projects/<project_name>/vault. This vault file is used to decrypt values in the main environment repository for a specific project, like the ssh key for the project environment repository, or the vault to be used for the next steps (to decrypt values in the project environment repository). If this file is not present, there is a prompt asking to enter the vault passphrase. This option runs the Controller Preparation Stepā without the vault file if the file is not present (it's expected that the file was created beforehand, or that the main environment file for this project doesn't use encrypted values to be decrypted using a vault file, otherwise an error will be thrown). |
-s--fast | Skips the Controller Preparation Stepā and may skip preparation steps in subsequent layers (if those layers use this option and forwards it to the next layer). Using the cloud layer defined at http://github.com/lucasbasquerotto/cloudā , this will skip the Controller Preparation Stepā , Cloud Preparation Stepā and Cloud Context Preparation Stepā , running only the Cloud Context Main Stepā for each context. |
-V--no-vault | By default, the launch expects an unencrypted vault fileā at secrets/projects/<project_name>/vault. This vault file is used to decrypt values in the main environment repository for a specific project, like the ssh key for the project environment repository, or the vault to be used for the next steps (to decrypt values in the project environment repository). This option runs the Controller Preparation Stepā without the vault file (it's expected that the main environment file for this project doesn't use encrypted values to be decrypted using a vault file, otherwise an error will be thrown). |
--ctl | Runs only the Controller Preparation Stepā and generates the Controller Output Varsā . Usiful to generate the variables that will be used in a demo that doesn't need the controller layer, like the official demoā . |
--debug | Runs in verbose mode and forwards this option to the subsequent step. |
--migration | Runs with the project migration parameter set as the value specified in this parameter. This value overrides the migration value specified for the project in the vars.yml file in the Main Environment Repositoryā (when both are specified). This parameter is useful to make sure that an automated process deploy the project only if this value is the same as the one specified for the environment. This is also useful to make sure that a migration that must run manually doesn't run automatically (the automatic process would fail in the preparation step, because the migration value is different from the one specified in the environment file, then you can run manually specifying this parameter explicitly when launching the project). |
-w--new-pass | Clears the project secrets directory (the directory that stores the passphrase used to decrypt the project variables at the main environment repository, which is asked right after deploying the project for the first time). It can be useful |
Content type
Image
Digest
sha256:b6210ac4dā¦
Size
247.8 MB
Last updated
about 4 years ago
docker pull lucasbasquerotto/ctl:20220727