mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-08-07 03:18:44 +00:00
Add Getting Started instructions. Rename gh-password to gh-token
This commit is contained in:
109
README.md
109
README.md
@@ -4,13 +4,108 @@
|
||||
A unified workflow for collaborating on Terraform through GitHub.
|
||||
|
||||
## Features
|
||||
-
|
||||
➜ Collaborate on Terraform with your team
|
||||
- Run terraform `plan` and `apply` **from GitHub pull requests** so everyone can review the output
|
||||
- todo: gif
|
||||
- **Lock environments** until pull requests are merged to prevent concurrent modification and confusion
|
||||
|
||||
➜ Developers can write Terraform safely
|
||||
- **No need to distribute AWS credentials** to your whole team! Developers can submit Terraform changes and run `plan` and `apply` directly from the pull request
|
||||
- Optionally, require a **review and approval** prior to running `apply`
|
||||
|
||||
➜ Also
|
||||
- No more **copy-pasted code across environments**. Atlantis supports using an `env/{env}.tfvars` file per environment so you can write your base configuration once
|
||||
- Support **multiple versions of Terraform** with a simple project config file
|
||||
|
||||
## Getting Started
|
||||
// todo: atlantis bootstrap workflow
|
||||
Atlantis runs as a server that receives GitHub webhooks. Once it's running and hooked up with GitHub, you can interact with it directly through GitHub comments.
|
||||
|
||||
### First Download Atlantis
|
||||
Download from https://github.com/hootsuite/atlantis/releases
|
||||
|
||||
### Start with `atlantis bootstrap` (recommended)
|
||||
Run `atlantis bootstrap` to get started quickly with Atlantis.
|
||||
|
||||
If you want to manually run through all the steps that `bootstrap` performs, keep reading.
|
||||
|
||||
### Start Manually
|
||||
To manually get started with Atlantis, you'll need to
|
||||
- install `terraform` into your `$PATH`
|
||||
- download from https://www.terraform.io/downloads.html
|
||||
- `unzip path/to/terraform_*.zip -d /usr/local/bin`
|
||||
- check that it's installed by running `terraform version`
|
||||
- Atlantis needs to be reachable on an IP address or hostname that github.com can access. By default, Atlantis runs on port `4141` (this can be changed with the `--port` flag). You can install `ngrok` to make exposing Atlantis easy for testing purposes
|
||||
- download from https://ngrok.com/download
|
||||
- `unzip path/to/ngrok*.zip -d /usr/local/bin`
|
||||
- start ngrok with `ngrok http 4141`
|
||||
- Create a GitHub personal access token for Atlantis to use GitHub's API
|
||||
- follow [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)
|
||||
- copy the access token to your clipboard
|
||||
- now you're ready to start Atlantis! Run:
|
||||
```
|
||||
$ atlantis server --atlantis-url $URL --gh-username $USERNAME --gh-token $TOKEN
|
||||
2049/10/6 00:00:00 [WARN] server: Atlantis started - listening on port 4141
|
||||
```
|
||||
|
||||
- where `$URL` is the URL that Atlantis can be reached at. If using `ngrok` it will be something like `https://68da2fdd.ngrok.io`
|
||||
- where `$USERNAME` is your GitHub username
|
||||
- where `$TOKEN` is the access token you created
|
||||
|
||||
Now that Atlantis is running, it's time to test it out. You'll need to set up a pull request first
|
||||
|
||||
- Fork https://github.com/hootsuite/atlantis-example to your user
|
||||
- Add Atlantis as a webhook to the forked repo
|
||||
- navigate to `{your-repo-url}/settings/hooks/new`, ex. https://github.com/hootsuite/atlantis-example/settings/hooks/new
|
||||
- set **Payload URL** to `$URL/events` where `$URL` is what you used above, ex. `https://68da2fdd.ngrok.io/events`. **Be sure to add `/events` to the end**
|
||||
- set **Content type** to `application/json`
|
||||
- leave **Secret** blank
|
||||
- select **Let me select individual events**
|
||||
- check the boxes
|
||||
- **Pull request review**
|
||||
- **Push**
|
||||
- **Issue comment**
|
||||
- **Pull request**
|
||||
- leave **Active** checked
|
||||
- click **Add webhook**
|
||||
- Now that Atlantis can receive events you should be able to comment on a pull request to trigger Atlantis. Let's create a pull request
|
||||
- Navigate to `{your-repo-url}/branches`, ex. https://github.com/hootsuite/atlantis-example/branches
|
||||
- click the **New pull request** button next to the `example` branch
|
||||
- Change the `base` to `{your-repo}/master`
|
||||
- click **Create pull request**
|
||||
- Finally we're ready to talk to 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`
|
||||
- You could also type `atlantis apply` but since you may not have AWS credentials set up this probably won't work TODO: VERIFY THIS
|
||||
|
||||
You're done! If you're ready to set up Atlantis for a production deployment, see [Production-Ready Deployment](#Production-Ready+Deployment)
|
||||
|
||||
|
||||
## Production-Ready Deployment
|
||||
|
||||
## Configuration
|
||||
Atlantis configuration can be specified via cli flags or a yaml config file.
|
||||
Atlantis configuration can be specified via command line flags or a YAML config file.
|
||||
|
||||
```
|
||||
$ atlantis server --help
|
||||
...
|
||||
Usage:
|
||||
atlantis server [flags]
|
||||
|
||||
Flags:
|
||||
--atlantis-url string Url that Atlantis can be reached at. Defaults to http://$(hostname):$port where $port comes from the port flag.
|
||||
--aws-assume-role-arn string ARN of the role to assume when running Terraform against AWS. If not using assume role, no need to set.
|
||||
--aws-region string The Amazon region to connect to for API actions. (default "us-east-1")
|
||||
--config string Path to config file.
|
||||
--data-dir string Path to directory to store Atlantis data. (default "~/.atlantis")
|
||||
--gh-hostname string Hostname of your Github Enterprise installation. If using github.com, no need to set. (default "github.com")
|
||||
--gh-password string [REQUIRED] GitHub password of API user. Can also be specified via the ATLANTIS_GH_PASSWORD environment variable.
|
||||
--gh-user string [REQUIRED] GitHub username of API user.
|
||||
-h, --help help for server
|
||||
--log-level string Log level. Either debug, info, warn, or error. (default "warn")
|
||||
--port int Port to bind to. (default 4141)
|
||||
--require-approval Require pull requests to be "Approved" before allowing the apply command to be run. (default true)
|
||||
```
|
||||
|
||||
The `gh-password` flag can also be specified via an `ATLANTIS_GH_PASSWORD` environment variable.
|
||||
Config file values are overridden by environment variables which in turn are overridden by flags.
|
||||
|
||||
@@ -35,7 +130,10 @@ to assume a role (specified by the `--aws-assume-role-arn` flag) and **dynamical
|
||||
name the session** with the GitHub username of whoever is running `atlantis apply`.
|
||||
To take advantage of this feature, simply set the `--aws-assume-role-arn` flag.
|
||||
|
||||
## Project Locking
|
||||
## Environments
|
||||
|
||||
|
||||
## Locking
|
||||
When `plan` is run, the project and environment are Locked until an `apply` succeeds and the pull request is merged.
|
||||
This protects against concurrent modifications to the same set of infrastructure and prevents
|
||||
users from seeing a `plan` that will be invalid if another pull request is merged.
|
||||
@@ -43,9 +141,12 @@ users from seeing a `plan` that will be invalid if another pull request is merge
|
||||
To unlock the project and environment without completing an `apply`, click the link
|
||||
at the bottom of each plan to discard the plan and delete the lock.
|
||||
|
||||
## `atlantis.yaml` Config File
|
||||
|
||||
## Glossary
|
||||
#### Project
|
||||
A Terraform project. Multiple projects can be in a single GitHub repo.
|
||||
|
||||
#### Environment
|
||||
A Terraform environment. See [terraform docs](https://www.terraform.io/docs/state/environments.html) for more information.
|
||||
|
||||
|
||||
@@ -56,14 +56,14 @@ Follow these instructions to create a token (we don't store any tokens):
|
||||
- add "repo" scope
|
||||
- copy the access token
|
||||
`)
|
||||
// read github password, check for error later
|
||||
// read github token, check for error later
|
||||
colorstring.Print("[white][bold]GitHub access token (will be hidden): ")
|
||||
githubPassword, _ = readPassword()
|
||||
githubToken, _ = readPassword()
|
||||
|
||||
// create github client
|
||||
tp := github.BasicAuthTransport{
|
||||
Username: strings.TrimSpace(githubUsername),
|
||||
Password: strings.TrimSpace(githubPassword),
|
||||
Password: strings.TrimSpace(githubToken),
|
||||
}
|
||||
|
||||
githubClient := &Client{client: github.NewClient(tp.Client()), ctx: context.Background()}
|
||||
@@ -137,7 +137,7 @@ Follow these instructions to create a token (we don't store any tokens):
|
||||
// start atlantis server
|
||||
colorstring.Printf("[white]=> starting atlantis server ")
|
||||
s.Start()
|
||||
atlantisCmd, err := executeCmd("./atlantis", []string{"server", "--gh-user", githubUsername, "--gh-password", githubPassword, "--data-dir", "/tmp/atlantis/data"})
|
||||
atlantisCmd, err := executeCmd("./atlantis", []string{"server", "--gh-user", githubUsername, "--gh-token", githubToken, "--data-dir", "/tmp/atlantis/data"})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "creating atlantis server")
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
var githubHostname = "http://api.github.com"
|
||||
var githubUsername string
|
||||
var githubPassword string
|
||||
var githubToken string
|
||||
|
||||
// Client used for github interactions
|
||||
type Client struct {
|
||||
|
||||
@@ -26,7 +26,7 @@ test:
|
||||
# Run e2e tests
|
||||
- cd "${WORKDIR}" && ./scripts/e2e-deps.sh
|
||||
# Start atlantis server
|
||||
- cd "${WORKDIR}/e2e" && ./atlantis server --gh-user="$GITHUB_USERNAME" --gh-password="$GITHUB_PASSWORD" --data-dir="/tmp" --require-approval=false --log-level="debug" &> /tmp/atlantis-server.log:
|
||||
- cd "${WORKDIR}/e2e" && ./atlantis server --gh-user="$GITHUB_USERNAME" --gh-token="$GITHUB_TOKEN" --data-dir="/tmp" --require-approval=false --log-level="debug" &> /tmp/atlantis-server.log:
|
||||
background: true
|
||||
- sleep 2
|
||||
- cd "${WORKDIR}/e2e" && ./ngrok http 4141:
|
||||
|
||||
@@ -23,7 +23,7 @@ const (
|
||||
configFlag = "config"
|
||||
dataDirFlag = "data-dir"
|
||||
ghHostnameFlag = "gh-hostname"
|
||||
ghPasswordFlag = "gh-password"
|
||||
ghTokenFlag = "gh-token"
|
||||
ghUserFlag = "gh-user"
|
||||
logLevelFlag = "log-level"
|
||||
portFlag = "port"
|
||||
@@ -59,9 +59,9 @@ var stringFlags = []stringFlag{
|
||||
value: "github.com",
|
||||
},
|
||||
{
|
||||
name: ghPasswordFlag,
|
||||
description: "[REQUIRED] GitHub password of API user. Can also be specified via the ATLANTIS_GH_PASSWORD environment variable.",
|
||||
env: "ATLANTIS_GH_PASSWORD",
|
||||
name: ghTokenFlag,
|
||||
description: "[REQUIRED] GitHub token of API user. Can also be specified via the ATLANTIS_GH_TOKEN environment variable.",
|
||||
env: "ATLANTIS_GH_TOKEN",
|
||||
},
|
||||
{
|
||||
name: ghUserFlag,
|
||||
@@ -70,7 +70,7 @@ var stringFlags = []stringFlag{
|
||||
{
|
||||
name: logLevelFlag,
|
||||
description: "Log level. Either debug, info, warn, or error.",
|
||||
value: "warn",
|
||||
value: "info",
|
||||
},
|
||||
}
|
||||
var boolFlags = []boolFlag{
|
||||
@@ -186,8 +186,8 @@ func validate(config server.ServerConfig) error {
|
||||
if config.GithubUser == "" {
|
||||
return fmt.Errorf("--%s must be set", ghUserFlag)
|
||||
}
|
||||
if config.GithubPassword == "" {
|
||||
return fmt.Errorf("--%s must be set", ghPasswordFlag)
|
||||
if config.GithubToken == "" {
|
||||
return fmt.Errorf("--%s must be set", ghTokenFlag)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
10
e2e/main.go
10
e2e/main.go
@@ -30,9 +30,9 @@ func main() {
|
||||
if githubUsername == "" {
|
||||
log.Fatalf("GITHUB_USERNAME cannot be empty")
|
||||
}
|
||||
githubPassword := os.Getenv("GITHUB_PASSWORD")
|
||||
if githubPassword == "" {
|
||||
log.Fatalf("GITHUB_PASSWORD cannot be empty")
|
||||
githubToken := os.Getenv("GITHUB_TOKEN")
|
||||
if githubToken == "" {
|
||||
log.Fatalf("GITHUB_TOKEN cannot be empty")
|
||||
}
|
||||
atlantisURL := os.Getenv("ATLANTIS_URL")
|
||||
if atlantisURL == "" {
|
||||
@@ -49,7 +49,7 @@ func main() {
|
||||
repoName = "atlantis-tests"
|
||||
}
|
||||
// using https to clone the repo
|
||||
repoUrl := fmt.Sprintf("https://%s:%s@github.com/%s/%s.git", githubUsername, githubPassword, ownerName, repoName)
|
||||
repoUrl := fmt.Sprintf("https://%s:%s@github.com/%s/%s.git", githubUsername, githubToken, ownerName, repoName)
|
||||
cloneDirRoot := os.Getenv("CLONE_DIR")
|
||||
if cloneDirRoot == "" {
|
||||
cloneDirRoot = "/tmp/atlantis-tests"
|
||||
@@ -65,7 +65,7 @@ func main() {
|
||||
// create github client
|
||||
tp := github.BasicAuthTransport{
|
||||
Username: strings.TrimSpace(githubUsername),
|
||||
Password: strings.TrimSpace(githubPassword),
|
||||
Password: strings.TrimSpace(githubToken),
|
||||
}
|
||||
ghClient := github.NewClient(tp.Client())
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ type ServerConfig struct {
|
||||
AtlantisURL string `mapstructure:"atlantis-url"`
|
||||
DataDir string `mapstructure:"data-dir"`
|
||||
GithubHostname string `mapstructure:"gh-hostname"`
|
||||
GithubPassword string `mapstructure:"gh-password"`
|
||||
GithubToken string `mapstructure:"gh-token"`
|
||||
GithubUser string `mapstructure:"gh-user"`
|
||||
LogLevel string `mapstructure:"log-level"`
|
||||
Port int `mapstructure:"port"`
|
||||
@@ -77,7 +77,7 @@ func NewServer(config ServerConfig) (*Server, error) {
|
||||
config.DataDir = expanded
|
||||
}
|
||||
|
||||
githubClient, err := github.NewClient(config.GithubHostname, config.GithubUser, config.GithubPassword)
|
||||
githubClient, err := github.NewClient(config.GithubHostname, config.GithubUser, config.GithubToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user