terraform-provider-xray
terraform-provider-xray copied to clipboard
Terraform provider to manage JFrog Xray
Terraform Provider Xray
To use this provider in your Terraform module, follow the documentation here.
Quick Start
Create a new Terraform file with xray
resource (and artifactory
resource as well):
HCL Example
# Required for Terraform 0.13 and up (https://www.terraform.io/upgrade-guides/0-13.html)
terraform {
required_providers {
artifactory = {
source = "registry.terraform.io/jfrog/artifactory"
version = "2.9.1"
}
project = {
source = "registry.terraform.io/jfrog/project"
version = "1.0.1"
}
xray = {
source = "registry.terraform.io/jfrog/xray"
version = "0.0.1"
}
}
}
provider "artifactory" {
// supply ARTIFACTORY_USERNAME, ARTIFACTORY_PASSWORD and ARTIFACTORY_URL as env vars
}
provider "project" {
// supply PROJECT_URL, PROJECT_ACCESS_TOKEN as env vars
url = "${var.project_url}"
access_token = "${var.project_access_token}"
}
provider "xray" {
// Also user can supply the following env vars:
// JFROG_URL or XRAY_URL
// XRAY_ACCESS_TOKEN or JFROG_ACCESS_TOKEN
}
resource "random_id" "randid" {
byte_length = 2
}
resource "artifactory_user" "user1" {
name = "user1"
email = "[email protected]"
groups = ["readers"]
password = "Passw0rd!"
}
resource "artifactory_local_docker_v2_repository" "docker-local" {
key = "docker-local"
description = "hello docker-local"
tag_retention = 3
max_unique_tags = 5
xray_index = true # must be set to true to be able to assign the watch to the repo
}
resource "artifactory_local_gradle_repository" "local-gradle-repo" {
key = "local-gradle-repo-basic"
checksum_policy_type = "client-checksums"
snapshot_version_behavior = "unique"
max_unique_snapshots = 10
handle_releases = true
handle_snapshots = true
suppress_pom_consistency_checks = true
xray_index = true # must be set to true to be able to assign the watch to the repo
}
resource "project" "myproject" {
key = "test"
display_name = "My Project"
description = "My Project"
admin_privileges {
manage_members = true
manage_resources = true
index_resources = true
}
}
resource "project" "myproject1" {
key = "test1"
display_name = "My Project"
description = "My Project"
admin_privileges {
manage_members = true
manage_resources = true
index_resources = true
}
}
resource "xray_security_policy" "security1" {
name = "test-security-policy-severity-${random_id.randid.dec}"
description = "Security policy description"
type = "security"
rule {
name = "rule-name-severity"
priority = 1
criteria {
min_severity = "High"
}
actions {
webhooks = []
mails = ["[email protected]"]
block_release_bundle_distribution = true
fail_build = true
notify_watch_recipients = true
notify_deployer = true
create_ticket_enabled = false // set to true only if Jira integration is enabled
build_failure_grace_period_in_days = 5 // use only if fail_build is enabled
block_download {
unscanned = true
active = true
}
}
}
}
resource "xray_security_policy" "security2" {
name = "test-security-policy-cvss-${random_id.randid.dec}"
description = "Security policy description"
type = "security"
rule {
name = "rule-name-cvss"
priority = 1
criteria {
cvss_range {
from = 1.5
to = 5.3
}
}
actions {
webhooks = []
mails = ["[email protected]"]
block_release_bundle_distribution = true
fail_build = true
notify_watch_recipients = true
notify_deployer = true
create_ticket_enabled = false // set to true only if Jira integration is enabled
build_failure_grace_period_in_days = 5 // use only if fail_build is enabled
block_download {
unscanned = true
active = true
}
}
}
}
resource "xray_license_policy" "license1" {
name = "test-license-policy-allowed-${random_id.randid.dec}"
description = "License policy, allow certain licenses"
type = "license"
rule {
name = "License_rule"
priority = 1
criteria {
allowed_licenses = ["Apache-1.0", "Apache-2.0"]
allow_unknown = false
multi_license_permissive = true
}
actions {
webhooks = []
mails = ["[email protected]"]
block_release_bundle_distribution = false
fail_build = true
notify_watch_recipients = true
notify_deployer = true
create_ticket_enabled = false // set to true only if Jira integration is enabled
custom_severity = "High"
build_failure_grace_period_in_days = 5 // use only if fail_build is enabled
block_download {
unscanned = true
active = true
}
}
}
}
resource "xray_license_policy" "license2" {
name = "test-license-policy-banned-${random_id.randid.dec}"
description = "License policy, block certain licenses"
type = "license"
rule {
name = "License_rule"
priority = 1
criteria {
banned_licenses = ["Apache-1.1", "APAFML"]
allow_unknown = false
multi_license_permissive = false
}
actions {
webhooks = []
mails = ["[email protected]"]
block_release_bundle_distribution = false
fail_build = true
notify_watch_recipients = true
notify_deployer = true
create_ticket_enabled = false // set to true only if Jira integration is enabled
custom_severity = "Medium"
build_failure_grace_period_in_days = 5 // use only if fail_build is enabled
block_download {
unscanned = true
active = true
}
}
}
}
resource "xray_watch" "all-repos" {
name = "all-repos-watch-${random_id.randid.dec}"
description = "Watch for all repositories, matching the filter"
active = true
watch_resource {
type = "all-repos"
filter {
type = "regex"
value = ".*"
}
}
assigned_policy {
name = xray_security_policy.security1.name
type = "security"
}
assigned_policy {
name = xray_license_policy.license1.name
type = "license"
}
watch_recipients = ["[email protected]", "[email protected]"]
}
resource "xray_watch" "repository" {
name = "repository-watch-${random_id.randid.dec}"
description = "Watch a single repo or a list of repositories"
active = true
watch_resource {
type = "repository"
bin_mgr_id = "default"
name = artifactory_local_docker_v2_repository.docker-local.key
filter {
type = "regex"
value = ".*"
}
}
watch_resource {
type = "repository"
bin_mgr_id = "default"
name = artifactory_local_gradle_repository.local-gradle-repo.key
filter {
type = "package-type"
value = "Docker"
}
}
assigned_policy {
name = xray_security_policy.security1.name
type = "security"
}
assigned_policy {
name = xray_license_policy.license1.name
type = "license"
}
watch_recipients = ["[email protected]", "[email protected]"]
}
resource "xray_watch" "build" {
name = "build-watch-${random_id.randid.dec}"
description = "Watch a single build or a list of builds"
active = true
watch_resource {
type = "build"
bin_mgr_id = "default"
name = "your-build-name"
}
watch_resource {
type = "build"
bin_mgr_id = "default"
name = "your-other-build-name"
}
assigned_policy {
name = xray_security_policy.security1.name
type = "security"
}
assigned_policy {
name = xray_license_policy.license1.name
type = "license"
}
watch_recipients = ["[email protected]", "[email protected]"]
}
resource "xray_watch" "all-projects" {
name = "all-projects-watch-${random_id.randid.dec}"
description = "Watch all the projects"
active = true
watch_resource {
type = "all-projects"
bin_mgr_id = "default"
}
assigned_policy {
name = xray_security_policy.security1.name
type = "security"
}
assigned_policy {
name = xray_license_policy.license1.name
type = "license"
}
watch_recipients = ["[email protected]", "[email protected]"]
}
resource "xray_watch" "project" {
name = "project-watch-${random_id.randid.dec}"
description = "Watch selected projects"
active = true
watch_resource {
type = "project"
name = project.myproject.key
}
watch_resource {
type = "project"
name = project.myproject1.key
}
assigned_policy {
name = xray_security_policy.security1.name
type = "security"
}
assigned_policy {
name = xray_license_policy.license1.name
type = "license"
}
watch_recipients = ["[email protected]", "[email protected]"]
}
License requirements:
This provider requires Xray to be added to your Artifactory installation.
Xray requires minimum Pro Team license (Public Marketplace version or SaaS) or Pro X license (Self-hosted).
See the details here
You can determine which license you have by accessing the following Artifactory URL ${host}/artifactory/api/system/licenses/
Limitations of functionality
Currently, Xray provider is not supporting JSON objects in the Watch filter value. We are working on adding this functionality.
Build the Provider
Simply run make install
- this will compile the provider and install it to ~/.terraform.d
. When running this, it will
take the current tag and bump it 1 minor version. It does not actually create a new tag (that is make release
).
If you wish to use the locally installed provider, make sure your TF script refers to the new version number.
Requirements:
Building on macOS
This provider uses GNU sed as part of the build toolchain, in both Linux and macOS. This provides consistency across OSes.
If you are building this on macOS, you have two options:
- Install gnu-sed using brew, OR
- Use a Linux Docker image/container
Using gnu-sed
After installing with brew, get the GNU sed information:
$ brew info gnu-sed
You should see something like:
GNU "sed" has been installed as "gsed".
If you need to use it as "sed", you can add a "gnubin" directory
to your PATH from your bashrc like:
PATH="$(brew --prefix)/opt/gnu-sed/libexec/gnubin:$PATH"
Add the gnubin
directory to your .bashrc
or .zshrc
per instruction so that sed
command uses gnu-sed.
Testing
Since JFrog Xray is an addon for Artifactory, you will need a running instance of the JFrog platform (Artifactory and Xray). However, there is no currently supported dockerized, local version. The fastest way to install Artifactory and Xray as a self-hosted installation is to use Platform Helm chart. Free 30 days trial version is available here If you want to test on SaaS instance - 30 day trial can be freely obtained and will allow local development.
Then, you have to set some environment variables as this is how the acceptance tests pick up their config:
JFROG_URL=http://localhost:8081
XRAY_ACCESS_TOKEN=your-admin-key
TF_ACC=true
a crucial, and very much hidden, env var to set is
TF_ACC=true
- you can literally set TF_ACC
to anything you want, so long as it's set. The acceptance tests use
terraform testing libraries that, if this flag isn't set, will skip all tests.
XRAY_ACCESS_TOKEN
can be generated in the UI. Go to Settings -> Identity and Access -> Access Tokens -> Generate Admin Token
You can then run the tests as make acceptance
. You can check what it's doing on the background in the GNUmakefile in the project.
We've found that it's very convenient to use Charles proxy to see the payload, generated by Terraform Provider during the testing process. You can also use any other network packet reader, like Wireshark and so on.
Registry documentation generation
All the documentation in the project is generated by tfplugindocs. If you make any changes to the resource schemas, you will need to re-generate documentation. Install tfplugindocs, then run:
$ make doc
Versioning
In general, this project follows semver as closely as we can for tagging releases of the package. We've adopted the following versioning policy:
- We increment the major version with any incompatible change to functionality, including changes to the exported Go API surface or behavior of the API.
- We increment the minor version with any backwards-compatible changes to functionality.
- We increment the patch version with any backwards-compatible bug fixes.
Contributors
Pull requests, issues and comments are welcomed. For pull requests:
- Add tests for new features and bug fixes
- Follow the existing style
- Separate unrelated changes into multiple pull requests
See the existing issues for things to start contributing.
For bigger changes, make sure you start a discussion first by creating an issue and explaining the intended change.
JFrog requires contributors to sign a Contributor License Agreement, known as a CLA. This serves as a record stating that the contributor is entitled to contribute the code/documentation/translation to the project and is willing to have it used in distributions and derivative works (or is willing to transfer ownership).
License
Copyright (c) 2021 JFrog.
Apache 2.0 licensed, see LICENSE file.