Creating a trigger for budgets that invokes a Cloud Functions function to stop VM instances
Create a trigger for budgets that invokes a Cloud Functions function. The function will stop Compute Cloud VM instances when the threshold values specified in the budget are exceeded.
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 trigger for budgets.
- Create Compute Cloud VM instances.
- Check that 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:
- Go to the management console
and log in to Yandex Cloud or create an account if you do not have one yet. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVE
orTRIAL_ACTIVE
status. If you do not have a billing account, create one.
If you have an active billing account, you can go to the cloud page
Learn more about clouds and folders.
Required paid resources
The cost of resources includes:
- Fee for using VMs (see Compute Cloud pricing).
- Fee for the number of function calls, computing resources allocated to a function, and outgoing 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.
- Enter a name for the service account:
service-account-for-budget
. - Click Add role and assign the
compute.admin
,iam.serviceAccounts.user
, andfunctions.functionInvoker
roles to the service account. - Click Create.
If you do not have the Yandex Cloud command line interface yet, install and initialize it.
The folder specified in the CLI profile is used by default. You can specify a different folder 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-budget
Result:
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 list
Result:
+----------------------+----------------------+--------+--------+ | ID | NAME | LABELS | STATUS | +----------------------+----------------------+--------+--------+ | b1gp7arme3nn******** | my-folder | | ACTIVE | | b1g0itj57rbj******** | test-folder | | ACTIVE | +----------------------+----------------------+--------+--------+
Save the ID of the folder to create the service account in.
-
Get a list of service accounts in the folder:
yc iam service-account list
Result:
+----------------------+------------------------------+ | ID | NAME | +----------------------+------------------------------+ | aje07l4q4vmo******** | test-sa | | ajersamh4sjq******** | service-account-for-budget | +----------------------+------------------------------+
Save the
service-account-for-budget
service account ID. -
Assign the
compute.admin
,iam.serviceAccounts.user
, andfunctions.functionInvoker
roles 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
Go 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.
- Enter the function name:
function-for-budget
. - Click Create.
- Create a function version:
- Select
golang119
as 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, sec:
5
- Memory:
512 MB
- Service account:
service-account-for-budget
- Environment variables:
FOLDER_ID
: ID of the folder to stop the VMs in.TAG
:target-for-stop
- Timeout, sec:
- Click Save changes.
- Select
-
Create a function named
function-for-budget
:yc serverless function create --name function-for-budget
Result:
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-budget
function: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.zip
Where:
--function-name
: Name of the function a version of which you are creating.--memory
: Amount of RAM.--execution-timeout
: Maximum function execution time before the timeout is reached.--runtime
: Runtime environment.--entrypoint
: Entry point.--service-account-id
:service-account-for-budget
service account ID.--environment
: Environment variables.FOLDER_ID
: ID of the folder you want to stop the VMs in.--source-path
: Path to thesrc.zip
archive.
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 trigger for budgets
-
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:
- Enter a name for the trigger:
vm-stop-trigger
. - In the Type field, select
Budget
. - In the Launched resource field, select
Function
.
- Enter a name for the trigger:
-
Under Budget settings, select your billing account and the
vm-budget
you created in the previous step. -
Under Function settings, select
function-for-budget
and specify the following:- Function version tag. The default tag is
$latest
. service-account-for-budget
service account. It will be used 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-budget
ID.--invoke-function-id
:function-for-budget
ID.--invoke-function-service-account-id
:service-account-for-budget
service 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 virtual machine:
yc compute instance create \ --name target-instance-1 \ --labels target-for-stop=true \ --zone ru-central1-a \ --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>.pub
Where:
--name
: VM name.--labels
: Label. The trigger for budgets will stop the VM when the threshold values are reached if thetarget-for-stop
label value istrue
.--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 family.--ssh-key
: Public SSH key path. The VM will automatically create a user namedyc-user
for 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-a 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
.
Check that the trigger stops the VM instances
Wait until the threshold values that you specified in the budget are reached. Make sure the trigger for budgets has invoked the function 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: