Skip to content

Commit

Permalink
add globlaconfig and doc
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcelo Medeiros committed Oct 25, 2023
1 parent b0c1d51 commit 90ead7e
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 29 deletions.
1 change: 1 addition & 0 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const (
AllowForkPRsFlag = "allow-fork-prs"
AllowRepoConfigFlag = "allow-repo-config"
AtlantisURLFlag = "atlantis-url"
AutoDiscover = "autodiscover"
AutomergeFlag = "automerge"
ParallelPlanFlag = "parallel-plan"
ParallelApplyFlag = "parallel-apply"
Expand Down
92 changes: 92 additions & 0 deletions runatlantis.io/docs/autodiscover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Autodiscover
Atlantis can be configured to automatically discover Terraform projects in a repository.


## How To Enable
By default the autodiscover is enabled, but you can "enforce it":
1. Server Side:
```yaml
repo:
...
autodiscover:
enabled: true
...
```
1. Repo side `atlantis.yaml` file:
```yaml
version: 3
autodiscover:
enabled: true
projects:
- dir: .
```
:::tip NOTE
You need allow override in the server side configuration if you would like to disable it for a specific repo in the repo side configuration:
```yaml
repo:
...
allowed_overrides: [autodiscover]
...
```
::::

## How to Disable
You can disable it globally for each repo in the server side.
1. Server Side:
```yaml
repo:
...
autodiscover:
enabled: false
...
```
or for a specific repo in the repo side `atlantis.yaml` file:
1. Repo side `atlantis.yaml` file:
```yaml
version: 3
autodiscover:
enabled: false
projects:
- dir: .
```
:::tip NOTE
You need allow override in the server side configuration if you would like to disable it for a specific repo in the repo side configuration:
```yaml
repo:
...
allowed_overrides: [autodiscover]
...
```
::::
## Cases
### Multiple Projects
Atlantis will discover all Terraform projects in a repository. For example, if you have a repository with the following structure:
```
|── prod
│ └── project1
│ └── main.tf
| └── project2
│ └── main.tf
```
Atlantis will discover both `project1` and `project2` and create a plan for each one.

### Multi Server
Image that you have a mono repository with multiples stages, and for each stage you have a different Atlantis server. You can configure each server to discover only the projects that are related to it. For example, if you have a repository with the following structure:
```
|── prod
│ └── project1
│ └── main.tf
|── stage
|── test
└── project1
└── main.tf
```
You can create the atlantis.yaml dynamically in each server to discover only the projects that are related to it. For example, the `prod` server side configuration will have the:
```yaml
repos:
- id: /.*/
apply_requirements: [approved, mergeable]
repo_config_file: atlantis-prod.yaml
```

and you can use a [pre_workflow_hooks](./pre-workflow-hooks.md) to create the `atlantis-prod.yaml` file dynamically.
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 @@ -47,6 +47,8 @@ need to be defined.
```yaml
version: 3
automerge: true
autodiscover:
enabled: true
delete_source_branch_on_merge: true
parallel_plan: true
parallel_apply: true
Expand Down Expand Up @@ -148,6 +150,15 @@ projects:
This will stop Atlantis automatically running plan when `project1/` is updated
in a pull request.

### Disabling Autodiscover
```
version: 3
autodiscover:
enabled: false
```
This will stop Atlantis automatically discovering projects in a repo.
### Run plans and applies in parallel
```yaml
Expand Down
7 changes: 6 additions & 1 deletion runatlantis.io/docs/server-side-repo-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ repos:

# allowed_overrides specifies which keys can be overridden by this repo in
# its atlantis.yaml file.
allowed_overrides: [apply_requirements, workflow, delete_source_branch_on_merge, repo_locking, custom_policy_check]
allowed_overrides: [apply_requirements, workflow, delete_source_branch_on_merge, repo_locking, custom_policy_check, autodiscover]

# allowed_workflows specifies which workflows the repos that match
# are allowed to select.
Expand Down Expand Up @@ -88,6 +88,10 @@ repos:
# policy_check defines if policy checking should be enable on this repository.
policy_check: false

# autodiscover defines if atlantis should automatically discover projects in this repository.
autodiscover:
enabled: true

# id can also be an exact match.
- id: github.com/myorg/specific-repo

Expand Down Expand Up @@ -496,6 +500,7 @@ If you set a workflow with the key `default`, it will override this.
| repo_locking | bool | false | no | Whether or not to get a lock. |
| 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 | true | no | Whether or not to enable autodiscover on this repository. |


:::tip Notes
Expand Down
25 changes: 24 additions & 1 deletion server/core/config/parser_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,7 @@ func TestParseGlobalCfg(t *testing.T) {
input: `repos:
- id: /.*/
allowed_overrides: [invalid]`,
expErr: "repos: (0: (allowed_overrides: \"invalid\" is not a valid override, only \"plan_requirements\", \"apply_requirements\", \"import_requirements\", \"workflow\", \"delete_source_branch_on_merge\", \"repo_locking\", \"policy_check\", and \"custom_policy_check\" are supported.).).",
expErr: "repos: (0: (allowed_overrides: \"invalid\" is not a valid override, only \"plan_requirements\", \"apply_requirements\", \"import_requirements\", \"workflow\", \"delete_source_branch_on_merge\", \"repo_locking\", \"policy_check\", \"custom_policy_check\", and \"auto_discover\" are supported.).).",
},
"invalid plan_requirement": {
input: `repos:
Expand All @@ -1374,6 +1374,22 @@ func TestParseGlobalCfg(t *testing.T) {
import_requirements: [invalid]`,
expErr: "repos: (0: (import_requirements: \"invalid\" is not a valid import_requirement, only \"approved\", \"mergeable\" and \"undiverged\" are supported.).).",
},
"disable autodiscover": {
input: `repos:
- id: /.*/
autodiscover:
enabled: false`,
exp: valid.GlobalCfg{
Repos: []valid.Repo{
defaultCfg.Repos[0],
{
IDRegex: regexp.MustCompile(".*"),
AutoDiscover: &valid.Autodiscover{Enabled: false},
},
},
Workflows: defaultCfg.Workflows,
},
},
"no workflows key": {
input: `repos: []`,
exp: defaultCfg,
Expand Down Expand Up @@ -1449,13 +1465,17 @@ repos:
allowed_overrides: [plan_requirements, apply_requirements, import_requirements, workflow, delete_source_branch_on_merge]
allow_custom_workflows: true
policy_check: true
autodiscover:
enabled: true
- id: /.*/
branch: /(master|main)/
pre_workflow_hooks:
- run: custom workflow command
post_workflow_hooks:
- run: custom workflow command
policy_check: false
autodiscover:
enabled: false
workflows:
custom1:
plan:
Expand Down Expand Up @@ -1502,13 +1522,15 @@ policies:
AllowedOverrides: []string{"plan_requirements", "apply_requirements", "import_requirements", "workflow", "delete_source_branch_on_merge"},
AllowCustomWorkflows: Bool(true),
PolicyCheck: Bool(true),
AutoDiscover: &valid.Autodiscover{Enabled: true},
},
{
IDRegex: regexp.MustCompile(".*"),
BranchRegex: regexp.MustCompile("(master|main)"),
PreWorkflowHooks: preWorkflowHooks,
PostWorkflowHooks: postWorkflowHooks,
PolicyCheck: Bool(false),
AutoDiscover: &valid.Autodiscover{Enabled: false},
},
},
Workflows: map[string]valid.Workflow{
Expand Down Expand Up @@ -1619,6 +1641,7 @@ workflows:
RepoLocking: Bool(true),
PolicyCheck: Bool(false),
CustomPolicyCheck: Bool(false),
AutoDiscover: &valid.Autodiscover{Enabled: true},
},
},
Workflows: map[string]valid.Workflow{
Expand Down
49 changes: 31 additions & 18 deletions server/core/config/raw/global_cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,23 @@ type GlobalCfg struct {

// Repo is the raw schema for repos in the server-side repo config.
type Repo struct {
ID string `yaml:"id" json:"id"`
Branch string `yaml:"branch" json:"branch"`
RepoConfigFile string `yaml:"repo_config_file" json:"repo_config_file"`
PlanRequirements []string `yaml:"plan_requirements" json:"plan_requirements"`
ApplyRequirements []string `yaml:"apply_requirements" json:"apply_requirements"`
ImportRequirements []string `yaml:"import_requirements" json:"import_requirements"`
PreWorkflowHooks []WorkflowHook `yaml:"pre_workflow_hooks" json:"pre_workflow_hooks"`
Workflow *string `yaml:"workflow,omitempty" json:"workflow,omitempty"`
PostWorkflowHooks []WorkflowHook `yaml:"post_workflow_hooks" json:"post_workflow_hooks"`
AllowedWorkflows []string `yaml:"allowed_workflows,omitempty" json:"allowed_workflows,omitempty"`
AllowedOverrides []string `yaml:"allowed_overrides" json:"allowed_overrides"`
AllowCustomWorkflows *bool `yaml:"allow_custom_workflows,omitempty" json:"allow_custom_workflows,omitempty"`
DeleteSourceBranchOnMerge *bool `yaml:"delete_source_branch_on_merge,omitempty" json:"delete_source_branch_on_merge,omitempty"`
RepoLocking *bool `yaml:"repo_locking,omitempty" json:"repo_locking,omitempty"`
PolicyCheck *bool `yaml:"policy_check,omitempty" json:"policy_check,omitempty"`
CustomPolicyCheck *bool `yaml:"custom_policy_check,omitempty" json:"custom_policy_check,omitempty"`
ID string `yaml:"id" json:"id"`
Branch string `yaml:"branch" json:"branch"`
RepoConfigFile string `yaml:"repo_config_file" json:"repo_config_file"`
PlanRequirements []string `yaml:"plan_requirements" json:"plan_requirements"`
ApplyRequirements []string `yaml:"apply_requirements" json:"apply_requirements"`
ImportRequirements []string `yaml:"import_requirements" json:"import_requirements"`
PreWorkflowHooks []WorkflowHook `yaml:"pre_workflow_hooks" json:"pre_workflow_hooks"`
Workflow *string `yaml:"workflow,omitempty" json:"workflow,omitempty"`
PostWorkflowHooks []WorkflowHook `yaml:"post_workflow_hooks" json:"post_workflow_hooks"`
AllowedWorkflows []string `yaml:"allowed_workflows,omitempty" json:"allowed_workflows,omitempty"`
AllowedOverrides []string `yaml:"allowed_overrides" json:"allowed_overrides"`
AllowCustomWorkflows *bool `yaml:"allow_custom_workflows,omitempty" json:"allow_custom_workflows,omitempty"`
DeleteSourceBranchOnMerge *bool `yaml:"delete_source_branch_on_merge,omitempty" json:"delete_source_branch_on_merge,omitempty"`
RepoLocking *bool `yaml:"repo_locking,omitempty" json:"repo_locking,omitempty"`
PolicyCheck *bool `yaml:"policy_check,omitempty" json:"policy_check,omitempty"`
CustomPolicyCheck *bool `yaml:"custom_policy_check,omitempty" json:"custom_policy_check,omitempty"`
Autodiscover *valid.Autodiscover `yaml:"autodiscover,omitempty" json:"autodiscover,omitempty"`
}

func (g GlobalCfg) Validate() error {
Expand Down Expand Up @@ -193,8 +194,8 @@ func (r Repo) Validate() error {
overridesValid := func(value interface{}) error {
overrides := value.([]string)
for _, o := range overrides {
if o != valid.PlanRequirementsKey && o != valid.ApplyRequirementsKey && o != valid.ImportRequirementsKey && o != valid.WorkflowKey && o != valid.DeleteSourceBranchOnMergeKey && o != valid.RepoLockingKey && o != valid.PolicyCheckKey && o != valid.CustomPolicyCheckKey {
return fmt.Errorf("%q is not a valid override, only %q, %q, %q, %q, %q, %q, %q, and %q are supported", o, valid.PlanRequirementsKey, valid.ApplyRequirementsKey, valid.ImportRequirementsKey, valid.WorkflowKey, valid.DeleteSourceBranchOnMergeKey, valid.RepoLockingKey, valid.PolicyCheckKey, valid.CustomPolicyCheckKey)
if o != valid.PlanRequirementsKey && o != valid.ApplyRequirementsKey && o != valid.ImportRequirementsKey && o != valid.WorkflowKey && o != valid.DeleteSourceBranchOnMergeKey && o != valid.RepoLockingKey && o != valid.PolicyCheckKey && o != valid.CustomPolicyCheckKey && o != valid.AutoDiscoverKey {
return fmt.Errorf("%q is not a valid override, only %q, %q, %q, %q, %q, %q, %q, %q, and %q are supported", o, valid.PlanRequirementsKey, valid.ApplyRequirementsKey, valid.ImportRequirementsKey, valid.WorkflowKey, valid.DeleteSourceBranchOnMergeKey, valid.RepoLockingKey, valid.PolicyCheckKey, valid.CustomPolicyCheckKey, valid.AutoDiscoverKey)
}
}
return nil
Expand All @@ -211,6 +212,16 @@ func (r Repo) Validate() error {
return nil
}

autoDiscoverValid := func(value interface{}) error {
// var autoDiscover interface{} = value
// if autoDiscover != nil {
// if _, ok := autoDiscover.(Autodiscover); !ok {
// return fmt.Errorf("autodiscover must be a map like : autodiscover: \\n enabled: true")
// }
// }
return nil
}

return validation.ValidateStruct(&r,
validation.Field(&r.ID, validation.Required, validation.By(idValid)),
validation.Field(&r.Branch, validation.By(branchValid)),
Expand All @@ -221,6 +232,7 @@ func (r Repo) Validate() error {
validation.Field(&r.ImportRequirements, validation.By(validImportReq)),
validation.Field(&r.Workflow, validation.By(workflowExists)),
validation.Field(&r.DeleteSourceBranchOnMerge, validation.By(deleteSourceBranchOnMergeValid)),
validation.Field(&r.Autodiscover, validation.By(autoDiscoverValid)),
)
}

Expand Down Expand Up @@ -333,5 +345,6 @@ OuterGlobalImportReqs:
RepoLocking: r.RepoLocking,
PolicyCheck: r.PolicyCheck,
CustomPolicyCheck: r.CustomPolicyCheck,
AutoDiscover: r.Autodiscover,
}
}
Loading

0 comments on commit 90ead7e

Please sign in to comment.