Skip to content

Commit

Permalink
Merge pull request #127 from GoogleCloudPlatform/terraform
Browse files Browse the repository at this point in the history
Merge Terraform config into master
  • Loading branch information
danielbeaudreau authored Jan 29, 2021
2 parents da59db4 + e3ab7d6 commit 032387a
Show file tree
Hide file tree
Showing 12 changed files with 476 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.gradle/

.DS_STORE

/terraform_alert_config/import_adapter/.terraform
/terraform_alert_config/import_adapter/.terraform.tfstate
/terraform_alert_config/import_adapter/.terraform.tfstate.backup
81 changes: 81 additions & 0 deletions terraform_alert_config/import_adapter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
## Terraform Alerting Config
This document describes the example DICOM Import adapter terraform configuration.
The terraform configuration deploys a DICOM Import adapter to Google Kubernetes
Engine, creates a Cloud Healthcare dataset and dicom store, and configures
monitoring to alert on the health of the adapter.

A storage bucket configuration is also provided in storage.tf, which can be used to
create a GCS storage bucket to use for [DICOM adapter backups](https://github.com/GoogleCloudPlatform/healthcare-dicom-dicomweb-adapter/wiki/C-STORE-Backup-and-Retries).
By default, this bucket is not used.

*Warning*: this configuration is for test purposes only, and will generate a random
password for the deployment and store it in the terraform state. For a real deployment,
consider a [different method](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs#authentication)
for managing authentication to kubernetes.

## Prepare workspace
The following software must be installed to use this configuration:
1. [gcloud](https://cloud.google.com/sdk/docs/install)
2. [Terraform](https://www.terraform.io/downloads.html)
3. [Kubernetes](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
## Description
Terraform configuration for deploying alerting on DICOM Import Adapter health.

The import adapter alerts on the following error events:
* CSTORE_ERROR
* CFIND_ERROR
* CFIND_QIDORS_ERROR
* CMOVE_ERROR
* CMOVE_QIDORS_ERROR
* CMOVE_CSTORE_ERROR
* COMMITMENT_ERROR
* COMMITMENT_QIDORS_ERROR

### Notification alerting
The configuration provides the ability to send notifications to the user when an event occurs, which is defined in the *terraform.tfvar* file.

### Health check
The configuration provides the ability to monitor the cluster uptime and send the corresponding event to the monitoring system.

## Configuration
The main connection settings and parameters are located in the *terraform.tfvars* file. Here the user can specify and change the settings for the following blocks:
* Google Cloud Project settings
* Google Cloud Storage settings
* Healthcare settings
* Dicom Import Adapter settings
* Google Kubernetes Engine settings

## Validate Terraform configuration
After you have made changes to the sample configuration, you can validate the configuration for any errors. To do this, run:
```bash
# load dependencies
terraform init -backend=false

# validate configuration
terraform validate
```

## Initialize Terraform workspace
After you have saved your customized variables file, you can initialize your Terraform workspace. This will download the provider and initialize it with the values provided in your `terraform.tfvars` file:
```bash
terraform init
```
In your initialized directory, run *terraform apply* and review the planned actions. Your terminal output should indicate the plan is running and what resources will be created:
```bash
terraform apply
```
This comand will provision a GKE Cluster and a GKE node pool. If you're comfortable with this, confirm the run with a `yes`.

Once the command has completed, verify the Import Adapter service is running:
```bash
kubectl get services
```
And verify the Import Adapter deployment has replicas.
```bash
kubectl get deployments
```

If you want to remove the deployment, run the destroy command and confirm with `yes` in your terminal.
```bash
terraform destroy
```
109 changes: 109 additions & 0 deletions terraform_alert_config/import_adapter/gke.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
resource "kubernetes_deployment" "dicom-adapter" {
metadata {
name = "dicom-adapter"
namespace = "namespace-dicom-import-adapter"
labels = {
App = "dicom-adapter"
}
}

# customize nodes params
spec {
progress_deadline_seconds = 2147483647
replicas = var.replicas
revision_history_limit = 2147483647
selector {
match_labels = {
App = "dicom-adapter"
}
}
strategy {
rolling_update {
max_surge = 2
max_unavailable = 1
}
type = "RollingUpdate"
}
template {
metadata {
labels = {
App = "dicom-adapter"
}
}
spec {
# Customize dicom import adapter settings
container {
image = var.image
name = "dicom-import-adapter"
image_pull_policy = "Always"
port {
container_port = var.dimse_port
name = "port"
protocol = "TCP"
}

resources {
limits {
cpu = "0.5"
memory = "512Mi"
}
requests {
cpu = "250m"
memory = "50Mi"
}
}

args = [
"--dimse_aet=IMPORTADAPTER",
"--dimse_port=${var.dimse_port}",
"--monitoring_project_id=${var.project_id}",
"--gcs_backup_project_id=${var.project_id}",
"--dicomweb_address=https://healthcare.googleapis.com/v1/projects/${var.project_id}/locations/${var.region}/datasets/${var.dataset}/dicomStores/${var.store}/dicomWeb",
"--persistent_file_upload_retry_amount=${var.persistent_file_upload_retry_amount}",
"--min_upload_delay=${var.min_upload_delay}",
"--persistent_file_storage_location=${var.persistent_file_storage_location}",
"--oauth_scopes=https://www.googleapis.com/auth/cloud-platform",
"--verbose"
]

env {
name = "ENV_POD_NAME"
value = "dicom-adapter"
}

env {
name = "ENV_POD_NAMESPACE"
value = "namespace-dicom-import-adapter"
}

env {
name = "ENV_CONTAINER_NAME"
value = "dicom-import-adapter"
}
}
dns_policy = "ClusterFirst"
restart_policy = "Always"

termination_grace_period_seconds = 300
}
}
}
}

# expose LoadBalancer
resource "kubernetes_service" "dicom-adapter" {
metadata {
name = "service-dicom-adapter"
namespace = "namespace-dicom-import-adapter"
}
spec {
selector = {
App = kubernetes_deployment.dicom-adapter.spec.0.template.0.metadata[0].labels.App
}
port {
port = var.dimse_port
target_port = var.dimse_port
}
type = "LoadBalancer"
}
}
12 changes: 12 additions & 0 deletions terraform_alert_config/import_adapter/healthcare.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Healthcare processing
# create healthcare dataset for storing dicom files
resource "google_healthcare_dataset" "dataset" {
name = var.dataset
location = var.region
}

# create healthcare store for storing dicom files
resource "google_healthcare_dicom_store" "default" {
name = var.store
dataset = google_healthcare_dataset.dataset.id
}
78 changes: 78 additions & 0 deletions terraform_alert_config/import_adapter/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Add required providers
provider "google" {
project = var.project_id
region = var.region
zone = var.zone
}

# Customize kubernetes provider

data "google_compute_zones" "available" {
project = var.project_id
}

resource "random_id" "cluster_name" {
byte_length = 10
}

resource "random_id" "username" {
byte_length = 14
}

resource "random_password" "password" {
length = 16
special = true
override_special = "_%@"
}

data "google_container_engine_versions" "supported" {
location = data.google_compute_zones.available.names[0]
}

resource "google_container_cluster" "primary" {
name = "tf-cluster-${random_id.cluster_name.hex}"
location = data.google_compute_zones.available.names[0]
network = "default"
initial_node_count = var.replicas
min_master_version = data.google_container_engine_versions.supported.latest_master_version
# node version must match master version
# https://www.terraform.io/docs/providers/google/r/container_cluster.html#node_version
node_version = data.google_container_engine_versions.supported.latest_master_version

node_locations = [
data.google_compute_zones.available.names[1]
]

master_auth {
username = random_id.username.hex
password = random_password.password.result
}

node_config {
machine_type = "n1-standard-4"

oauth_scopes = [
"https://www.googleapis.com/auth/compute",
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring",
]
}
}

provider "kubernetes" {
load_config_file = "false"
host = google_container_cluster.primary.endpoint

username = google_container_cluster.primary.master_auth[0].username
password = google_container_cluster.primary.master_auth[0].password
client_certificate = base64decode(google_container_cluster.primary.master_auth[0].client_certificate)
client_key = base64decode(google_container_cluster.primary.master_auth[0].client_key)
cluster_ca_certificate = base64decode(google_container_cluster.primary.master_auth[0].cluster_ca_certificate)
}

resource "kubernetes_namespace" "healthcare-dicom-adapter" {
metadata {
name = "namespace-dicom-import-adapter"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# google_monitoring_alert_policy should be corrected
# Monitoring and Alerting policy
resource "google_monitoring_notification_channel" "basic" {
display_name = "Error Notification Channel"
type = "email"
labels = {
email_address = var.alert_notification_email
}
}

# Setup alerting policy
resource "google_monitoring_alert_policy" "alert_policy" {
display_name = "Notification Alert Policy"
notification_channels = [google_monitoring_notification_channel.basic.name]
combiner = "OR"
conditions {
display_name = "Import adapter error condition"
condition_threshold {
threshold_value = var.threshold_value
filter = var.alert_filter
duration = var.alert_duration
comparison = "COMPARISON_GT"
aggregations {
alignment_period = var.alert_alignment_period
per_series_aligner = "ALIGN_COUNT"
}
}
}
}

7 changes: 7 additions & 0 deletions terraform_alert_config/import_adapter/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "lb_ip" {
value = kubernetes_service.dicom-adapter.load_balancer_ingress[0].ip
}

data "google_monitoring_uptime_check_ips" "ips" {
}

14 changes: 14 additions & 0 deletions terraform_alert_config/import_adapter/storage.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Google Cloud Storage processing
# create bucket for data backup
module "gcs_buckets" {
source = "terraform-google-modules/cloud-storage/google"
version = "~> 1.7"
project_id = var.project_id
names = [var.bucket_id]
prefix = ""
set_admin_roles = false
versioning = {
first = false
}
}

40 changes: 40 additions & 0 deletions terraform_alert_config/import_adapter/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# These variables must be changed by the user to work with a personal project
# Google Cloud Project settings
project_id = "your_project_id"
region = "your_region"
zone = "your_zone"

# Google Cloud Storage settings
bucket_id = "your_bucket_id"

# Healthcare settigs
dataset = "your_healthcare_dataset_name"
store = "your_healthcare_store_name"

# Dicom import adapter setting
# import adapter port
dimse_port = 4070

# set the backup storage location
# you can specify a local storage path like "/tmp"
# or an address in GCS, for example gs://bucket_id
persistent_file_storage_location = "/tmp"
persistent_file_upload_retry_amount = 3
min_upload_delay = 100
max_waiting_time_btw_uploads = 5000

# image with Dicom Import Adapter
image = "gcr.io/cloud-healthcare-containers/healthcare-api-dicom-dicomweb-adapter-import:0.2.22"

# Google Kubernetes Engine settings
replicas = 1

# Monitoring and Alerting settings
# user can customize filter and set custom events
# you can add yours filters in this variable
alert_filter = "metric.type=\"custom.googleapis.com/dicomadapter/import/cstore_errors\" AND resource.type=\"k8s_container\""

alert_duration = "60s"
alert_alignment_period = "60s"
alert_notification_email = "your_valid_email"
threshold_value = 0
Loading

0 comments on commit 032387a

Please sign in to comment.