Skip to content

added support 2nd generation cloud function #872

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

Merged
merged 15 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# 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.
#
# CFv2 define whether to use Cloud function 2nd generation or 1st generation

from distutils.command.config import config
import os
Expand All @@ -22,16 +22,20 @@
from googleapiclient import discovery
from metrics import ilb_fwrules, instances, networks, metrics, limits, peerings, routes, subnets, vpc_firewalls

CFv2 = False
if CFv2:
import functions_framework


def get_monitored_projects_list(config):
'''
Gets the projects to be monitored from the MONITORED_FOLDERS_LIST environment variable.
Gets the projects to be monitored from the MONITORED_FOLDERS_LIST environment variable.

Parameters:
config (dict): The dict containing config like clients and limits
Returns:
monitored_projects (List of strings): Full list of projects to be monitored
'''
Parameters:
config (dict): The dict containing config like clients and limits
Returns:
monitored_projects (List of strings): Full list of projects to be monitored
'''
monitored_projects = config["monitored_projects"]
monitored_folders = [] #os.environ.get("MONITORED_FOLDERS_LIST").split(",")

Expand Down Expand Up @@ -68,10 +72,10 @@ def get_monitored_projects_list(config):

def monitoring_interval():
'''
Creates the monitoring interval of 24 hours
Returns:
monitoring_v3.TimeInterval: Monitoring time interval of 24h
'''
Creates the monitoring interval of 24 hours
Returns:
monitoring_v3.TimeInterval: Monitoring time interval of 24h
'''
now = time.time()
seconds = int(now)
nanos = int((now - seconds) * 10**9)
Expand Down Expand Up @@ -124,13 +128,13 @@ def monitoring_interval():

def main(event, context):
'''
Cloud Function Entry point, called by the scheduler.
Parameters:
event: Not used for now (Pubsub trigger)
context: Not used for now (Pubsub trigger)
Returns:
'Function executed successfully'
'''
Cloud Function Entry point, called by the scheduler.
Parameters:
event: Not used for now (Pubsub trigger)
context: Not used for now (Pubsub trigger)
Returns:
'Function executed successfully'
'''
# Handling empty monitored projects list
if config["monitored_projects"] == ['']:
config["monitored_projects"] = []
Expand Down Expand Up @@ -203,5 +207,11 @@ def main(event, context):
return 'Function executed successfully'


if __name__ == "__main__":
main(None, None)
if CFv2:

@functions_framework.http
def main_http(request):
main(None, None)
else:
if __name__ == "__main__":
main(None, None)
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ google-cloud-monitoring==2.9.1
oauth2client==4.1.3
google-api-core==2.7.0
PyYAML==6.0
google-cloud-asset==3.8.1
google-cloud-asset==3.8.1
functions-framework==3.*
34 changes: 30 additions & 4 deletions blueprints/cloud-operations/network-dashboard/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ module "service-account-function" {
# Required IAM permissions for this service account are:
# 1) compute.networkViewer on projects to be monitored (I gave it at organization level for now for simplicity)
# 2) monitoring viewer on the projects to be monitored (I gave it at organization level for now for simplicity)
# 3) if you dont have permission to create service account and assign permission at organization Level, move these 3 roles to project level.

iam_organization_roles = {
"${var.organization_id}" = [
"roles/compute.networkViewer",
Expand All @@ -59,17 +61,20 @@ module "service-account-function" {
}

iam_project_roles = {
"${local.monitoring_project}" = [
"roles/monitoring.metricWriter"
]
"${local.monitoring_project}" = compact([
"roles/monitoring.metricWriter",
var.v2 ? "roles/run.invoker" : ""
])
}
}

################################################
# Cloud Function configuration (& Scheduler) #
# you can comment out the pub/sub call in case of 2nd generation function
################################################

module "pubsub" {

source = "../../../modules/pubsub"
project_id = local.monitoring_project
name = "network-dashboard-pubsub"
Expand All @@ -81,6 +86,7 @@ module "pubsub" {
}

resource "google_cloud_scheduler_job" "job" {
count = var.v2 ? 0 : 1
project = local.monitoring_project
region = var.region
name = "network-dashboard-scheduler"
Expand All @@ -92,9 +98,28 @@ resource "google_cloud_scheduler_job" "job" {
data = base64encode("test")
}
}
#http trigger for 2nd generation function

resource "google_cloud_scheduler_job" "job_httptrigger" {
count = var.v2 ? 1 : 0
project = local.monitoring_project
region = var.region
name = "network-dashboard-scheduler"
schedule = var.schedule_cron
time_zone = "UTC"

http_target {
http_method = "POST"
uri = module.cloud-function.uri

oidc_token {
service_account_email = module.service-account-function.email
}
}
}

module "cloud-function" {
v2 = var.v2
source = "../../../modules/cloud-function"
project_id = local.monitoring_project
name = "network-dashboard-cloud-function"
Expand All @@ -115,7 +140,8 @@ module "cloud-function" {
entry_point = "main"
runtime = "python39"
instances = 1
memory = 256
memory = 256 # Memory in MB

}

environment_variables = {
Expand Down
5 changes: 5 additions & 0 deletions blueprints/cloud-operations/network-dashboard/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,9 @@ variable "project_monitoring_services" {
variable "region" {
description = "Region used to deploy the cloud functions and scheduler"
default = "europe-west1"
}
variable "v2" {
description = "Whether to use Cloud Function version 2nd Gen or 1st Gen."
type = bool
default = false
}
12 changes: 7 additions & 5 deletions modules/cloud-function/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ module "cf-http" {
| [bucket_config](variables.tf#L17) | Enable and configure auto-created bucket. Set fields to null to use defaults. | <code title="object&#40;&#123;&#10; location &#61; string&#10; lifecycle_delete_age &#61; number&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [description](variables.tf#L40) | Optional description. | <code>string</code> | | <code>&#34;Terraform managed.&#34;</code> |
| [environment_variables](variables.tf#L46) | Cloud function environment variables. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [function_config](variables.tf#L52) | Cloud function configuration. | <code title="object&#40;&#123;&#10; entry_point &#61; string&#10; instances &#61; number&#10; memory &#61; number&#10; runtime &#61; string&#10; timeout &#61; number&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; entry_point &#61; &#34;main&#34;&#10; instances &#61; 1&#10; memory &#61; 256&#10; runtime &#61; &#34;python37&#34;&#10; timeout &#61; 180&#10;&#125;">&#123;&#8230;&#125;</code> |
| [function_config](variables.tf#L52) | Cloud function configuration. | <code title="object&#40;&#123;&#10; entry_point &#61; string&#10; instances &#61; number&#10; memory &#61; number &#35; Memory in MB&#10; runtime &#61; string&#10; timeout &#61; number&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; entry_point &#61; &#34;main&#34;&#10; instances &#61; 1&#10; memory &#61; 256&#10; runtime &#61; &#34;python37&#34;&#10; timeout &#61; 180&#10;&#125;">&#123;&#8230;&#125;</code> |
| [iam](variables.tf#L70) | IAM bindings for topic in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [ingress_settings](variables.tf#L76) | Control traffic that reaches the cloud function. Allowed values are ALLOW_ALL, ALLOW_INTERNAL_AND_GCLB and ALLOW_INTERNAL_ONLY . | <code>string</code> | | <code>null</code> |
| [labels](variables.tf#L82) | Resource labels. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
Expand All @@ -177,6 +177,7 @@ module "cf-http" {
| [service_account](variables.tf#L122) | Service account email. Unused if service account is auto-created. | <code>string</code> | | <code>null</code> |
| [service_account_create](variables.tf#L128) | Auto-create service account. | <code>bool</code> | | <code>false</code> |
| [trigger_config](variables.tf#L134) | Function trigger configuration. Leave null for HTTP trigger. | <code title="object&#40;&#123;&#10; event &#61; string&#10; resource &#61; string&#10; retry &#61; bool&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [v2](variables.tf#L163) | Whether to use Cloud Function version 2nd Gen or 1st Gen. | <code>bool</code> | | <code>false</code> |
| [vpc_connector](variables.tf#L144) | VPC connector configuration. Set create to 'true' if a new connector needs to be created. | <code title="object&#40;&#123;&#10; create &#61; bool&#10; name &#61; string&#10; egress_settings &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [vpc_connector_config](variables.tf#L154) | VPC connector network configuration. Must be provided if new VPC connector is being created. | <code title="object&#40;&#123;&#10; ip_cidr_range &#61; string&#10; network &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |

Expand All @@ -188,9 +189,10 @@ module "cf-http" {
| [bucket_name](outputs.tf#L24) | Bucket name. | |
| [function](outputs.tf#L29) | Cloud function resources. | |
| [function_name](outputs.tf#L34) | Cloud function name. | |
| [service_account](outputs.tf#L39) | Service account resource. | |
| [service_account_email](outputs.tf#L44) | Service account email. | |
| [service_account_iam_email](outputs.tf#L49) | Service account email. | |
| [vpc_connector](outputs.tf#L57) | VPC connector resource if created. | |
| [service_account](outputs.tf#L42) | Service account resource. | |
| [service_account_email](outputs.tf#L47) | Service account email. | |
| [service_account_iam_email](outputs.tf#L52) | Service account email. | |
| [uri](outputs.tf#L38) | Cloud function service uri. | |
| [vpc_connector](outputs.tf#L60) | VPC connector resource if created. | |

<!-- END TFDOC -->
71 changes: 70 additions & 1 deletion modules/cloud-function/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ locals {
: null
)
)
function = (
var.v2
? google_cloudfunctions2_function.function[0]
: google_cloudfunctions_function.function[0]
)
prefix = var.prefix == null ? "" : "${var.prefix}-"
service_account_email = (
var.service_account_create
Expand Down Expand Up @@ -55,6 +60,7 @@ resource "google_vpc_access_connector" "connector" {
}

resource "google_cloudfunctions_function" "function" {
count = var.v2 ? 0 : 1
project = var.project_id
region = var.region
name = "${local.prefix}${var.name}"
Expand Down Expand Up @@ -122,11 +128,74 @@ resource "google_cloudfunctions_function" "function" {

}

resource "google_cloudfunctions2_function" "function" {
count = var.v2 ? 1 : 0
provider = google-beta
project = var.project_id
location = var.region
name = "${local.prefix}${var.name}"
description = var.description
build_config {
runtime = var.function_config.runtime
entry_point = "${var.function_config.entry_point}_http" # Set the entry point
environment_variables = var.environment_variables
source {
storage_source {
bucket = google_storage_bucket.bucket[0].name
object = google_storage_bucket_object.bundle.name
}
}
}
service_config {
max_instance_count = var.function_config.instances
min_instance_count = 0
available_memory = "${var.function_config.memory}M"
timeout_seconds = var.function_config.timeout
environment_variables = var.environment_variables
ingress_settings = var.ingress_settings
all_traffic_on_latest_revision = true
service_account_email = local.service_account_email
vpc_connector = local.vpc_connector
vpc_connector_egress_settings = try(
var.vpc_connector.egress_settings, null)

dynamic "secret_environment_variables" {
for_each = { for k, v in var.secrets : k => v if !v.is_volume }
iterator = secret
content {
key = secret.key
project_id = secret.value.project_id
secret = secret.value.secret
version = try(secret.value.versions.0, "latest")
}
}

dynamic "secret_volumes" {
for_each = { for k, v in var.secrets : k => v if v.is_volume }
iterator = secret
content {
mount_path = secret.key
project_id = secret.value.project_id
secret = secret.value.secret
dynamic "versions" {
for_each = secret.value.versions
iterator = version
content {
path = split(":", version)[1]
version = split(":", version)[0]
}
}
}
}
}
labels = var.labels
}

resource "google_cloudfunctions_function_iam_binding" "default" {
for_each = var.iam
project = var.project_id
region = var.region
cloud_function = google_cloudfunctions_function.function.name
cloud_function = local.function.name
role = each.key
members = each.value
}
Expand Down
9 changes: 6 additions & 3 deletions modules/cloud-function/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ output "bucket_name" {

output "function" {
description = "Cloud function resources."
value = google_cloudfunctions_function.function
value = local.function
}

output "function_name" {
description = "Cloud function name."
value = google_cloudfunctions_function.function.name
value = local.function.name
}
output "uri" {
description = "Cloud function service uri."
value = var.v2 ? google_cloudfunctions2_function.function[0].service_config[0].uri : null
}

output "service_account" {
description = "Service account resource."
value = try(google_service_account.service_account[0], null)
Expand Down
8 changes: 7 additions & 1 deletion modules/cloud-function/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ variable "function_config" {
type = object({
entry_point = string
instances = number
memory = number
memory = number # Memory in MB
runtime = string
timeout = number
})
Expand Down Expand Up @@ -160,3 +160,9 @@ variable "vpc_connector_config" {
default = null
}

variable "v2" {
description = "Whether to use Cloud Function version 2nd Gen or 1st Gen."
type = bool
default = false
}