Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions runatlantis.io/docs/repo-level-atlantis-yaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ version: 3 # Available since v0.1.0
automerge: true # Available since v0.15.0
autodiscover: # Available since v0.18.0
mode: auto
workspace: default
ignore_paths:
- some/path
delete_source_branch_on_merge: true # Available since v0.15.0
Expand Down Expand Up @@ -418,6 +419,16 @@ autodiscover:

Autodiscover can also be configured to skip over directories that match a path glob (as defined [here](https://pkg.go.dev/github.com/bmatcuk/doublestar/v4))

```yaml
autodiscover:
mode: "enabled"
workspace: qa
ignore_paths:
- terraform/aws-test/**
```

Use `workspace` to set the Terraform workspace for all autodiscovered projects. This is useful when running separate Atlantis instances per workspace on a shared repository. The configured workspace takes precedence over any workspace detected from `terraform { cloud { workspaces { name = "..." } } }` blocks in Terraform code.

### Custom Backend Config

See [Custom Workflow Use Cases: Custom Backend Config](custom-workflows.md#custom-backend-config)
Expand Down
19 changes: 18 additions & 1 deletion runatlantis.io/docs/server-side-repo-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ repos:
# If any part of this setting is set here, it overrides the entire setting in the repo config.
autodiscover:
mode: auto
# Optionally set a workspace for all autodiscovered projects
workspace: ""
# Optionally ignore some paths for autodiscovery by a glob path
ignore_paths:
- foo/*
Expand Down Expand Up @@ -546,7 +548,7 @@ If you set a workflow with the key `default`, it will override this.
| repo_locks | [RepoLocks](#repolocks) | `mode: on_plan` | no | Whether or not repository locks are enabled for this project on plan or apply. See [RepoLocks](#repolocks) for more details. |
| policy_check | bool | false | no | Whether or not to run policy checks on this repository. |
| custom_policy_check | bool | false | no | Whether or not to enable custom policy check tools outside of Conftest on this repository. |
| autodiscover | AutoDiscover | none | no | Auto discover settings for this repo |
| autodiscover | [AutoDiscover](#autodiscover) | none | no | Auto discover settings for this repo. See [AutoDiscover](#autodiscover) for more details. |
| silence_pr_comments | []string | none | no | Silence PR comments from defined stages while preserving PR status checks. Useful in large environments with many Atlantis instances and/or projects, when the comments are too big and too many, therefore it is preferable to rely solely on PR status checks. Supported values are: `plan`, `apply`. |

:::tip Notes
Expand Down Expand Up @@ -584,6 +586,21 @@ If you set a workflow with the key `default`, it will override this.
by the `id: github.com/owner/repo` config because it didn't define that key.
:::

### AutoDiscover

```yaml
mode: auto
workspace: ""
ignore_paths:
- some/path/**
```

| Key | Type | Default | Required | Description |
|--------------|-----------------|----------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| mode | string | `"auto"` | no | When `auto`, projects are discovered only if the repo has no `projects` configured. When `enabled`, discovery always runs. When `disabled`, discovery never runs. |
| workspace | string | `""` | no | Workspace to use for all autodiscovered projects. When set, this overrides workspace detection from `terraform { cloud { workspaces { name = "..." } } }` blocks. Useful when running one Atlantis instance per workspace. |
| ignore_paths | array\[string\] | `[]` | no | List of path globs (as defined [here](https://pkg.go.dev/github.com/bmatcuk/doublestar/v4)) to exclude from autodiscovery. |

### RepoLocks

```yaml
Expand Down
2 changes: 2 additions & 0 deletions server/core/config/raw/autodiscover.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var DefaultAutoDiscoverMode = valid.AutoDiscoverAutoMode
type AutoDiscover struct {
Mode *valid.AutoDiscoverMode `yaml:"mode,omitempty"`
IgnorePaths []string `yaml:"ignore_paths,omitempty"`
Workspace string `yaml:"workspace,omitempty"`
}

func (a AutoDiscover) ToValid() *valid.AutoDiscover {
Expand All @@ -30,6 +31,7 @@ func (a AutoDiscover) ToValid() *valid.AutoDiscover {
}

v.IgnorePaths = a.IgnorePaths
v.Workspace = a.Workspace

return &v
}
Expand Down
21 changes: 21 additions & 0 deletions server/core/config/raw/autodiscover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ ignore_paths:
IgnorePaths: []string{"foobar"},
},
},
{
description: "workspace set",
input: `
workspace: qa
`,
exp: raw.AutoDiscover{
Mode: nil,
Workspace: "qa",
},
},
}

for _, c := range cases {
Expand Down Expand Up @@ -198,6 +208,17 @@ func TestAutoDiscover_ToValid(t *testing.T) {
},
},
},
{
description: "workspace set",
input: raw.AutoDiscover{
Mode: &autoDiscoverEnabled,
Workspace: "qa",
},
exp: &valid.AutoDiscover{
Mode: valid.AutoDiscoverEnabledMode,
Workspace: "qa",
},
},
}
for _, c := range cases {
t.Run(c.description, func(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions server/core/config/valid/autodiscover.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const (
type AutoDiscover struct {
Mode AutoDiscoverMode
IgnorePaths []string
Workspace string
}

func (a AutoDiscover) IsPathIgnored(path string) bool {
Expand Down
24 changes: 19 additions & 5 deletions server/events/project_command_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,13 +384,13 @@ func (p *DefaultProjectCommandBuilder) autoDiscoverModeEnabled(ctx *command.Cont
// isAutoDiscoverPathIgnored determines whether this particular path is ignored for the purposes of auto discovery
func (p *DefaultProjectCommandBuilder) isAutoDiscoverPathIgnored(ctx *command.Context, repoCfg valid.RepoCfg, path string) bool {
fromGlobalAutoDiscover := p.GlobalCfg.RepoAutoDiscoverCfg(ctx.Pull.BaseRepo.ID())
if fromGlobalAutoDiscover != nil {
// Only use global config's IgnorePaths if they are explicitly set; otherwise fall through to repo-level.
if fromGlobalAutoDiscover != nil && fromGlobalAutoDiscover.IgnorePaths != nil {
return fromGlobalAutoDiscover.IsPathIgnored(path)
}
if repoCfg.AutoDiscover != nil {
return repoCfg.AutoDiscover.IsPathIgnored(path)
}

return false
}

Expand Down Expand Up @@ -447,12 +447,26 @@ func (p *DefaultProjectCommandBuilder) getMergedProjectCfgs(ctx *command.Context
}
ctx.Log.Info("automatically determined that there were %d additional projects modified in this pull request: %s",
len(modifiedProjects), modifiedProjects)
// Determine the workspace to use for autodiscovered projects. Global config takes precedence
// over repo-level config; both are only consulted when explicitly set (non-empty).
configuredWorkspace := ""
fromGlobalAutoDiscover := p.GlobalCfg.RepoAutoDiscoverCfg(ctx.Pull.BaseRepo.ID())
if fromGlobalAutoDiscover != nil && fromGlobalAutoDiscover.Workspace != "" {
configuredWorkspace = fromGlobalAutoDiscover.Workspace
} else if repoCfg.AutoDiscover != nil && repoCfg.AutoDiscover.Workspace != "" {
configuredWorkspace = repoCfg.AutoDiscover.Workspace
}
for _, mp := range modifiedProjects {
ctx.Log.Debug("determining config for project at dir: '%s'", mp.Path)
absProjectDir := filepath.Join(repoDir, mp.Path)
pWorkspace, err := p.ProjectFinder.DetermineWorkspaceFromHCL(ctx.Log, absProjectDir)
if err != nil {
return nil, fmt.Errorf("looking for Terraform Cloud workspace from configuration in '%s': %w", absProjectDir, err)
var pWorkspace string
if configuredWorkspace != "" {
pWorkspace = configuredWorkspace
} else {
pWorkspace, err = p.ProjectFinder.DetermineWorkspaceFromHCL(ctx.Log, absProjectDir)
if err != nil {
return nil, fmt.Errorf("looking for Terraform Cloud workspace from configuration in '%s': %w", absProjectDir, err)
}
}

pCfg := p.GlobalCfg.DefaultProjCfg(ctx.Log, ctx.Pull.BaseRepo.ID(), mp.Path, pWorkspace)
Expand Down
24 changes: 24 additions & 0 deletions server/events/project_command_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,30 @@ projects:
},
},
},
"autodiscover workspace set in autodiscover config": {
DirStructure: map[string]any{
"project1": map[string]any{
"main.tf": nil,
},
"project2": map[string]any{
"main.tf": nil,
},
},
AtlantisYAML: `version: 3
autodiscover:
mode: enabled
workspace: qa
ignore_paths:
- project2`,
ModifiedFiles: []string{"project1/main.tf", "project2/main.tf"},
Exp: []expCtxFields{
{
ProjectName: "",
RepoRelDir: "project1",
Workspace: "qa",
},
},
},
"autodiscover enabled but project excluded by empty when_modified": {
DirStructure: map[string]any{
"project1": map[string]any{
Expand Down
Loading