From 0e71ccc6ad2bd3d80e500ba5f0b06f01dbd68bc0 Mon Sep 17 00:00:00 2001 From: Luke Kysow Date: Mon, 25 Jun 2018 17:12:57 +0100 Subject: [PATCH] Finish docs --- runatlantis.io/.vuepress/config.js | 5 +- runatlantis.io/docs/README.md | 2 + runatlantis.io/docs/apply-requirements.md | 17 ++ .../docs/atlantis-yaml-reference.md | 203 +++++++++++--- runatlantis.io/docs/autoplanning.md | 19 ++ runatlantis.io/docs/security.md | 7 + runatlantis.io/docs/server-configuration.md | 7 - .../guide/atlantis-yaml-use-cases.md | 251 ++++++++++++++++++ runatlantis.io/guide/requirements.md | 8 +- 9 files changed, 467 insertions(+), 52 deletions(-) create mode 100644 runatlantis.io/docs/apply-requirements.md create mode 100644 runatlantis.io/docs/autoplanning.md create mode 100644 runatlantis.io/guide/atlantis-yaml-use-cases.md diff --git a/runatlantis.io/.vuepress/config.js b/runatlantis.io/.vuepress/config.js index 34fd2d09e..ba8a6ce8e 100644 --- a/runatlantis.io/.vuepress/config.js +++ b/runatlantis.io/.vuepress/config.js @@ -36,7 +36,9 @@ module.exports = { 'pull-request-commands', 'deployment', 'server-configuration', + 'apply-requirements', 'locking', + 'autoplanning', ['atlantis-yaml-reference', 'atlantis.yaml Reference'], 'security', 'faq', @@ -45,7 +47,8 @@ module.exports = { '', 'test-drive', 'getting-started', - 'requirements' + 'requirements', + 'atlantis-yaml-use-cases' ] }, repo: 'runatlantis/atlantis', diff --git a/runatlantis.io/docs/README.md b/runatlantis.io/docs/README.md index b55f19a23..90952633b 100644 --- a/runatlantis.io/docs/README.md +++ b/runatlantis.io/docs/README.md @@ -4,7 +4,9 @@ This documentation is divided into sections: * [Pull Request Commands](pull-request-commands.html) - the commands that Atlantis supports via pull request comments. * [Production-Ready Deployment](deployment.html) - how to deploy Atlantis. * [Server Configuration](server-configuration.html) - how to configure the Atlantis server. +* [Apply Requirements](apply-requirements.html) - what requirements can be set before `atlantis apply` is allowed. * [Locking](locking.html) - how and why Atlantis does locking. +* [Autoplanning](autoplanning.html) - how Atlantis runs plan automatically. * [`atlantis.yaml` Reference](atlantis-yaml-reference) - reference docs for the `atlantis.yaml` configuration file. * [Security](security.html) - what you need to think about in terms of security for Atlantis. * [FAQ](faq.html) - Frequently asked questions. diff --git a/runatlantis.io/docs/apply-requirements.md b/runatlantis.io/docs/apply-requirements.md new file mode 100644 index 000000000..34a304848 --- /dev/null +++ b/runatlantis.io/docs/apply-requirements.md @@ -0,0 +1,17 @@ +# Apply Requirements + +## Approved +If you'd like to require pull/merge requests to be approved prior to a user running `atlantis apply` simply run Atlantis with the `--require-approval` flag. +By default, no approval is required. If you want to configure this on a per-repo/project basis, for example to only require approvals for your production +configuration you must use an `atlantis.yaml` file: +```yaml +version: 2 +projects: +- dir: . + apply_requirements: [approved] +``` + +## Next Steps +For more information on GitHub pull request reviews and approvals see: [https://help.github.com/articles/about-pull-request-reviews/](https://help.github.com/articles/about-pull-request-reviews/) + +For more information on GitLab merge request reviews and approvals (only supported on GitLab Enterprise) see: [https://docs.gitlab.com/ee/user/project/merge_requests/merge_request_approvals.html](https://docs.gitlab.com/ee/user/project/merge_requests/merge_request_approvals.html). \ No newline at end of file diff --git a/runatlantis.io/docs/atlantis-yaml-reference.md b/runatlantis.io/docs/atlantis-yaml-reference.md index 63f36752e..029b67e29 100644 --- a/runatlantis.io/docs/atlantis-yaml-reference.md +++ b/runatlantis.io/docs/atlantis-yaml-reference.md @@ -1,45 +1,168 @@ -# Customization -An `atlantis.yaml` config file in your project root (which is not necessarily the repo root) can be used to customize -- what commands Atlantis runs **before** `init`, `get`, `plan` and `apply` with `pre_init`, `pre_get`, `pre_plan` and `pre_apply` -- what commands Atlantis runs **after** `plan` and `apply` with `post_plan` and `post_apply` -- additional arguments to be supplied to specific terraform commands with `extra_arguments` - - the commmands that we support adding extra args to are `init`, `get`, `plan` and `apply` -- what version of Terraform to use (see [Terraform Versions](#terraform-versions)) +# atlantis.yaml Reference +[[toc]] -The schema of the `atlantis.yaml` project config file is +::: tip +`atlantis.yaml` files are only required if you wish to customize some aspect of Atlantis. +::: +## Example Using All Keys ```yaml -# atlantis.yaml ---- -terraform_version: 0.8.8 # optional version -# pre_init commands are run when the Terraform version is >= 0.9.0 -pre_init: - commands: - - "curl http://example.com" -# pre_get commands are run when the Terraform version is < 0.9.0 -pre_get: - commands: - - "curl http://example.com" -pre_plan: - commands: - - "curl http://example.com" -post_plan: - commands: - - "curl http://example.com" -pre_apply: - commands: - - "curl http://example.com" -post_apply: - commands: - - "curl http://example.com" -extra_arguments: - - command_name: plan - arguments: - - "-var-file=terraform.tfvars" +version: 2 +projects: +- name: my-project-name + dir: . + workspace: default + terraform_version: v0.11.0 + autoplan: + when_modified: ["*.tf", "../modules/**.tf"] + enabled: true + apply_requirements: [approved] + workflow: myworkflow +workflows: + myworkflow: + plan: + steps: + - run: my-custom-command arg1 arg2 + - init + - plan: + extra_args: ["-lock", "false"] + - run: my-custom-command arg1 arg2 + apply: + steps: + - run: echo hi + - apply ``` -When running the `pre_plan`, `post_plan`, `pre_apply`, and `post_apply` commands the following environment variables are available -- `WORKSPACE`: if a workspace argument is supplied to `atlantis plan` or `atlantis apply`, ex `atlantis plan -w staging`, this will -be the value of that argument. Else it will be `default` -- `ATLANTIS_TERRAFORM_VERSION`: local version of `terraform` or the version from `terraform_version` if specified, ex. `0.8.8` -- `DIR`: absolute path to the root of the project on disk \ No newline at end of file +## Usage Notes +* `atlantis.yaml` files must be placed at the root of the repo +* The only supported name is `atlantis.yaml`. Not `atlantis.yml` or `.atlantis.yaml`. +* Once an `atlantis.yaml` file exists in a repo Atlantis will not automatically plan +any other projects. This means if you have multiple projects in the same repo, once +you add an `atlantis.yaml` you'll need to add entries for each project. +* Atlantis uses the `atlantis.yaml` version from the pull request. + +## Security +`atlantis.yaml` files allow users to run arbitrary code on the Atlantis server. +This is obviously extremely powerful and dangerous since the Atlantis server will +likely hold your highest privilege credentials. + +The risk is increased because Atlantis uses the `atlantis.yaml` file from the +pull request so anyone that can submit a pull request can submit a malicious file. + +As such, **`atlantis.yaml` files should only be enabled in a trusted environment**. + +::: danger +It should be noted that `atlantis apply` itself could be exploited if run on a malicious file. See [Security](security.html#exploits). +::: + +## Reference +### Top-Level Keys +```yaml +version: +projects: +workflows: +``` +| Key | Type | Default | Required | Description | +| -------------| --- |-------------| -----|---| +| version | int | none | yes | This key is required and must be set to `2`| +| projects | array[[Project](atlantis-yaml-reference.html#project)] | [] | no | Lists the projects in this repo | +| workflows | map string -> [Workflow](atlantis-yaml-reference.html#workflow) | {} | no | Custom workflows | + +### Project +```yaml +name: myname +dir: mydir +workspace: myworkspace +autoplan: +terraform_version: 0.11.0 +apply_requirements: ["approved"] +workflow: myworkflow +``` + +| Key | Type | Default | Required | Description | +| -------------| --- |-------------| -----|---| +| name | string | none | maybe | Required if there is more than one project with the same `dir` and `workspace`. This project name can be used with the `-p` flag.| +| dir | string | none | yes | The directory of this project relative to the repo root. Use `.` for the root. For example if the project was under `./project1` then use `project1`| +| workspace | string| default | no | The [Terraform workspace](https://www.terraform.io/docs/state/workspaces.html) for this project. Atlantis will switch to this workplace when planning/applying and will create it if it doesn't exist.| +| autoplan | [Autoplan](atlantis-yaml-reference.html#autoplan) | none | no | A custom autoplan configuration. If not specified, will use the default algorithm. See [Autoplanning](autoplanning.html).| +| terraform_version | string | none | no | A specific Terraform version to use when running commands for this project. Requires there to be a binary in the Atlantis `PATH` with the name `terraform{VERSION}`, ex. `terraform0.11.0`| +| apply_requirements | array[string] | [] | no | Requirements that must be satisfied before `atlantis apply` can be run. Currently the only supported requirement is `approved`. See [Apply Requirements](apply-requirements.html#approved) for more details.| +| workflow | string | none | no | A custom workflow. If not specified, Atlantis will use its default workflow.| + +::: tip +A project represents a Terraform state. Typically, there is one state per directory and workspace however it's possible to +have multiple states in the same directory using `terraform init -backend-config=custom-config.tfvars`. +Atlantis supports this but requires the `name` key to be specified. See [atlantis.yaml Use Cases](../guide/atlantis-yaml-use-cases.html#custom-backend-config) for more details. +::: + +### Autoplan +```yaml +enabled: true +when_modified: ["*.tf"] +``` +| Key | Type | Default | Required | Description | +| -------------| --- |-------------| -----|---| +| enabled | boolean | true | no | Whether autoplanning is enabled for this project. | +| when_modified | array[string] | no | no | Uses [.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file) syntax. If any modified file in the pull request matches, this project will be planned. If not specified, Atlantis will use its own algorithm. See [Autoplanning](autoplanning.html). Paths are relative to the project's dir.| + +### Workflow +```yaml +plan: +apply: +``` + +| Key | Type | Default | Required | Description | +| -------------| --- |-------------| -----|---| +| plan | [Stage](atlantis-yaml-reference.html#stage) | `steps: [init, plan]` | no | How to plan for this project. | +| apply | [Stage](atlantis-yaml-reference.html#stage) | `steps: [apply]` | no | How to apply for this project. | + +### Stage +```yaml +steps: +- run: custom-command +- init +- plan: + extra_args: [-lock=false] +``` + +| Key | Type | Default | Required | Description | +| -------------| --- |-------------| -----|---| +| steps | array[[Step](atlantis-yaml-reference.html#step)] | `[]` | no | List of steps for this stage. If the steps key is empty, no steps will be run for this stage. | + +### Step +#### Built-In Command +Steps can be a single string for a built-in command. +```yaml +- init +- plan +- apply +``` +| Key | Type | Default | Required | Description | +| -------------| --- |-------------| -----|---| +| init/plan/apply | string | none | no | Use a built-in command without additional configuration. Only `init`, `plan` and `apply` are supported|| + +#### Built-In Command With Extra Args +A map from string to `extra_args` for a built-in command with extra arguments. +```yaml +- init: + extra_args: [arg1, arg2] +- plan: + extra_args: [arg1, arg2] +- apply: + extra_args: [arg1, arg2] +``` +| Key | Type | Default | Required | Description | +| -------------| --- |-------------| -----|---| +| init/plan/apply | map `extra_args` -> array[string] | none | no | Use a built-in command and append `extra_args`. Only `init`, `plan` and `apply` are supported as keys and only `extra_args` is supported as a value|| +#### Custom Command +Or a custom command +```yaml +- run: custom-command +``` +| Key | Type | Default | Required | Description | +| -------------| --- |-------------| -----|---| +| run | string| "" | no | Run a custom command| + +## Next Steps +Check out the [atlantis.yaml Use Cases](../guide/atlantis-yaml-use-cases.html) for +some real world examples. diff --git a/runatlantis.io/docs/autoplanning.md b/runatlantis.io/docs/autoplanning.md new file mode 100644 index 000000000..92480e099 --- /dev/null +++ b/runatlantis.io/docs/autoplanning.md @@ -0,0 +1,19 @@ +# Autoplanning +On any **new** pull request or **new commit** to an existing pull request, Atlantis will attempt to +run `terraform plan` in the directories it thinks hold modified Terraform projects. + +The algorithm it uses is as follows: +1. Get list of all modified files in pull request +1. Filter to those containing `.tf` +1. Get the directories that those files are in +1. If the directory path doesn't contain `modules/` then try to run `plan` in that directory +1. If it does contain `modules/` look at the directory one level above `modules/`. If it +contains a `main.tf` run plan in that directory, otherwise ignore the change. + +todo: add example + +If you would like to configure how Atlantis determines which directory to run in +or disable it all together you need to create an `atlantis.yaml` file. +See +* Disabling Autoplanning +* Configur diff --git a/runatlantis.io/docs/security.md b/runatlantis.io/docs/security.md index 6f66886b3..b26da1e6c 100644 --- a/runatlantis.io/docs/security.md +++ b/runatlantis.io/docs/security.md @@ -1,4 +1,6 @@ # Security +[[toc]] +## Exploits Because you usually run Atlantis on a server with credentials that allow access to your infrastructure it's important that you deploy Atlantis securely. Atlantis could be exploited by @@ -35,3 +37,8 @@ This flag ensures your Atlantis install isn't being used with repositories you d Atlantis should be run with Webhook secrets set via the `$ATLANTIS_GH_WEBHOOK_SECRET`/`$ATLANTIS_GITLAB_WEBHOOK_SECRET` environment variables. Even with the `--repo-whitelist` flag set, without a webhook secret, attackers could make requests to Atlantis posing as a repository that is whitelisted. Webhook secrets ensure that the webhook requests are actually coming from your VCS provider (GitHub or GitLab). + +### SSL/HTTPS +If you're using webhook secrets but your traffic is over HTTP then the webhook secrets +could be stolen. Enable SSL/HTTPS using the `--ssl-cert-file` and `--ssl-key-file` +flags. diff --git a/runatlantis.io/docs/server-configuration.md b/runatlantis.io/docs/server-configuration.md index e5c68ca01..27d1f94de 100644 --- a/runatlantis.io/docs/server-configuration.md +++ b/runatlantis.io/docs/server-configuration.md @@ -90,10 +90,3 @@ able to use `session_name = "${var.atlantis_user}"`. However, the backend assume role is only used for state-related API actions. Any other API actions will be performed using the assumed role specified in the `aws` provider and will have the session named as the GitHub user. -## Approvals -If you'd like to require pull/merge requests to be approved prior to a user running `atlantis apply` simply run Atlantis with the `--require-approval` flag. -By default, no approval is required. - -For more information on GitHub pull request reviews and approvals see: [https://help.github.com/articles/about-pull-request-reviews/](https://help.github.com/articles/about-pull-request-reviews/) - -For more information on GitLab merge request reviews and approvals (only supported on GitLab Enterprise) see: [https://docs.gitlab.com/ee/user/project/merge_requests/merge_request_approvals.html](https://docs.gitlab.com/ee/user/project/merge_requests/merge_request_approvals.html). \ No newline at end of file diff --git a/runatlantis.io/guide/atlantis-yaml-use-cases.md b/runatlantis.io/guide/atlantis-yaml-use-cases.md new file mode 100644 index 000000000..f01da6fc3 --- /dev/null +++ b/runatlantis.io/guide/atlantis-yaml-use-cases.md @@ -0,0 +1,251 @@ +# atlantis.yaml Use Cases + +An `atlantis.yaml` file can be placed in the root of each repository to configure +how Atlantis runs. This documentation describes some use cases. + +::: tip +Looking for the full atlantis.yaml reference? See [atlantis.yaml Reference](../docs/atlantis-yaml-reference.html). +::: + +[[toc]] + +## Disabling Autoplanning +```yaml +version: 2 +projects: +- dir: project1 + autoplan: + enabled: false +``` +This will stop Atlantis automatically running plan when `project1/` is updated +in a pull request. + +## Configuring Autoplanning +Given the directory structure: +``` +. +├── modules +│   └── module1 +│   ├── main.tf +│   ├── outputs.tf +│   └── submodule +│   ├── main.tf +│   └── outputs.tf +└── project1 + └── main.tf +``` +If you wanted Atlantis to autoplan `project1/` whenever any `.tf` file under `module1/` +changed, you could use the following configuration: + +```yaml +version: 2 +projects: +- dir: project1 + autoplan: + when_modified: ["../modules/**/*.tf", "*.tf"] +``` +Note: +* `when_modified` uses the [`.dockerignore` syntax](https://docs.docker.com/engine/reference/builder/#dockerignore-file) +* The paths are relative to the project's directory. + +## Supporting Terraform Workspaces +```yaml +version: 2 +projects: +- dir: project1 + workspace: staging +- dir: project1 + workspace: production +``` +With the above config, when Atlantis determines that the configuration for the `project1` dir has changed, +it will run plan for both the `staging` and `production` workspaces. + +If you want to `plan` or `apply` for a specific workspace you can use +``` +atlantis plan -w staging -d project1 +``` +and +``` +atlantis apply -w staging -d project1 +``` + +## Using .tfvars files +Given the structure: +``` +. +└── project1 + ├── main.tf + ├── production.tfvars + └── staging.tfvars +``` + +If you wanted Atlantis to automatically run plan with `-var-file staging.tfvars` and `-var-file production.tfvars` +you could use the following config: + +```yaml +version: 2 +projects: +# If two or more projects have the same dir and workspace, they must also have +# a 'name' key to differentiate them. +- name: project1-staging + dir: project1 + # NOTE: the key here is 'workflow' not 'workspace' + workflow: staging +- name: project1-production + dir: project1 + workflow: production + +workflows: + staging: + plan: + steps: + - init + - plan: + extra_args: ["-var-file", "staging.tfvars"] + production: + plan: + steps: + - init + - plan: + extra_args: ["-var-file", "production.tfvars"] +``` +Here we're defining two projects with the same directory but with different +`workflow`s. + +If you wanted to manually plan one of these projects you could use +``` +atlantis plan -p project1-staging +``` +Where `-p` refers to the project name. + +When you want to apply the plan, you can run +``` +atlantis apply -p project1-staging +``` + +::: warning Why can't you use atlantis apply -d project1? +Because Atlantis outputs the plan for both workflows into the `project1` directory +so it needs a way to differentiate between the plans. +::: + +## Adding extra arguments to Terraform commands +If you need to append flags to `terraform plan` or `apply` temporarily, you can +append flags on a comment following `--`, for example commenting: +``` +atlantis plan -- -lock=false +``` +Would cause atlantis to run `terraform plan -lock=false`. + +If you always need to do this for a project's `init`, `plan` or `apply` commands +then you must define the project's steps and set the `extra_args` key for the +command you need to modify. + +```yaml +version: 2 +projects: +- dir: project1 + workflow: myworkflow +workflows: + myworkflow: + plan: + steps: + - init: + extra_args: ["-lock=false"] + - plan: + extra_args: ["-lock=false"] + apply: + steps: + - apply: + extra_args: ["-lock=false"] +``` + +## Running custom commands +Atlantis supports running custom commands. In this example, we want to run +a script after every `apply`: + +```yaml +version: 2 +projects: +- dir: project1 + workflow: myworkflow +workflows: + myworkflow: + apply: + steps: + - apply + - run: ./my-custom-script.sh +``` + +::: tip +Note how we're not specifying the `plan` key under `myworkflow`. If the `plan` key +isn't set, Atlantis will use the default plan workflow which is what we want in this case. +::: + +## Terraform Versions +If you'd like to use a different version of Terraform than what is in Atlantis' +`PATH` then set the `terraform_version` key: + +```yaml +version: 2 +projects: +- dir: project1 + terraform_version: 0.10.0 +``` + +Atlantis will then execute all Terraform commands with `terraform0.10.0` instead +of `terraform`. This requires that the 0.10.0 binary is in Atlantis's `PATH` with the +name `terraform0.10.0`. + +## Requiring Approvals For Production +In this example, we only want to require `apply` approvals for the `production` directory. +```yaml +version: 2 +projects: +- dir: staging +- dir: production + apply_requirements: [approved] +``` +:::tip +By default, there are no apply requirements so we only need to specify the `apply_requirements` key for production. +::: + + +## Custom Backend Config +If you need to specify the `-backend-config` flag to `terraform init` you'll need to use an `atlantis.yaml` file. +In this example, we're using custom backend files to configure two remote states, one for each environment. +We're then using `.tfvars` files to load different variables for each environment. + +```yaml +version: 2 +projects: +- name: staging + dir: . + workflow: staging +- name: production + dir: . + workflow: production +workflows: + staging: + plan: + steps: + - rm -rf .terraform + - init: + extra_args: [-backend-config=staging.backend.tfvars] + - plan: + extra_args: [-var-file=staging.tfvars] + production: + plan: + steps: + - rm -rf .terraform + - init: + extra_args: [-backend-config=production.backend.tfvars] + - plan: + extra_args: [-var-file=production.tfvars] +``` +::: warning NOTE +We have to use a custom `run` step to `rm -rf .terraform` because otherwise Terraform +will complain in-between commands since the backend config has changed. +::: + +## Next Steps +Check out the full [`atlantis.yaml` Reference](../docs/atlantis-yaml-reference.html) for more details. \ No newline at end of file diff --git a/runatlantis.io/guide/requirements.md b/runatlantis.io/guide/requirements.md index 2edf50c49..0681a0b93 100644 --- a/runatlantis.io/guide/requirements.md +++ b/runatlantis.io/guide/requirements.md @@ -46,7 +46,7 @@ Atlantis supports any Terraform project structures, for example: └── ... ``` With modules, if you want `project1` automatically planned when `module1` is modified -you need to create an `atlantis.yaml` file. See [atlantis.yaml Reference](../docs/atlantis-yaml-reference.html) for more details. +you need to create an `atlantis.yaml` file. See [atlantis.yaml Use Cases](atlantis-yaml-use-cases.html#configuring-autoplanning) for more details. ### Terraform Workspaces ::: tip @@ -54,7 +54,7 @@ See [Terraform's docs](https://www.terraform.io/docs/state/workspaces.html) if y ::: If you're using a Terraform version >= 0.9.0, Atlantis supports workspaces through an `atlantis.yaml` file that tells Atlantis the names of your workspaces -(see [atlantis.yaml Reference](../docs/atlantis-yaml-reference.html) for more details) +(see [atlantis.yaml Use Cases](atlantis-yaml-use-cases.html#supporting-terraform-workspaces) for more details) or through the `-w` flag. For example: ``` atlantis plan -w staging @@ -71,7 +71,7 @@ atlantis apply -w staging ``` For Atlantis to be able to plan automatically with `.tfvars files`, you need to create an `atlantis.yaml` file to tell it to use `-var-file={YOUR_FILE}`. -See [atlantis.yaml Reference](../docs/atlantis-yaml-reference.html) for more details. +See [atlantis.yaml Use Cases](atlantis-yaml-use-cases.html#using-tfvars-files) for more details. ## Terraform Versions By default, Atlantis will use the `terraform` executable that is in its path. @@ -79,7 +79,7 @@ To use a specific version of Terraform: 1. Install the desired version of Terraform into the `$PATH` of where Atlantis is running and name it `terraform{version}`, ex. `terraform0.8.8`. 2. Create an `atlantis.yaml` file for your repo and set the `terraform_version` key. -See [atlantis.yaml Reference](../docs/atlantis-yaml-reference.html) for more details. +See [atlantis.yaml Use Cases](atlantis-yaml-use-cases.html#terraform-versions) for more details. ## Next Steps Check out our [full documentation](../docs/).