Creating a budget trigger that invokes a Cloud Functions function to stop VM instances
Create a budget trigger that invokes a Cloud Functions function. The function will stop Compute Cloud VM instances when their resource use exceeds the budget thresholds.
To deploy a project:
- Download a project.
- Create a service account.
- Prepare a ZIP archive with the function code.
- Create a Cloud Functions function.
- Create a budget.
- Create a budget trigger.
- Create Compute Cloud VM instances.
- Make sure the trigger stops the VM instances.
If you no longer need the resources you created, delete them.
Getting started
Sign up for Yandex Cloud and create a billing account:
- Navigate to the management console
and log in to Yandex Cloud or create a new account. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVEorTRIAL_ACTIVEstatus. If you do not have a billing account, create one and link a cloud to it.
If you have an active billing account, you can navigate to the cloud page
Learn more about clouds and folders here.
Required paid resources
The cost of resources includes:
- Fee for using VM instances (see Compute Cloud pricing).
- Fee for the number of function calls, computing resources allocated to the function, and outbound traffic (see Cloud Functions pricing).
Download a project
Clone the repository with the project:
git clone https://github.com/yandex-cloud-examples/yc-serverless-trigger-budget
Create a service account
- In the management console
, select the folder where you want to create a service account. - In the list of services, select Identity and Access Management.
- Click Create service account.
- Specify a name for the service account:
service-account-for-budget. - Click Add role and assign the
compute.admin,iam.serviceAccounts.user, andfunctions.functionInvokerroles to the service account. - Click Create.
If you do not have the Yandex Cloud CLI installed yet, install and initialize it.
By default, the CLI uses the folder specified when creating the profile. To change the default folder, use the yc config set folder-id <folder_ID> command. You can also set a different folder for any specific command using the --folder-name or --folder-id parameter.
-
Create a service account named
service-account-for-budget:yc iam service-account create --name service-account-for-budgetResult:
id: ajersamh4sjq******** folder_id: b1gc1t4cb638******** created_at: "2022-12-07T10:36:29.726397755Z" name: service-account-for-budget -
Get a list of folders in the cloud:
yc resource-manager folder listResult:
+----------------------+----------------------+--------+--------+ | ID | NAME | LABELS | STATUS | +----------------------+----------------------+--------+--------+ | b1gp7arme3nn******** | my-folder | | ACTIVE | | b1g0itj57rbj******** | test-folder | | ACTIVE | +----------------------+----------------------+--------+--------+Save the ID of the folder where you want to create the service account.
-
Get a list of service accounts in the folder:
yc iam service-account listResult:
+----------------------+------------------------------+ | ID | NAME | +----------------------+------------------------------+ | aje07l4q4vmo******** | test-sa | | ajersamh4sjq******** | service-account-for-budget | +----------------------+------------------------------+Save the
service-account-for-budgetservice account ID. -
Assign the
compute.admin,iam.serviceAccounts.user, andfunctions.functionInvokerroles to the service account:yc resource-manager folder add-access-binding <folder_ID> \ --role compute.admin \ --subject serviceAccount:<service_account_ID> yc resource-manager folder add-access-binding <folder_ID> \ --role iam.serviceAccounts.user \ --subject serviceAccount:<service_account_ID> yc resource-manager folder add-access-binding <folder_ID> \ --role functions.functionInvoker \ --subject serviceAccount:<service_account_ID>Result:
done (1s)
To create a service account, use the create method for the ServiceAccount resource.
To assign the service account the compute.admin, iam.serviceAccounts.user, and functions.functionInvoker roles for the folder, use the setAccessBindings method for the ServiceAccount resource.
Prepare a ZIP archive with the function code
Navigate to the yc-serverless-trigger-budget/steps/2-create-function/ directory and add files to the src.zip archive:
zip src.zip index.go go.mod
Create a Cloud Functions function
- In the management console
, select the folder where you created the service account. - Select Cloud Functions.
- Create a function:
- Click Create function.
- Specify the function name:
function-for-budget. - Click Create.
- Create a function version:
- Select
golang119as the runtime environment, disable the Add files with code examples option, and click Continue. - Specify the ZIP archive upload method and select the archive created in the previous step.
- Specify the entry point:
index.StopComputeInstances. - Under Parameters, specify:
- Timeout:
5 - Memory:
512 MB - Service account:
service-account-for-budget - Environment variables:
FOLDER_ID: ID of the folder where you want the VMs stopped.TAG:target-for-stop.
- Timeout:
- Click Save changes.
- Select
-
Create a function named
function-for-budget:yc serverless function create --name function-for-budgetResult:
done (1s) id: d4eiqjdbqt7s******** folder_id: b1gc1t4cb638******** created_at: "2022-12-07T10:44:13.156Z" name: function-for-budget log_group_id: ckg6bie2rtgd******** http_invoke_url: https://functions.yandexcloud.net/d4eiqjdbqt7s******** status: ACTIVE -
Create a version of the
function-for-budgetfunction:yc serverless function version create \ --function-name function-for-budget \ --memory=512m \ --execution-timeout=5s \ --runtime=golang119 \ --entrypoint=index.StopComputeInstances \ --service-account-id=<service_account_ID> \ --environment FOLDER_ID=<folder_ID> \ --environment TAG=target-for-stop \ --source-path=./src.zipWhere:
--function-name: Name of the function.--memory: Amount of RAM.--execution-timeout: Maximum function execution time.--runtime: Runtime environment.--entrypoint: Entry point.--service-account-id:service-account-for-budgetservice account ID.--environment: Environment variables;FOLDER_ID: ID of the folder where you want the VMs stopped.--source-path: Path to thesrc.ziparchive.
Result:
done (2m7s) id: d4ev38dddr41******** function_id: d4eiqjdbqt7s******** created_at: "2022-12-07T11:14:07.802Z" runtime: golang119 entrypoint: index.StopComputeInstances resources: memory: "536870912" execution_timeout: 5s service_account_id: ajersamh4sjq******** image_size: "19587072" status: ACTIVE tags: - $latest log_group_id: ckg6bie2rtgd******** environment: FOLDER_ID: b1gc1t4cb638******** TAG: target-for-stop log_options: folder_id: b1gc1t4cb638********
To create a function, use the create method for the Function resource.
To create a function version, use the createVersion method for the Function resource.
Create a budget
The user needs the editor role to create a budget. To get notifications, the viewer role is sufficient.
-
Go to Yandex Cloud Billing
. -
Select a billing account.
-
In the General information section, in the ID field, copy the billing account ID. You will need it when creating a trigger for budgets.
-
Go to the Budgets tab and click Create budget.
-
Under General information, specify:
-
Name:
vm-budget. -
Type:
Due and payable. -
Amount: Amount of consumption expenses, e.g.
₽10. -
Calculation period:
Monthly. -
Expires: Budget expiration date.
The end date is when the budget stops calculating usage and sending notifications. The end date is the last day of the month. It must be within five years of the current date.
-
Notify: Select yourself.
-
-
Under Scope, select your current folder and the Compute Cloud service.
-
Under Limits, set the threshold values as a percentage upon reaching which:
- Specified users will get notifications.
- Trigger for budgets will fire.
For example, you can set two thresholds:
50%and100%. -
Click Create.
-
A window will open with the new
vm-budget. In the ID field, copy the ID of the new budget. You will need it later when creating a trigger.
To create a budget, use the create method for the Budget resource or the BudgetService/Create gRPC API call.
Create a budget trigger
-
In the management console
, select the folder where you created the service account, function, and budget. -
Select Cloud Functions.
-
In the left-hand panel, select
Triggers. -
Click Create trigger.
-
Under Basic settings:
- Specify the trigger name:
vm-stop-trigger. - In the Type field, select
Budget. - In the Launched resource field, select
Function.
- Specify the trigger name:
-
Under Budget settings, select your billing account and the
vm-budgetyou created in the previous step. -
Under Function settings, select the
function-for-budgetfunction and specify the following:- Function version tag. The default tag is
$latest. service-account-for-budgetservice account. This is the service account to invoke the function.
- Function version tag. The default tag is
-
Click Create trigger.
To create a budget trigger that invokes the function-for-budget function, run the following command:
yc serverless trigger create billing-budget \
--name vm-stop-trigger \
--billing-account-id <billing_account_ID> \
--budget-id <budget_ID> \
--invoke-function-id <function_ID> \
--invoke-function-service-account-id <service_account_ID>
Where:
--name: Trigger name.--billing-account-id: Billing account ID.--budget-id:vm-budgetID.--invoke-function-id:function-for-budgetID.--invoke-function-service-account-id:service-account-for-budgetservice account ID.
Result:
id: a1sfe084v4**********
folder_id: b1g88tflru**********
created_at: "2022-12-04T08:45:31.131391Z"
name: vm-stop-trigger
rule:
billing-budget:
billing-account-id: dn2char50j**********
budget-id: dn2jnshmdlc1********
invoke_function:
function_id: d4eofc7n0m03********
function_tag: $latest
service_account_id: aje3932acd0c********
status: ACTIVE
Create Compute Cloud VMs
-
Select a subnet:
yc vpc subnet list -
Create a VM:
yc compute instance create \ --name target-instance-1 \ --labels target-for-stop=true \ --zone ru-central1-d \ --network-interface subnet-name=<subnet_name>,nat-ip-version=ipv4 \ --create-boot-disk image-folder-id=standard-images,image-family=ubuntu-2004-lts \ --ssh-key ~/.ssh/<key_name>.pubWhere:
--name: VM name.--labels: Label. If thetarget-for-stoplabel value istrue, the budget trigger will stop the VM when it exceeds the resources allocated in the budget.--zone: Availability zone matching the selected subnet.subnet-name: Name of the selected subnet.nat-ip-version: Public IP.image-family: Image family. This option allows you to install the latest version of the operating system from the specified image family.--ssh-key: Public SSH key path. The VM will automatically create a user namedyc-userfor this key. How to create an SSH key pair.
Result:
done (34s) id: fhm8lon8b9a9******** folder_id: b1gc1t4cb638******** created_at: "2022-12-07T11:29:39Z" name: target-instance-1 labels: target-for-stop: "true" zone_id: ru-central1-d platform_id: standard-v2 resources: memory: "2147483648" cores: "2" core_fraction: "100" status: RUNNING metadata_options: gce_http_endpoint: ENABLED aws_v1_http_endpoint: ENABLED gce_http_token: ENABLED aws_v1_http_token: ENABLED boot_disk: mode: READ_WRITE device_name: fhm459pv68ta******** auto_delete: true disk_id: fhm459pv68ta******** network_interfaces: - index: "0" mac_address: d0:0d:8a:e2:e8:5a subnet_id: e9b3vsm91fl7******** primary_v4_address: address: 10.128.0.4 one_to_one_nat: address: 158.160.47.82 ip_version: IPV4 fqdn: fhm8lon8b9a9********.auto.internal scheduling_policy: {} network_settings: type: STANDARD placement_policy: {}
Similarly, create two more VMs: target-instance-2 and target-instance-3. For the latter, set the target-for-stop label to false.
Make sure the trigger stops the VM instances
Wait until the resource use of your VMs reaches the threshold values specified in your budget. Make sure the budget trigger has invoked the function you created, and target-instance-1 and target-instance-2 have stopped.
How to delete the resources you created
To stop paying for the resources you created: