From 37e2ab85a8df01e19234b53bfea3644478b2dbb7 Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 4 Jan 2019 15:53:43 -0500 Subject: [PATCH] Reorganize docs. Also add a build step that checks the Netlify deploy preview for broken links. --- .circleci/config.yml | 16 + runatlantis.io/.vuepress/config.js | 59 ++- runatlantis.io/.vuepress/style.styl | 4 + runatlantis.io/docs/README.md | 26 +- runatlantis.io/docs/access-credentials.md | 46 ++ runatlantis.io/docs/configuring-webhooks.md | 88 ++++ runatlantis.io/docs/customizing-atlantis.md | 7 + runatlantis.io/docs/deployment.md | 481 ++++++++---------- runatlantis.io/docs/how-atlantis-works.md | 5 + .../docs/images/example-comment.png | Bin 0 -> 81105 bytes runatlantis.io/docs/installation-guide.md | 13 + .../{guide => docs}/requirements.md | 25 +- runatlantis.io/docs/server-configuration.md | 19 + ...-request-commands.md => using-atlantis.md} | 6 +- runatlantis.io/docs/webhook-secrets.md | 30 ++ runatlantis.io/guide/README.md | 2 +- runatlantis.io/guide/getting-started.md | 2 +- 17 files changed, 525 insertions(+), 304 deletions(-) create mode 100644 runatlantis.io/docs/access-credentials.md create mode 100644 runatlantis.io/docs/configuring-webhooks.md create mode 100644 runatlantis.io/docs/customizing-atlantis.md create mode 100644 runatlantis.io/docs/how-atlantis-works.md create mode 100644 runatlantis.io/docs/images/example-comment.png create mode 100644 runatlantis.io/docs/installation-guide.md rename runatlantis.io/{guide => docs}/requirements.md (65%) rename runatlantis.io/docs/{pull-request-commands.md => using-atlantis.md} (95%) create mode 100644 runatlantis.io/docs/webhook-secrets.md diff --git a/.circleci/config.yml b/.circleci/config.yml index edb590a88..8871419be 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,6 +24,18 @@ jobs: # We don't run e2e tests on fork PRs because they don't have access to the secret env vars. - run: if [ -z "${CIRCLE_PR_REPONAME}" ]; then ./scripts/e2e.sh; fi + # Check the website that this PR creates for broken links. + website_link_check: + docker: + - image: lkysow/netlify-broken-link-checker:latest + environment: + GITHUB_ORG: runatlantis + GITHUB_REPO: atlantis + MUFFET_ARGS: '-e https://github\.com/runatlantis/atlantis/edit/master/.* -e https://github.com/helm/charts/tree/master/stable/atlantis#customization' + DELAY_SECONDS: 30 + steps: + - run: check-links + # Build and push 'latest' Docker tag. docker_master: working_directory: /go/src/github.com/runatlantis/atlantis @@ -77,6 +89,10 @@ workflows: filters: branches: ignore: /.*-docs/ + - website_link_check: + filters: + branches: + ignore: master - docker_master: requires: [e2e] filters: diff --git a/runatlantis.io/.vuepress/config.js b/runatlantis.io/.vuepress/config.js index ee81209ad..ed5477542 100644 --- a/runatlantis.io/.vuepress/config.js +++ b/runatlantis.io/.vuepress/config.js @@ -34,29 +34,58 @@ module.exports = { {text: 'Blog', link: 'https://medium.com/runatlantis'} ], sidebar: { - '/docs/': [ - '', - 'pull-request-commands', - 'deployment', - 'server-configuration', - 'apply-requirements', - 'locking', - 'autoplanning', - ['atlantis-yaml-reference', 'atlantis.yaml Reference'], - 'upgrading-atlantis-yaml-to-version-2', - 'security', - 'faq', - ], '/guide/': [ '', 'test-drive', 'getting-started', - 'requirements', 'atlantis-yaml-use-cases' + ], + '/docs/': [ + ['', 'Overview'], + { + title: 'Installing Atlantis', + collapsable: true, + children: [ + 'installation-guide', + 'requirements', + 'access-credentials', + 'webhook-secrets', + 'deployment', + 'configuring-webhooks', + 'server-configuration', + 'security' + ] + }, + { + title: 'Using Atlantis', + collapsable: true, + children: [ + ['using-atlantis', 'Overview'] + ] + }, + { + title: 'Customizing Atlantis', + collapsable: true, + children: [ + ['customizing-atlantis', 'Overview'], + 'atlantis-yaml-reference', + 'upgrading-atlantis-yaml-to-version-2', + 'apply-requirements' + ] + }, + { + title: 'How Atlantis Works', + collapsable: true, + children: [ + ['how-atlantis-works', 'Overview'], + 'locking', + 'autoplanning' + ] + } ] }, repo: 'runatlantis/atlantis', docsDir: 'runatlantis.io', editLinks: true, } -} \ No newline at end of file +} diff --git a/runatlantis.io/.vuepress/style.styl b/runatlantis.io/.vuepress/style.styl index f0fd8e7bc..ed600df81 100644 --- a/runatlantis.io/.vuepress/style.styl +++ b/runatlantis.io/.vuepress/style.styl @@ -32,3 +32,7 @@ } } } + +.sidebar-heading { + font-size: inherit +} diff --git a/runatlantis.io/docs/README.md b/runatlantis.io/docs/README.md index da4d83c95..215e12758 100644 --- a/runatlantis.io/docs/README.md +++ b/runatlantis.io/docs/README.md @@ -1,18 +1,14 @@ -# Overview - -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.html) - 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. - - - +# Atlantis Documentation +These docs are for users that are ready to get Atlantis installed and start using it. +:::tip Looking to get started? +If you're new here, check out the [Guide](/guide/) +where you can try our [Test Drive](/guide/test-drive.html) or [Run Atlantis Locally](/guide/getting-started.html). +::: +### Next Steps +* [Installing Atlantis](/docs/installation-guide.html)  –  Get Atlantis up and running +* [Using Atlantis](using-atlantis.html)  –  How do I use Atlantis to run Terraform +* [Customizing Atlantis](customizing-atlantis.html)  –  Modify how Atlantis works for my use case +* [How Atlantis Works](how-atlantis-works.html)  –  Internals of what Atlantis is doing diff --git a/runatlantis.io/docs/access-credentials.md b/runatlantis.io/docs/access-credentials.md new file mode 100644 index 000000000..0e5d3203d --- /dev/null +++ b/runatlantis.io/docs/access-credentials.md @@ -0,0 +1,46 @@ +# Git Host Access Credentials +This doc describes how to create credentials on your Git host (GitHub, GitLab or Bitbucket) +that Atlantis will use to make API calls. +[[toc]] + +## Create an Atlantis user (optional) +We recommend creating a new user named **@atlantis** (or something close) or using a dedicated CI user. + +This isn't required (you can use an existing user), however all the comments that Atlantis writes +will come from that user so it might be confusing if its coming from a personal account. + +![Example Comment](./images/example-comment.png) +

An example comment coming from the @atlantisbot user

+ +## Generating an Access Token +Once you've created a new user (or decided to use an existing one), you need to +generate an access token. Read on for the instructions for your Git host. + +### Create a GitHub Token +**NOTE: The Atlantis user must have "Write permissions" (for repos in an organization) or be a "Collaborator" (for repos in a user account) to be able to set commit statuses:** +![Atlantis status](./images/status.png) +- create a Personal Access Token by following [https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/#creating-a-token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/#creating-a-token) +- create the token with **repo** scope +- record the access token + +### Create a GitLab Token +- follow [https://docs.gitlab.com/ce/user/profile/personal_access_tokens.html#creating-a-personal-access-token](https://docs.gitlab.com/ce/user/profile/personal_access_tokens.html#creating-a-personal-access-token) +- create a token with **api** scope +- record the access token + +### Create a Bitbucket Cloud (bitbucket.org) App Password +- create an App Password by following [https://confluence.atlassian.com/bitbucket/app-passwords-828781300.html#Apppasswords-Createanapppassword](https://confluence.atlassian.com/bitbucket/app-passwords-828781300.html#Apppasswords-Createanapppassword) +- Label the password "atlantis" +- Select **Pull requests**: **Read** and **Write** so that Atlantis can read your pull requests and write comments to them +- record the access token + +### Create a Bitbucket Server (aka Stash) Personal Access Token +- Click on your avatar in the top right and select **Manage account** +- Click **Personal access tokens** in the sidebar +- Click **Create a token** +- Name the token **atlantis** +- Give the token **Read** Project permissions and **Write** Pull request permissions +- Click **Create** and record the access token + +## Next Steps +Once you've got your user and access token, you're ready to create a webhook secret. See [Creating a Webhook Secret](webhook-secrets.html). diff --git a/runatlantis.io/docs/configuring-webhooks.md b/runatlantis.io/docs/configuring-webhooks.md new file mode 100644 index 000000000..8de7d1138 --- /dev/null +++ b/runatlantis.io/docs/configuring-webhooks.md @@ -0,0 +1,88 @@ +# Configuring Webhooks +Atlantis needs to receive Webhooks from your Git host so that it can respond to pull request events. + +:::tip Pre-Requisites +* You have created an [access credential](access-credentials.html) +* You have created a [webhook secret](webhook-secrets.html) +* You have [deployed](deployment.html) Atlantis and have a url for it +::: + +See the instructions for your specific provider below. +[[toc]] + +## GitHub/GitHub Enterprise Webhook +You can install your webhook at the organization level, or for each repository. + +If only some of the repos in your organization are to be managed by Atlantis, then you +may want to only install on specific repos for now. + +::: tip +If you're not sure if you have a GitHub organization see [https://help.github.com/articles/differences-between-user-and-organization-accounts/](https://help.github.com/articles/differences-between-user-and-organization-accounts/) +::: + +If you're installing on the organization, navigate to your organization's page and click **Settings**. +If installing on a single repository, navigate to the repository home page and click **Settings**. +- Select **Webhooks** or **Hooks** in the sidebar +- Click **Add webhook** +- set **Payload URL** to `http://$URL/events` (or `https://$URL/events` if you're using SSL) where `$URL` is where Atlantis is hosted. **Be sure to add `/events`** +- double-check you added `/events` to the end of your URL. +- set **Content type** to `application/json` +- set **Secret** to the Webhook Secret you generated previously + - **NOTE** If you're adding a webhook to multiple repositories, each repository will need to use the **same** secret. +- select **Let me select individual events** +- check the boxes + - **Pull request reviews** + - **Pushes** + - **Issue comments** + - **Pull requests** +- leave **Active** checked +- click **Add webhook** + +## GitLab Webhook +If you're using GitLab, navigate to your project's home page in GitLab +- Click **Settings > Integrations** in the sidebar +- set **URL** to `http://$URL/events` (or `https://$URL/events` if you're using SSL) where `$URL` is where Atlantis is hosted. **Be sure to add `/events`** +- double-check you added `/events` to the end of your URL. +- set **Secret Token** to the Webhook Secret you generated previously + - **NOTE** If you're adding a webhook to multiple repositories, each repository will need to use the **same** secret. +- check the boxes + - **Push events** + - **Comments** + - **Merge Request events** +- leave **Enable SSL verification** checked +- click **Add webhook** + +## Bitbucket Cloud (bitbucket.org) Webhook +- Go to your repo's home page +- Click **Settings** in the sidebar +- Click **Webhooks** under the **WORKFLOW** section +- Click **Add webhook** +- Enter "Atlantis" for **Title** +- set **URL** to `http://$URL/events` (or `https://$URL/events` if you're using SSL) where `$URL` is where Atlantis is hosted. **Be sure to add `/events`** +- double-check you added `/events` to the end of your URL. +- Keep **Status** as Active +- Don't check **Skip certificate validation** because NGROK has a valid cert. +- Select **Choose from a full list of triggers** +- Under **Repository** **un**check everything +- Under **Issues** leave everything **un**checked +- Under **Pull Request**, select: Created, Updated, Merged, Declined and Comment created +- Click **Save** +Bitbucket Webhook + +## Bitbucket Server (aka Stash) Webhook +- Go to your repo's home page +- Click **Settings** in the sidebar +- Click **Webhooks** under the **WORKFLOW** section +- Click **Create webhook** +- Enter "Atlantis" for **Name** +- set **URL** to `http://$URL/events` (or `https://$URL/events` if you're using SSL) where `$URL` is where Atlantis is hosted. **Be sure to add `/events`** +- Double-check you added `/events` to the end of your URL. +- Set **Secret** to the Webhook Secret you generated previously + - **NOTE** If you're adding a webhook to multiple repositories, each repository will need to use the **same** secret. +- Under **Repository** select **Push** +- Under **Pull Request**, select: Opened, Modified, Merged, Declined, Deleted and Comment added +- Click **Save**Bitbucket Webhook + +## Next Steps +* Now you're finally ready to use Atlantis! Open up a Terraform pull request + and you should see Atlantis respond. diff --git a/runatlantis.io/docs/customizing-atlantis.md b/runatlantis.io/docs/customizing-atlantis.md new file mode 100644 index 000000000..d7f6cf0cb --- /dev/null +++ b/runatlantis.io/docs/customizing-atlantis.md @@ -0,0 +1,7 @@ +# Customizing Atlantis + +How Atlantis exactly operates for each repo can be customized via an +`atlantis.yaml` file placed at the root of each repo. + +* Read about the possible [use cases](/guide/atlantis-yaml-use-cases.html) +* Check out the [atlantis.yaml reference](atlantis-yaml-reference.html) diff --git a/runatlantis.io/docs/deployment.md b/runatlantis.io/docs/deployment.md index de06315dc..982ceb86a 100644 --- a/runatlantis.io/docs/deployment.md +++ b/runatlantis.io/docs/deployment.md @@ -1,255 +1,86 @@ -# Production-Ready Deployment -[[toc]] +# Deployment +This doc covers getting Atlantis up and running in your infrastructure. -## Install Terraform -`terraform` needs to be in the `$PATH` for Atlantis. -Download from https://www.terraform.io/downloads.html -```bash -unzip path/to/terraform_*.zip -d /usr/local/bin -``` -Check that it's in your `$PATH` -``` -$ terraform version -Terraform v0.10.0 -``` -If you want to use a different version of Terraform see [Terraform Versions](#terraform-versions) - -## Hosting Atlantis -Atlantis needs to be hosted somewhere that github.com/gitlab.com/bitbucket.org or your GitHub/GitLab Enterprise installation can reach. -Developers in your organization also need to be able to access Atlantis to view the UI and to delete locks. - -By default Atlantis runs on port `4141`. This can be changed with the `--port` flag. - -## Install Atlantis -Get the latest release from [https://github.com/runatlantis/atlantis/releases](https://github.com/runatlantis/atlantis/releases) and unpackage it. - -## Add Webhook -Once you've decided where to host Atlantis you need to add that URL as a webhook -to your Git host so that Atlantis gets notified about pull request events. -See the instructions for your specific provider below: - -### GitHub/GitHub Enterprise Webhook -If you already have a GitHub organization we recommend installing the webhook at the **organization level** rather than on each repository, however both methods will work. - -::: tip -If you're not sure if you have a GitHub organization see [https://help.github.com/articles/differences-between-user-and-organization-accounts/](https://help.github.com/articles/differences-between-user-and-organization-accounts/) +::: tip Pre-Requisites +* You have created an [access credential](access-credentials.html) +* You have created a [webhook secret](webhook-secrets.html) ::: -If you're installing on the organization, navigate to your organization's page and click **Settings**. -If installing on a single repository, navigate to the repository home page and click **Settings**. -- Select **Webhooks** or **Hooks** in the sidebar -- Click **Add webhook** -- set **Payload URL** to `http://$URL/events` (or `https://$URL/events` if you're using SSL) where `$URL` is where Atlantis is hosted. **Be sure to add `/events`** -- double-check you added `/events` to the end of your URL. -- set **Content type** to `application/json` -- set **Secret** to a random key (https://www.random.org/strings/). You'll need to pass this value to the `--gh-webhook-secret` flag when you start Atlantis - - **NOTE** If you're adding a webhook to multiple repositories, each repository will need to use the **same** secret. -- select **Let me select individual events** -- check the boxes - - **Pull request reviews** - - **Pushes** - - **Issue comments** - - **Pull requests** -- leave **Active** checked -- click **Add webhook** +[[toc]] -### GitLab Webhook -If you're using GitLab, navigate to your project's home page in GitLab -- Click **Settings > Integrations** in the sidebar -- set **URL** to `http://$URL/events` (or `https://$URL/events` if you're using SSL) where `$URL` is where Atlantis is hosted. **Be sure to add `/events`** -- double-check you added `/events` to the end of your URL. -- set **Secret Token** to a random key (https://www.random.org/strings/). You'll need to pass this value to the `--gitlab-webhook-secret` flag when you start Atlantis - - **NOTE** If you're adding a webhook to multiple repositories, each repository will need to use the **same** secret. -- check the boxes - - **Push events** - - **Comments** - - **Merge Request events** -- leave **Enable SSL verification** checked -- click **Add webhook** +## Architecture Overview +### Runtime +Atlantis is a simple [Go](https://golang.org/) app. It receives webhooks from +your Git host and executes Terraform commands locally. There is an official +Atlantis [Docker image](https://hub.docker.com/r/runatlantis/atlantis/). -### Bitbucket Cloud (bitbucket.org) Webhook -- Go to your repo's home page -- Click **Settings** in the sidebar -- Click **Webhooks** under the **WORKFLOW** section -- Click **Add webhook** -- Enter "Atlantis" for **Title** -- set **URL** to `http://$URL/events` (or `https://$URL/events` if you're using SSL) where `$URL` is where Atlantis is hosted. **Be sure to add `/events`** -- double-check you added `/events` to the end of your URL. -- Keep **Status** as Active -- Don't check **Skip certificate validation** because NGROK has a valid cert. -- Select **Choose from a full list of triggers** -- Under **Repository** **un**check everything -- Under **Issues** leave everything **un**checked -- Under **Pull Request**, select: Created, Updated, Merged, Declined and Comment created -- Click **Save** -Bitbucket Webhook +### Routing +Because Atlantis needs to receive webhooks from your Git host, it must be routable +from that Git host. If you're using a public Git host like GitHub.com, GitLab.com +or Bitbucket.org then you'll need to expose Atlantis to the internet. -### Bitbucket Server (aka Stash) Webhook -- Go to your repo's home page -- Click **Settings** in the sidebar -- Click **Webhooks** under the **WORKFLOW** section -- Click **Create webhook** -- Enter "Atlantis" for **Name** -- set **URL** to `http://$URL/events` (or `https://$URL/events` if you're using SSL) where `$URL` is where Atlantis is hosted. **Be sure to add `/events`** -- Double-check you added `/events` to the end of your URL. -- Set **Secret** to a random key (https://www.random.org/strings/). You'll need to pass this value to the `--bitbucket-webhook-secret` flag when you start Atlantis - - **NOTE** If you're adding a webhook to multiple repositories, each repository will need to use the **same** secret. -- Under **Repository** select **Push** -- Under **Pull Request**, select: Opened, Modified, Merged, Declined, Deleted and Comment added -- Click **Save**Bitbucket Webhook +If you're using a private Git host like GitHub Enterprise, GitLab Enterprise or +Bitbucket Server, then you just need Atlantis to be routable from there. -## Create an access token for Atlantis -We recommend using a dedicated CI user or creating a new user named **@atlantis** that performs all API actions, however for testing, -you can use your own user. Here we'll create the access token that Atlantis uses to comment on the pull request and -set commit statuses. +### Data +Atlantis has no external database. Atlantis stores Terraform plan files on disk. +If Atlantis loses that data in between a `plan` and `apply` cycle, then users will have +to re-run `plan`. Because of this, you may want to provision a persistent disk +for Atlantis. -### Create a GitHub Token -**NOTE: The Atlantis user must have "Write permissions" (for repos in an organization) or be a "Collaborator" (for repos in a user account) to be able to set commit statuses:** -![Atlantis status](./images/status.png) -- create a Personal Access Token by following [https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/#creating-a-token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/#creating-a-token) -- create the token with **repo** scope -- copy the access token +## Deployment -### Create a GitLab Token -- follow [https://docs.gitlab.com/ce/user/profile/personal_access_tokens.html#creating-a-personal-access-token](https://docs.gitlab.com/ce/user/profile/personal_access_tokens.html#creating-a-personal-access-token) -- create a token with **api** scope -- copy the access token +Pick your deployment type: +* [Kubernetes Helm Chart](#kubernetes-helm-chart) +* [Kubernetes Manifests](#kubernetes-manifests) +* [OpenShift](#openshift) +* [AWS Fargate](#aws-fargate) +* [Google Kubernetes Engine (GKE)](#google-kubernetes-engine-gke) +* [Docker](#docker) +* [Roll your own](#roll-your-own) -### Create a Bitbucket Cloud (bitbucket.org) App Password -- create an App Password by following [https://confluence.atlassian.com/bitbucket/app-passwords-828781300.html#Apppasswords-Createanapppassword](https://confluence.atlassian.com/bitbucket/app-passwords-828781300.html#Apppasswords-Createanapppassword) -- Label the password "atlantis" -- Select **Pull requests**: **Read** and **Write** so that Atlantis can read your pull requests and write comments to them -- copy the access token -### Create a Bitbucket Server (aka Stash) Personal Access Token -- Click on your avatar in the top right and select **Manage account** -- Click **Personal access tokens** in the sidebar -- Click **Create a token** -- Name the token **atlantis** -- Give the token **Read** Project permissions and **Write** Pull request permissions -- Click **Create** and copy the access token +### Kubernetes Helm Chart +Atlantis has an [official Helm chart](https://hub.kubeapps.com/charts/stable/atlantis). -## Start Atlantis -Now you're ready to start Atlantis! The exact command depends on your Git host: +To install: +1. `cd` into a directory where you're going to configure your Atlantis Helm chart +1. Create a `values.yaml` file by running + ```bash + helm inspect values stable/atlantis > values.yaml + ``` +1. Edit `values.yaml` and add your access credentials and webhook secret + ```yaml + # for example + github: + user: foo + token: bar + secret: baz + ``` +1. Edit `values.yaml` and set your `orgWhitelist` + ```yaml + orgWhitelist: github.com/runatlantis/* + ``` + See [Repo Whitelist](server-configuration.html#repo-whitelist) for more information. +1. Configure any other variables. See [https://github.com/helm/charts/tree/master/stable/atlantis#customization](https://github.com/helm/charts/tree/master/stable/atlantis#customization) + for documentation. +1. Run + ```sh + helm install -f values.yaml stable/atlantis + ``` -### GitHub Command -```bash -atlantis server \ ---atlantis-url="$URL" \ ---gh-user="$USERNAME" \ ---gh-token="$TOKEN" \ ---gh-webhook-secret="$SECRET" \ ---repo-whitelist="$REPO_WHITELIST" -``` -### GitHub Enterprise Command -```bash -HOSTNAME=YOUR_GITHUB_ENTERPRISE_HOSTNAME # ex. github.runatlantis.io -atlantis server \ ---atlantis-url="$URL" \ ---gh-user="$USERNAME" \ ---gh-token="$TOKEN" \ ---gh-webhook-secret="$SECRET" \ ---gh-hostname="$HOSTNAME" \ ---repo-whitelist="$REPO_WHITELIST" -``` +Atlantis should be up and running in minutes! See [Next Steps](#next-steps) for +what to do next. -### GitLab Command -```bash -atlantis server \ ---atlantis-url="$URL" \ ---gitlab-user="$USERNAME" \ ---gitlab-token="$TOKEN" \ ---gitlab-webhook-secret="$SECRET" \ ---repo-whitelist="$REPO_WHITELIST" -``` - -### GitLab Enterprise Command -```bash -HOSTNAME=YOUR_GITLAB_ENTERPRISE_HOSTNAME # ex. gitlab.runatlantis.io -atlantis server \ ---atlantis-url="$URL" \ ---gitlab-user="$USERNAME" \ ---gitlab-token="$TOKEN" \ ---gitlab-webhook-secret="$SECRET" \ ---gitlab-hostname="$HOSTNAME" \ ---repo-whitelist="$REPO_WHITELIST" -``` - -### Bitbucket Cloud (bitbucket.org) Command -```bash -atlantis server \ ---atlantis-url="$URL" \ ---bitbucket-user="$USERNAME" \ ---bitbucket-token="$TOKEN" \ ---repo-whitelist="$REPO_WHITELIST" -``` - -### Bitbucket Server (aka Stash) Command -```bash -BASE_URL=YOUR_BITBUCKET_SERVER_URL # ex. http://bitbucket.mycorp:7990 -atlantis server \ ---atlantis-url="$URL" \ ---bitbucket-user="$USERNAME" \ ---bitbucket-token="$TOKEN" \ ---bitbucket-webhook-secret="$SECRET" \ ---bitbucket-base-url="$BASE_URL" \ ---repo-whitelist="$REPO_WHITELIST" -``` - -Where -- `$URL` is the URL that Atlantis can be reached at -- `$USERNAME` is the GitHub/GitLab/Bitbucket username you generated the token for -- `$TOKEN` is the access token you created. If you don't want this to be passed in as an argument for security reasons you can specify it in a config file (see [Configuration](/docs/server-configuration.html#environment-variables)) or as an environment variable: `ATLANTIS_GH_TOKEN` or `ATLANTIS_GITLAB_TOKEN` or `ATLANTIS_BITBUCKET_TOKEN` -- `$SECRET` is the random key you used for the webhook secret. If you don't want this to be passed in as an argument for security reasons you can specify it in a config file (see [Configuration](/docs/server-configuration.html#environment-variables)) or as an environment variable: `ATLANTIS_GH_WEBHOOK_SECRET` or `ATLANTIS_GITLAB_WEBHOOK_SECRET` -- `$REPO_WHITELIST` is which repos Atlantis can run on, ex. `github.com/runatlantis/*` or `github.enterprise.corp.com/*`. See [www.runatlantis.io/docs/security.html#repo-whitelist](/docs/security.html#repo-whitelist) for more details. - -Atlantis is now running! -**We recommend running it under something like Systemd or Supervisord.** - -## Docker -Atlantis also ships inside a docker image. Run the docker image: - -```bash -docker run runatlantis/atlantis:latest server -``` - -### Usage -If you need to modify the Docker image that we provide, for instance to add a specific version of Terraform, you can do something like this: - -* Create a custom docker file -```bash -vim Dockerfile-custom -``` - -```dockerfile -FROM runatlantis/atlantis - -# copy a terraform binary of the version you need -COPY terraform /usr/local/bin/terraform -``` - -* Build docker image - -```bash -docker build -t {YOUR_DOCKER_ORG}/atlantis-custom -f Dockerfile-custom . -``` - -* Run docker image - -```bash -docker run {YOUR_DOCKER_ORG}/atlantis-custom server --gh-user=GITHUB_USERNAME --gh-token=GITHUB_TOKEN -``` - -## Kubernetes -Atlantis can be deployed into Kubernetes as a +### Kubernetes Manifests +If you'd like to use a raw Kubernetes manifest, we offer either a [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) -or as a [Statefulset](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) with persistent storage. +or a [Statefulset](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) with persistent storage. StatefulSet is recommended because Atlantis stores its data on disk and so if your Pod dies -or you upgrade Atlantis, you won't lose the data. On the other hand, the only data that -Atlantis has right now is any plans that haven't been applied and Atlantis locks. If -Atlantis loses that data, you just need to run `atlantis plan` again so it's not the end of the world. +or you upgrade Atlantis, you won't lose plans that haven't been applied. If +you do lose that data, you just need to run `atlantis plan` again so it's not the end of the world. Regardless of whether you choose a Deployment or StatefulSet, first create a Secret with the webhook secret and access token: ```bash @@ -257,16 +88,16 @@ echo -n "yourtoken" > token echo -n "yoursecret" > webhook-secret kubectl create secret generic atlantis-vcs --from-file=token --from-file=webhook-secret ``` -::: tip +::: tip Note If you're using Bitbucket Cloud then there is no webhook secret since it's not supported. ::: Next, edit the manifests below as follows: -1. Replace `` in `image: runatlantis/atlantis:` with the most recent version from https://github.com/runatlantis/atlantis/releases/latest. +1. Replace `` in `image: runatlantis/atlantis:` with the most recent version from [https://github.com/runatlantis/atlantis/releases/latest](https://github.com/runatlantis/atlantis/releases/latest). * NOTE: You never want to run with `:latest` because if your Pod moves to a new node, Kubernetes will pull the latest image and you might end up upgrading Atlantis by accident! 2. Replace `value: github.com/yourorg/*` under `name: ATLANTIS_REPO_WHITELIST` with the whitelist pattern -for your Terraform repos. See [--repo-whitelist](/docs/security.html#repo-whitelist) for more details. +for your Terraform repos. See [Repo Whitelist](server-configuration.html#repo-whitelist) for more details. 3. If you're using GitHub: 1. Replace `` with the username of your Atlantis GitHub user without the `@`. 2. Delete all the `ATLANTIS_GITLAB_*` and `ATLANTIS_BITBUCKET_*` environment variables. @@ -277,7 +108,7 @@ for your Terraform repos. See [--repo-whitelist](/docs/security.html#repo-whitel 1. Replace `` with the username of your Atlantis Bitbucket user without the `@`. 2. Delete all the `ATLANTIS_GH_*` and `ATLANTIS_GITLAB_*` environment variables. -### StatefulSet Manifest +#### StatefulSet Manifest
Show... @@ -339,7 +170,7 @@ spec: name: atlantis-vcs key: webhook-secret ### End GitLab Config ### - + ### Bitbucket Config ### - name: ATLANTIS_BITBUCKET_USER value: # 5i. If you're using Bitbucket replace with the username of your Atlantis Bitbucket user without the `@`. @@ -409,7 +240,7 @@ spec:
-### Deployment Manifest +#### Deployment Manifest
Show... @@ -520,7 +351,7 @@ spec: ```
-### Routing and SSL +#### Routing and SSL The manifests above create a Kubernetes `Service` of type `ClusterIP` which isn't accessible outside your cluster. Depending on how you're doing routing into Kubernetes, you may want to use a `LoadBalancer` so that Atlantis is accessible to GitHub/GitLab and your internal users. @@ -529,31 +360,161 @@ If you want to add SSL you can use something like [https://github.com/jetstack/c certs and mount them into the Pod. Then set the `ATLANTIS_SSL_CERT_FILE` and `ATLANTIS_SSL_KEY_FILE` environment variables to enable SSL. You could also set up SSL at your LoadBalancer. +**You're done! See [Next Steps](#next-steps) for what to do next.** + ### OpenShift -The Atlantis Docker image is compatible with OpenShift, however you need to run -with an additional flag: `--data-dir=/home/atlantis`. This is required because +The Helm chart and Kubernetes manifests above are compatible with OpenShift, however you need to run +with an additional environment variable: `ATLANTIS_DATA_DIR=/home/atlantis`. This is required because OpenShift runs Docker images with random user id's that use `/` as their home directory. -Since Atlantis defaults to using the home directory as its data dir and `/` doesn't have the correct permissions, -you need to set `--data-dir` or the environment variable `ATLANTIS_DATA_DIR` to `/home/atlantis`. -## AWS Fargate +### AWS Fargate +If you'd like to run Atlantis on [AWS Fargate](https://aws.amazon.com/fargate/) + check out the Atlantis module on the Terraform Module Registry: [https://registry.terraform.io/modules/terraform-aws-modules/atlantis/aws](https://registry.terraform.io/modules/terraform-aws-modules/atlantis/aws) + and then check out the [Next Steps](#next-steps). -If you'd like to run Atlantis on [AWS Fargate](https://aws.amazon.com/fargate/) check out the Atlantis module on the Terraform Module Registry: https://registry.terraform.io/modules/terraform-aws-modules/atlantis/aws +### Google Kubernetes Engine (GKE) +You can run Atlantis on GKE using the [Helm chart](#kubernetes-helm-chart) or the [manifests](#kubernetes-manifests). -## Testing Out Atlantis on GitHub +There is also a set of full Terraform configurations that create a GKE Cluster, +Cloud Storage Backend and TLS certs: [https://github.com/sethvargo/atlantis-on-gke](https://github.com/sethvargo/atlantis-on-gke). -If you'd like to test out Atlantis before running it on your own repositories you can fork our example repo. +Once you're done, see [Next Steps](#next-steps). -- Fork [https://github.com/runatlantis/atlantis-example](https://github.com/runatlantis/atlantis-example) -- If you didn't add the Webhook as to your organization add Atlantis as a Webhook to the forked repo (see [Add GitHub Webhook](#add-github-webhook)) -- Now that Atlantis can receive events you should be able to comment on a pull request to trigger Atlantis. Create a pull request - - Click **Branches** on your forked repo's homepage - - click the **New pull request** button next to the `example` branch - - Change the `base` to `{your-repo}/master` - - click **Create pull request** -- Now you can test out Atlantis - - Create a comment `atlantis help` to see what commands you can run from the pull request - - `atlantis plan` will run `terraform plan` behind the scenes. You should see the output commented back on the pull request. You should also see some logs show up where you're running `atlantis server` - - `atlantis apply` will run `terraform apply`. Since our pull request creates a `null_resource` (which does nothing) this is safe to do. +### Docker +Atlantis has an [official](https://hub.docker.com/r/runatlantis/atlantis/) Docker image: `runatlantis/atlantis`. +#### Customization +If you need to modify the Docker image that we provide, for instance to add a specific version of Terraform, you can do something like this: +1. Create a custom docker file + ```dockerfile + FROM runatlantis/atlantis:{latest version} + + # copy a terraform binary of the version you need + COPY terraform /usr/local/bin/terraform + ``` + +1. Build your Docker image + ```bash + docker build -t {YOUR_DOCKER_ORG}/atlantis-custom . + ``` + +1. Run your image + ```bash + docker run {YOUR_DOCKER_ORG}/atlantis-custom server --gh-user=GITHUB_USERNAME --gh-token=GITHUB_TOKEN + ``` + +### Roll Your Own +If you're deploying Atlantis into infrastructure not listed above, here's what +Atlantis needs in its environment. + +#### Terraform +The `terraform` binary needs to be in the `$PATH` for Atlantis. +Download from https://www.terraform.io/downloads.html +```bash +unzip path/to/terraform_*.zip -d /usr/local/bin +``` +Check that it's in your `$PATH` +``` +$ terraform version +Terraform v0.10.0 +``` +If you want to use a different version of Terraform see [Terraform Versions](requirements.html#terraform-versions) + +#### Atlantis Binary +Get the latest release from [https://github.com/runatlantis/atlantis/releases](https://github.com/runatlantis/atlantis/releases) and unpackage it. + +#### Startup Command +The exact flags to `atlantis server` depends on your Git host: + +##### GitHub +```bash +atlantis server \ +--atlantis-url="$URL" \ +--gh-user="$USERNAME" \ +--gh-token="$TOKEN" \ +--gh-webhook-secret="$SECRET" \ +--repo-whitelist="$REPO_WHITELIST" +``` + +##### GitHub Enterprise +```bash +HOSTNAME=YOUR_GITHUB_ENTERPRISE_HOSTNAME # ex. github.runatlantis.io +atlantis server \ +--atlantis-url="$URL" \ +--gh-user="$USERNAME" \ +--gh-token="$TOKEN" \ +--gh-webhook-secret="$SECRET" \ +--gh-hostname="$HOSTNAME" \ +--repo-whitelist="$REPO_WHITELIST" +``` + +##### GitLab +```bash +atlantis server \ +--atlantis-url="$URL" \ +--gitlab-user="$USERNAME" \ +--gitlab-token="$TOKEN" \ +--gitlab-webhook-secret="$SECRET" \ +--repo-whitelist="$REPO_WHITELIST" +``` + +##### GitLab Enterprise +```bash +HOSTNAME=YOUR_GITLAB_ENTERPRISE_HOSTNAME # ex. gitlab.runatlantis.io +atlantis server \ +--atlantis-url="$URL" \ +--gitlab-user="$USERNAME" \ +--gitlab-token="$TOKEN" \ +--gitlab-webhook-secret="$SECRET" \ +--gitlab-hostname="$HOSTNAME" \ +--repo-whitelist="$REPO_WHITELIST" +``` + +##### Bitbucket Cloud (bitbucket.org) +```bash +atlantis server \ +--atlantis-url="$URL" \ +--bitbucket-user="$USERNAME" \ +--bitbucket-token="$TOKEN" \ +--repo-whitelist="$REPO_WHITELIST" +``` + +##### Bitbucket Server (aka Stash) +```bash +BASE_URL=YOUR_BITBUCKET_SERVER_URL # ex. http://bitbucket.mycorp:7990 +atlantis server \ +--atlantis-url="$URL" \ +--bitbucket-user="$USERNAME" \ +--bitbucket-token="$TOKEN" \ +--bitbucket-webhook-secret="$SECRET" \ +--bitbucket-base-url="$BASE_URL" \ +--repo-whitelist="$REPO_WHITELIST" +``` + +Where +- `$URL` is the URL that Atlantis can be reached at +- `$USERNAME` is the GitHub/GitLab/Bitbucket username you generated the token for +- `$TOKEN` is the access token you created. If you don't want this to be passed + in as an argument for security reasons you can specify it in a config file + (see [Configuration](/docs/server-configuration.html#environment-variables)) + or as an environment variable: `ATLANTIS_GH_TOKEN` or `ATLANTIS_GITLAB_TOKEN` + or `ATLANTIS_BITBUCKET_TOKEN` +- `$SECRET` is the random key you used for the webhook secret. + If you don't want this to be passed in as an argument for security reasons + you can specify it in a config file + (see [Configuration](/docs/server-configuration.html#environment-variables)) + or as an environment variable: `ATLANTIS_GH_WEBHOOK_SECRET` or `ATLANTIS_GITLAB_WEBHOOK_SECRET` +- `$REPO_WHITELIST` is which repos Atlantis can run on, ex. + `github.com/runatlantis/*` or `github.enterprise.corp.com/*`. + See [Repo Whitelist](server-configuration.html#repo-whitelist) for more details. + +Atlantis is now running! +::: tip +We recommend running it under something like Systemd or Supervisord. That will +restart it in case of failure. +::: + +## Next Steps +* To ensure Atlantis is running, load its UI. By default Atlantis runs on port `4141`. +* Now you're ready to add Webhooks to your repos. See [Configuring Webhooks](configuring-webhooks.html). diff --git a/runatlantis.io/docs/how-atlantis-works.md b/runatlantis.io/docs/how-atlantis-works.md new file mode 100644 index 000000000..261a9fb9e --- /dev/null +++ b/runatlantis.io/docs/how-atlantis-works.md @@ -0,0 +1,5 @@ +# How Atlantis Works +This section of docs talks about how Atlantis at deeper level. + +* [Locking](locking.html) +* [Autoplanning](autoplanning.html) diff --git a/runatlantis.io/docs/images/example-comment.png b/runatlantis.io/docs/images/example-comment.png new file mode 100644 index 0000000000000000000000000000000000000000..6b8e4e03f03237ef55519c412b4171a818b30800 GIT binary patch literal 81105 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 literal 0 HcmV?d00001 diff --git a/runatlantis.io/docs/installation-guide.md b/runatlantis.io/docs/installation-guide.md new file mode 100644 index 000000000..10310c2f5 --- /dev/null +++ b/runatlantis.io/docs/installation-guide.md @@ -0,0 +1,13 @@ +# Installation Guide + +To get Atlantis running you need to: +1. Create **access credentials** on your Git host (GitHub, GitLab, Bitbucket) + * See [Generating Git host Access Credentials](access-credentials.html) +1. Create a **webhook secret** so Atlantis can validate webhooks securely + * See [Creating a Webhook Secret](webhook-secrets.html) +1. **Deploy** Atlantis into your infrastructure + * See [Deployment](deployment.html) +1. Configure **Webhooks** on your Git host so Atlantis can respond to your pull requests + * See [Configuring Webhooks](configuring-webhooks.html) + +And before you do all this, first check that you meet all the [Requirements](requirements.html). diff --git a/runatlantis.io/guide/requirements.md b/runatlantis.io/docs/requirements.md similarity index 65% rename from runatlantis.io/guide/requirements.md rename to runatlantis.io/docs/requirements.md index c7db09168..f15dadd81 100644 --- a/runatlantis.io/guide/requirements.md +++ b/runatlantis.io/docs/requirements.md @@ -1,19 +1,23 @@ # Requirements +Atlantis works with most Git hosts and Terraform setups. Read on to confirm +it works with yours. [[toc]] -## Git Host +## Git host +Atlantis integrates with the following Git hosts: + * GitHub (public, private or enterprise) * GitLab (public, private or enterprise) * Bitbucket Cloud aka bitbucket.org (public or private) * Bitbucket Server aka Stash -## Remote State -Atlantis supports all remote state backends. It **does not** support local state +## Terraform State +Atlantis supports all **remote state** backends. It **does not** support local state because it does not commit the modified state files back to version control. ## Repository Structure -Atlantis supports any Terraform project structures, for example: +Atlantis supports any Terraform repository structure, for example: ### Single Terraform project at repo root ``` @@ -45,15 +49,15 @@ 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 Use Cases](atlantis-yaml-use-cases.html#configuring-autoplanning) for more details. +you need to create an `atlantis.yaml` file. See [atlantis.yaml Use Cases](/guide/atlantis-yaml-use-cases.html#configuring-autoplanning) for more details. ### Terraform Workspaces ::: tip See [Terraform's docs](https://www.terraform.io/docs/state/workspaces.html) if you are unfamiliar with workspaces. ::: -If you're using a Terraform version >= 0.9.0, Atlantis supports workspaces through an +If you're using Terraform `>= 0.9.0`, Atlantis supports workspaces through an `atlantis.yaml` file that tells Atlantis the names of your workspaces -(see [atlantis.yaml Use Cases](atlantis-yaml-use-cases.html#supporting-terraform-workspaces) for more details) +(see [atlantis.yaml Use Cases](/guide/atlantis-yaml-use-cases.html#supporting-terraform-workspaces) for more details) or through the `-w` flag. For example: ``` atlantis plan -w staging @@ -70,7 +74,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 Use Cases](atlantis-yaml-use-cases.html#using-tfvars-files) for more details. +See [atlantis.yaml Use Cases](/guide/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. @@ -78,7 +82,8 @@ 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 Use Cases](atlantis-yaml-use-cases.html#terraform-versions) for more details. +See [atlantis.yaml Use Cases](/guide/atlantis-yaml-use-cases.html#terraform-versions) for more details. ## Next Steps -Check out our [full documentation](../docs/). +* If your Terraform setup meets the Atlantis requirements, head back to our [Installation Guide](installation-guide.html) to get started + installing Atlantis diff --git a/runatlantis.io/docs/server-configuration.md b/runatlantis.io/docs/server-configuration.md index cffd53078..d4fe5e8ad 100644 --- a/runatlantis.io/docs/server-configuration.md +++ b/runatlantis.io/docs/server-configuration.md @@ -85,3 +85,22 @@ terraform { } } ``` + +## Repo Whitelist +Atlantis requires you to specify a whitelist of repositories it will accept webhooks from via the `--repo-whitelist` flag. + +Notes: +* Accepts a comma separated list, ex. `definition1,definition2` +* Format is `{hostname}/{owner}/{repo}`, ex. `github.com/runatlantis/atlantis` +* `*` matches any characters, ex. `github.com/runatlantis/*` will match all repos in the runatlantis organization +* For Bitbucket Server: `{hostname}` is the domain without scheme and port, `{owner}` is the name of the project (not the key), and `{repo}` is the repo name + +Examples: +* Whitelist `myorg/repo1` and `myorg/repo2` on `github.com` + * `--repo-whitelist=github.com/myorg/repo1,github.com/myorg/repo2` +* Whitelist all repos under `myorg` on `github.com` + * `--repo-whitelist='github.com/myorg/*'` +* Whitelist all repos in my GitHub Enterprise installation + * `--repo-whitelist='github.yourcompany.com/*'` +* Whitelist all repositories + * `--repo-whitelist='*'` diff --git a/runatlantis.io/docs/pull-request-commands.md b/runatlantis.io/docs/using-atlantis.md similarity index 95% rename from runatlantis.io/docs/pull-request-commands.md rename to runatlantis.io/docs/using-atlantis.md index 2bed29c9f..c23f380fd 100644 --- a/runatlantis.io/docs/pull-request-commands.md +++ b/runatlantis.io/docs/using-atlantis.md @@ -1,4 +1,5 @@ -# Pull Request Commands +# Using Atlantis + Atlantis currently supports three commands that can be run via pull request comments: [[toc]] @@ -51,7 +52,7 @@ you can append them to the end of the comment after `--`, ex. ``` atlantis plan -d dir -- -var 'foo=bar' ``` -If you always need to append a certain flag, see [Project-Specific Customization](#project-specific-customization). +If you always need to append a certain flag, see [atlantis.yaml Use Cases](/guide/atlantis-yaml-use-cases.html#adding-extra-arguments-to-terraform-commands). --- ## atlantis apply @@ -96,3 +97,4 @@ Because Atlantis under the hood is running `terraform apply plan.tfplan`, any Te They're ignored because they can't be specified for an already generated planfile. If you would like to specify these flags, do it while running `atlantis plan`. + diff --git a/runatlantis.io/docs/webhook-secrets.md b/runatlantis.io/docs/webhook-secrets.md new file mode 100644 index 000000000..0fa34689c --- /dev/null +++ b/runatlantis.io/docs/webhook-secrets.md @@ -0,0 +1,30 @@ +# Webhook Secrets + +Atlantis uses Webhook secrets to validate that the webhooks it receives from your +Git host are legitimate. + +One way to confirm this would be to whitelist requests +to only come from the IPs of your Git host but an easier way is to use a Webhook +Secret. + +::: tip Note +Webhook secrets are actually optional. However they're highly recommended for +security. +::: + +## Generating A Webhook Secret +You can use any random string generator to create your Webhook secret. It should be > 24 characters. + +For example: +* Generate via Ruby with `ruby -rsecurerandom -e 'puts SecureRandom.hex(20)'` +* Generate online with [https://www.random.org/passwords/?num=2&len=20&format=html&rnd=new](https://www.random.org/passwords/?num=2&len=20&format=html&rnd=new) + +::: tip +You must use **the same** webhook secret for each repo. +::: + +## Next Steps +* Record your secret +* You'll be using it later to [configure your webhooks](configuring-webhooks.html), however if you're +following the [Installation Guide](installation-guide.html) then your next step is to +[Deploy Atlantis](deployment.html) diff --git a/runatlantis.io/guide/README.md b/runatlantis.io/guide/README.md index d0994eb99..27d9fce99 100644 --- a/runatlantis.io/guide/README.md +++ b/runatlantis.io/guide/README.md @@ -56,4 +56,4 @@ to construct your ideal workflow. ## Next Steps * If you'd like to try out Atlantis on a test repo, check out the [Test Drive](test-drive.html). * If you're ready to deploy it on your own repos, check out [Getting Started](getting-started.html). -* If you're wondering if Atlantis supports how you run Terraform, read [Requirements](requirements.html). \ No newline at end of file +* If you're wondering if Atlantis supports how you run Terraform, read [Requirements](/docs/requirements.html). diff --git a/runatlantis.io/guide/getting-started.md b/runatlantis.io/guide/getting-started.md index 2968df707..5c2dd9c06 100644 --- a/runatlantis.io/guide/getting-started.md +++ b/runatlantis.io/guide/getting-started.md @@ -195,7 +195,7 @@ REPO_WHITELIST="$YOUR_GIT_HOST/$YOUR_USERNAME/$YOUR_REPO" # server without scheme or port and $YOUR_USERNAME will be the name of the **project** the repo # is under, **not the key** of the project. ``` -Now you can start Atlantis. The exact command differs depending on your Git Host: +Now you can start Atlantis. The exact command differs depending on your Git host: ### GitHub Command ```bash