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 new resource Workload for Apphub #10155

Merged
merged 16 commits into from
Mar 12, 2024
Merged
228 changes: 228 additions & 0 deletions mmv1/products/apphub/Workload.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

--- !ruby/object:Api::Resource
base_url: projects/{{project}}/locations/{{location}}/applications/{{application_id}}/workloads
create_url: projects/{{project}}/locations/{{location}}/applications/{{application_id}}/workloads?workloadId={{workload_id}}
self_link: projects/{{project}}/locations/{{location}}/applications/{{application_id}}/workloads/{{workload_id}}
id_format: projects/{{project}}/locations/{{location}}/applications/{{application_id}}/workloads/{{workload_id}}
import_format:
- projects/{{project}}/locations/{{location}}/applications/{{application_id}}/workloads/{{workload_id}}
name: Workload
description: 'Workload represents a binary deployment (such as Managed Instance Groups (MIGs), GKE deployments, etc.) that performs the smallest logical subset of business functionality.
It registers identified workload to the Application.'
autogen_async: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "apphub_workload_basic"
pull_external: true
primary_resource_id: "example"
vars:
application_id: "example-application-1"
service_project_attachment_id: "project-1"
ilb_network: "l7-ilb-network"
ilb_subnet: "l7-ilb-subnet"
instance_template: "l7-ilb-mig-template"
mig: "l7-ilb-mig1"
test_env_vars:
org_id: :ORG_ID
billing_account: :BILLING_ACCT
- !ruby/object:Provider::Terraform::Examples
name: "apphub_workload_full"
pull_external: true
primary_resource_id: "example"
vars:
application_id: "example-application-1"
service_project_attachment_id: "project-1"
display_name: "Example Service Full"
description: "Register service for testing"
business_name: "Alice"
business_email: "alice@google.com"
developer_name: "Bob"
developer_email: "bob@google.com"
operator_name: "Charlie"
operator_email: "charlie@google.com"
ilb_network: "l7-ilb-network"
ilb_subnet: "l7-ilb-subnet"
instance_template: "l7-ilb-mig-template"
mig: "l7-ilb-mig1"
test_env_vars:
org_id: :ORG_ID
billing_account: :BILLING_ACCT
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
path: name
base_url: "{{op_id}}"
wait_ms: 1000
timeouts:
result: !ruby/object:Api::OpAsync::Result
path: response
resource_inside_response: true
status: !ruby/object:Api::OpAsync::Status
path: done
complete: true
allowed:
- true
- false
error: !ruby/object:Api::OpAsync::Error
path: error
message: message
update_verb: :PATCH
update_mask: true
parameters:
- !ruby/object:Api::Type::String
name: location
description: 'Part of `parent`. Full resource name of a parent Application. Example: projects/{HOST_PROJECT_ID}/locations/{LOCATION}/applications/{APPLICATION_ID} '
url_param_only: true
required: true
immutable: true
- !ruby/object:Api::Type::String
name: applicationId
description: 'Part of `parent`. Full resource name of a parent Application. Example: projects/{HOST_PROJECT_ID}/locations/{LOCATION}/applications/{APPLICATION_ID}'
url_param_only: true
required: true
immutable: true
- !ruby/object:Api::Type::String
name: workloadId
description: 'The Workload identifier. '
url_param_only: true
required: true
immutable: true
properties:
- !ruby/object:Api::Type::String
name: name
output: true
description: "Identifier. The resource name of the Workload. Format:\"projects/{host-project-id}/locations/{location}/applications/{application-id}/workloads/{workload-id}\" "
- !ruby/object:Api::Type::String
name: displayName
description: 'User-defined name for the Workload. '
- !ruby/object:Api::Type::String
name: description
description: 'User-defined description of a Workload. '
- !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: uri
description: 'Output only. The underlying compute resource uri. '
output: true
output: true
name: workloadReference
eshagoel06 marked this conversation as resolved.
Show resolved Hide resolved
description: 'Reference of an underlying compute resource represented by the Workload. '
- !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: gcpProject
description: "Output only. The service project identifier that the underlying
cloud resource resides in. Empty for non cloud resources. "
output: true
- !ruby/object:Api::Type::String
name: location
description: "Output only. The location that the underlying compute resource resides
in (e.g us-west1). "
output: true
- !ruby/object:Api::Type::String
name: zone
description: "Output only. The location that the underlying compute resource resides
in if it is zonal (e.g us-west1-a). "
output: true
output: true
name: workloadProperties
description: 'Properties of an underlying compute resource represented by the Workload. '
- !ruby/object:Api::Type::String
name: discoveredWorkload
diff_suppress_func: 'tpgresource.ProjectNumberDiffSuppress'
description: 'Immutable. The resource name of the original discovered workload. '
required: true
immutable: true
- !ruby/object:Api::Type::NestedObject
name: attributes
description: 'Consumer provided attributes. '
properties:
- !ruby/object:Api::Type::NestedObject
name: criticality
description: 'Criticality of the Application, Service, or Workload '
properties:
- !ruby/object:Api::Type::Enum
name: type
description: 'Criticality type. '
required: true
values:
- :MISSION_CRITICAL
- :HIGH
- :MEDIUM
- :LOW
- !ruby/object:Api::Type::NestedObject
name: environment
description: 'Environment of the Application, Service, or Workload '
properties:
- !ruby/object:Api::Type::Enum
name: type
description: 'Environment type. '
required: true
values:
- :PRODUCTION
- :STAGING
- :TEST
- :DEVELOPMENT
- !ruby/object:Api::Type::Array
name: developerOwners
description: 'Developer team that owns development and coding. '
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: displayName
description: 'Contact''s name. '
- !ruby/object:Api::Type::String
name: email
description: 'Email address of the contacts. '
required: true
- !ruby/object:Api::Type::Array
name: operatorOwners
description: 'Operator team that ensures runtime and operations. '
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: displayName
description: 'Contact''s name. '
- !ruby/object:Api::Type::String
name: email
description: 'Email address of the contacts. '
required: true
- !ruby/object:Api::Type::Array
name: businessOwners
description: 'Business team that ensures user needs are met and value is delivered '
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: displayName
description: 'Contact''s name. '
- !ruby/object:Api::Type::String
name: email
description: 'Email address of the contacts. '
required: true
- !ruby/object:Api::Type::String
name: createTime
description: 'Output only. Create time. '
output: true
- !ruby/object:Api::Type::String
name: updateTime
description: 'Output only. Update time. '
output: true
- !ruby/object:Api::Type::String
name: uid
description: "Output only. A universally unique identifier (UUID) for the `Workload` in the UUID4 format. "
output: true
- !ruby/object:Api::Type::String
name: state
description: "Output only. Workload state. Possible values: STATE_UNSPECIFIED CREATING ACTIVE DELETING DETACHED"
output: true
126 changes: 126 additions & 0 deletions mmv1/templates/terraform/examples/apphub_workload_basic.tf.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
resource "google_apphub_application" "application" {
location = "us-central1"
application_id = "<%= ctx[:vars]['application_id'] %>"
scope {
type = "REGIONAL"
}
}

resource "google_project" "service_project" {
project_id ="<%= ctx[:vars]['service_project_attachment_id'] %>"
name = "Service Project"
org_id = "<%= ctx[:test_env_vars]['org_id'] %>"
billing_account = "<%= ctx[:test_env_vars]['billing_account'] %>"
}

# Enable Compute API
resource "google_project_service" "compute_service_project" {
project = google_project.service_project.project_id
service = "compute.googleapis.com"
}

resource "time_sleep" "wait_120s" {
depends_on = [google_project_service.compute_service_project]

create_duration = "120s"
}

resource "google_apphub_service_project_attachment" "service_project_attachment" {
service_project_attachment_id = google_project.service_project.project_id
depends_on = [time_sleep.wait_120s]
}


# Discovered workload
data "google_apphub_discovered_workload" "catalog-workload" {
location = "us-central1"
workload_uri = "${replace(google_compute_region_instance_group_manager.mig.instance_group, "https://www.googleapis.com/compute/v1", "//compute.googleapis.com")}"
depends_on = [time_sleep.wait_120s_for_resource_ingestion]
}

resource "time_sleep" "wait_120s_for_resource_ingestion" {
depends_on = [google_compute_region_instance_group_manager.mig]
create_duration = "120s"
}

resource "google_apphub_workload" "<%= ctx[:primary_resource_id] %>" {
location = "us-central1"
application_id = google_apphub_application.application.application_id
workload_id = google_compute_region_instance_group_manager.mig.name
discovered_workload = data.google_apphub_discovered_workload.catalog-workload.name
}

#Workload creation


# VPC network
resource "google_compute_network" "ilb_network" {
name = "<%= ctx[:vars]['ilb_network'] %>"
project = google_project.service_project.project_id
auto_create_subnetworks = false
depends_on = [time_sleep.wait_120s]
}

# backend subnet
resource "google_compute_subnetwork" "ilb_subnet" {
name = "<%= ctx[:vars]['ilb_subnet'] %>"
project = google_project.service_project.project_id
ip_cidr_range = "10.0.1.0/24"
region = "us-central1"
network = google_compute_network.ilb_network.id
}

# instance template
resource "google_compute_instance_template" "instance_template" {
name = "<%= ctx[:vars]['instance_template'] %>"
project = google_project.service_project.project_id
machine_type = "e2-small"
tags = ["http-server"]
network_interface {
network = google_compute_network.ilb_network.id
subnetwork = google_compute_subnetwork.ilb_subnet.id
access_config {
# add external ip to fetch packages
}
}
disk {
source_image = "debian-cloud/debian-10"
auto_delete = true
boot = true
}
# install nginx and serve a simple web page
metadata = {
startup-script = <<-EOF1
#! /bin/bash
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y nginx-light jq
NAME=$(curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/hostname")
IP=$(curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip")
METADATA=$(curl -f -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=True" | jq 'del(.["startup-script"])')
cat <<EOF > /var/www/html/index.html
<pre>
Name: $NAME
IP: $IP
Metadata: $METADATA
</pre>
EOF
EOF1
}
lifecycle {
create_before_destroy = true
}
}

resource "google_compute_region_instance_group_manager" "mig" {
name = "<%= ctx[:vars]['mig'] %>"
project = google_project.service_project.project_id
region = "us-central1"
version {
instance_template = google_compute_instance_template.instance_template.id
name = "primary"
}
base_instance_name = "vm"
target_size = 2
}
Loading