Skip to content

Commit

Permalink
Add new resource Workload for Apphub (GoogleCloudPlatform#10155)
Browse files Browse the repository at this point in the history
* Add new resource Workload for Apphub

* Fix lint error

* Add billing account

* Remove extra delay from test

* Resolve comments

* Add handwritten update test

* Fix lint error

* Add data source changes

* Remove merged changes

* Remove merged changes

* Batch all update tests into one step to make test fast

* Add a delay between discovered resource fetch and managed instance group manager creation

* Add back org_id

* Update region from us-east1 to us-central1

* Use standard diff suppress function

---------

Co-authored-by: praseedhaPK <[email protected]>
Co-authored-by: Krishnan Gopal <[email protected]>
  • Loading branch information
3 people authored and balanaguharsha committed May 2, 2024
1 parent e25fd61 commit 7da3111
Show file tree
Hide file tree
Showing 4 changed files with 681 additions and 0 deletions.
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: "[email protected]"
developer_name: "Bob"
developer_email: "[email protected]"
operator_name: "Charlie"
operator_email: "[email protected]"
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
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

0 comments on commit 7da3111

Please sign in to comment.