Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Microsoft Azure ARM as an IaC Provider #736

Merged
merged 12 commits into from
Jun 30, 2021

Conversation

gauravgahlot
Copy link
Contributor

@gauravgahlot gauravgahlot commented May 5, 2021

The PR adds Microsoft Azure ARM as an IaC Provider for terrascan. Here is a quick run:

asciicast

➜ terrascan scan -h
...
  -i, --iac-type string           iac type (arm, helm, k8s, kustomize, terraform, tfplan)
      --iac-version string        iac version (arm: v1, helm: v3, k8s: v1, kustomize: v3, terraform: v12, v13, v14, tfplan: v1)
  -p, --policy-path stringArray   policy path directory
...

This allows terrascan users to validate their ARM templates against the existing policies for Azure. For example:

➜ terrascan scan -i arm

Violation Details -
	Description    :	Ensure that logging for Azure KeyVault is 'Enabled'
	File           :	/home/gg/go/src/github.com/infracloudio/mapper-test-files/arm/key-vault/azuredeploy.json
	Line           :	1
	Severity       :	HIGH
	-----------------------------------------------------------------------

Scan Summary -
	File/Folder         :	/home/gg/go/src/github.com/infracloudio/mapper-test-files/arm/key-vault
	IaC Type            :	arm
	Scanned At          :	2021-05-05 14:03:11.701178176 +0000 UTC
	Policies Validated  :	562
	Violated Policies   :	1
	Low                 :	0
	Medium              :	0
	High                :	1

@gauravgahlot gauravgahlot force-pushed the iac-provider-arm branch 5 times, most recently from 7594d9f to b01edba Compare May 11, 2021 07:42
@sigmabaryon sigmabaryon force-pushed the iac-provider-arm branch 2 times, most recently from b909941 to 4f6adf2 Compare May 12, 2021 09:50
@gauravgahlot gauravgahlot force-pushed the iac-provider-arm branch 5 times, most recently from c099d11 to af92d33 Compare May 13, 2021 17:29
@codecov
Copy link

codecov bot commented May 13, 2021

Codecov Report

Merging #736 (49499d0) into master (b8fda7c) will increase coverage by 0.67%.
The diff coverage is 83.79%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #736      +/-   ##
==========================================
+ Coverage   78.41%   79.08%   +0.67%     
==========================================
  Files         168      211      +43     
  Lines        4470     5117     +647     
==========================================
+ Hits         3505     4047     +542     
- Misses        741      826      +85     
- Partials      224      244      +20     
Impacted Files Coverage Δ
...mapper/iac-providers/arm/config/auditing-policy.go 0.00% <0.00%> (ø)
.../mapper/iac-providers/arm/config/patch-schedule.go 0.00% <0.00%> (ø)
...c-providers/arm/config/postgresql-configuration.go 0.00% <0.00%> (ø)
...er/iac-providers/arm/config/redis-firewall-rule.go 0.00% <0.00%> (ø)
...pper/iac-providers/arm/config/storage-container.go 0.00% <0.00%> (ø)
...c-providers/arm/config/network-watcher-flow-log.go 61.11% <61.11%> (ø)
pkg/iac-providers/arm/v1/load-dir.go 67.27% <67.27%> (ø)
pkg/iac-providers/arm/v1/load-file.go 72.05% <72.05%> (ø)
pkg/mapper/iac-providers/arm/functions/to-lower.go 80.00% <80.00%> (ø)
.../mapper/iac-providers/arm/functions/resource-id.go 83.33% <83.33%> (ø)
... and 78 more

for fileDir, files := range fileMap {
for i := range files {
// continue if file is a *.parameters.json or metadata.json
if isParametersFile(*files[i]) || isMetadataFile(*files[i]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to have a nil pointer check before accessing *files[i]?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be okay as long as range is generating it


func (a *ARMV1) hasValidParametersFile(i int, fileDir string, files []*string) bool {
f := strings.TrimSuffix(*files[i], filepath.Ext(*files[i]))
for n := range files {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get rid of this loop here. If we know the file name f+".parameters.json", why loop over all the files?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been fixed


const errFileLoad = "error while loading iac files"

func (a *ARMV1) hasValidParametersFile(i int, fileDir string, files []*string) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there not be a need to pass i. Can we try passing the filename directly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

return false
}

func extractParameterValues(params map[string]interface{}) (map[string]interface{}, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we associate this function with ARMV1 struct? Seems specific to ARM feature

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

continue
}

if strings.EqualFold(*files[n], f+".parameters.json") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we convert ".parameters.json" into a const, similar to JSONExtension?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

}

func (*ARMV1) getFileType(file string) string {
if strings.HasSuffix(file, JSONExtension) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if filepath.Ext() would be a better way of checking file extensions?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

zap.S().Debug("failed to load file", zap.String("file", absFilePath))
return allResourcesConfig, err
}
doc := iacDocuments[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think, it would be better to check the len(iacDocuments) > 0? There is a possibility of a panic if iacDocuments is empty?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

typeOnly bool
want output.AllResourceConfigs
wantErr error
}{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please add some unit test cases?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

wantErr: fmt.Errorf("no directories found for path ./testdata/testfile"),
},
{
name: "load invalid config dir",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering, should the wantErr=nil? From the test case name it seems that we are testing invalid config dir

if err != nil {
t.Error(err)
}
_, err = m.Map(doc, params)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apart from asserting on the error, we should also verify that the output we get from Map method is expected. It may happen that the test file gets modified or Map is modified which may result in a different output.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}{
{
name: "empty config",
dirPath: "./testdata/testfile",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use filepath.Join() here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

name: "empty config",
dirPath: "./testdata/testfile",
armv1: ARMV1{},
wantErr: fmt.Errorf("no directories found for path ./testdata/testfile"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use filepath.Join() here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

},
{
name: "key-vault",
dirPath: "./testdata/key-vault",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use filepath.Join() here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

name: "invalid dirPath",
dirPath: "not-there",
armv1: ARMV1{},
wantErr: &os.PathError{Err: syscall.ENOENT, Op: "lstat", Path: "not-there"},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this error check would fail on windows platform.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

}

var tmp Template
err = json.Unmarshal(data, &tmp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if possible, we should also verify the unmarshalled fields.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do the changed similar to cft, in upcoming PR, because ti will also need changes in KaiMonkey


// ARMV1 struct implements the IacProvider interface
type ARMV1 struct {
templateParameters map[string]interface{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Associate a multierror with the struct. Its job would be collecting all the file loading related errors. Please refer to other iac provider implementations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

@sigmabaryon sigmabaryon force-pushed the iac-provider-arm branch 3 times, most recently from b83d49c to 5800881 Compare June 28, 2021 16:22
gauravgahlot and others added 11 commits June 28, 2021 21:55
Signed-off-by: Gaurav Gahlot <gauravgahlot0107@gmail.com>
Signed-off-by: Gaurav Gahlot <gauravgahlot0107@gmail.com>
Signed-off-by: Gaurav Gahlot <gauravgahlot0107@gmail.com>
Signed-off-by: Gaurav Gahlot <gauravgahlot0107@gmail.com>
Signed-off-by: Gaurav Gahlot <gauravgahlot0107@gmail.com>
Signed-off-by: Gaurav Gahlot <gauravgahlot0107@gmail.com>
Signed-off-by: Gaurav Gahlot <gauravgahlot0107@gmail.com>
Signed-off-by: Gaurav Gahlot <gauravgahlot0107@gmail.com>
@sigmabaryon sigmabaryon force-pushed the iac-provider-arm branch 5 times, most recently from c35a4b1 to 3f4287f Compare June 29, 2021 06:36
@sonarcloud
Copy link

sonarcloud bot commented Jun 29, 2021

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 4 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

@kanchwala-yusuf kanchwala-yusuf merged commit 9e962b9 into tenable:master Jun 30, 2021
@gauravgahlot gauravgahlot deleted the iac-provider-arm branch June 30, 2021 11:37
sigmabaryon pushed a commit to infracloudio/terrascan that referenced this pull request Jun 30, 2021
sigmabaryon pushed a commit to infracloudio/terrascan that referenced this pull request Jun 30, 2021
kanchwala-yusuf pushed a commit that referenced this pull request Jul 22, 2021
* Add Microsoft Azure ARM as an IaC Provider  (#736)
* Add support for linked templates
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants