Skip to content

Commit a3ef8a4

Browse files
maddiefordnarrieta
andauthored
Re-enable extension policy tests in daily runbook (#3607)
* Enable ext_policy tests * Address copilot comments --------- Co-authored-by: Norberto Arrieta <narrieta@users.noreply.github.com>
1 parent a5b8cb1 commit a3ef8a4

9 files changed

Lines changed: 140 additions & 32 deletions

File tree

tests_e2e/orchestrator/lib/agent_test_loader.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ class VmImageInfo(object):
8080
locations: Dict[str, List[str]]
8181
# Indicates that the image is available only for those VM sizes. If empty, the image should be available for all VM sizes
8282
vm_sizes: List[str]
83+
# Optional security type (e.g. "ConfidentialVM") to use when deploying this image. When set, the deployment
84+
# is forced to use this security type both for VM (via LISA's Security_Profile requirement) and for VMSS
85+
# (via the 'securityType' parameter in the ARM template). When empty, the default deployment behavior is used.
86+
security_type: str
8387

8488
def __str__(self):
8589
return self.urn
@@ -373,12 +377,16 @@ def _load_images() -> Dict[str, List[VmImageInfo]]:
373377
i.urn = description
374378
i.locations = {}
375379
i.vm_sizes = []
380+
i.security_type = ""
376381
else:
377382
if "urn" not in description:
378383
raise Exception(f"Image {name} is missing the 'urn' property: {description}")
379384
i.urn = description["urn"]
380385
i.locations = description["locations"] if "locations" in description else {}
381386
i.vm_sizes = description["vm_sizes"] if "vm_sizes" in description else []
387+
i.security_type = description["security_type"] if "security_type" in description else ""
388+
if i.security_type not in ("", "ConfidentialVM"):
389+
raise Exception(f"Invalid security_type {i.security_type} for image {name} in images.yml; expected one of '', 'ConfidentialVM'")
382390
for cloud in i.locations.keys():
383391
if cloud not in ["AzureCloud", "AzureChinaCloud", "AzureUSGovernment"]:
384392
raise Exception(f"Invalid cloud {cloud} for image {name} in images.yml")

tests_e2e/orchestrator/lib/agent_test_suite.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ def __init__(self, metadata: TestSuiteMetadata) -> None:
145145
self._location: str # Azure location (region) where test VMs are located
146146
self._image: str # Image used to create the test VMs; it can be empty if LISA chose the size, or when using an existing VM
147147

148+
self._vm_size: str # VM size to use when creating scale sets; empty means use the template default
149+
self._security_type: str # ARM security type (e.g. 'ConfidentialVM') to use when deploying scale sets; empty means template default
150+
148151
self._is_vhd: bool # True when the test VMs were created by LISA from a VHD; this is usually used to validate a new VHD and the test Agent is not installed
149152

150153
# username and public SSH key for the admin account used to connect to the test VMs
@@ -203,6 +206,8 @@ def _initialize(self, environment: Environment, variables: Dict[str, Any], lisa_
203206
self._subscription_id = variables["subscription_id"]
204207
self._location = variables["c_location"]
205208
self._image = variables["c_image"]
209+
self._vm_size = variables["c_vm_size"]
210+
self._security_type = variables["c_security_type"]
206211

207212
self._is_vhd = variables["c_is_vhd"]
208213

@@ -903,7 +908,7 @@ def read_file(path: str) -> str:
903908
if self._allow_ssh != '':
904909
network_security_rule.add_allow_ssh_rule(self._allow_ssh)
905910

906-
return template, {
911+
parameters = {
907912
"username": {"value": self._user},
908913
"sshPublicKey": {"value": read_file(f"{self._identity_file}.pub")},
909914
"vmName": {"value": scale_set_name},
@@ -913,5 +918,17 @@ def read_file(path: str) -> str:
913918
"version": {"value": version}
914919
}
915920

921+
# If the image definition (in images.yml) or the runbook specifies a VM size, use it; otherwise fall back
922+
# to the template default.
923+
if self._vm_size != '':
924+
parameters["vmSize"] = {"value": self._vm_size}
925+
926+
# If the image definition (in images.yml) declares a security type (e.g. 'ConfidentialVM'), set it on the
927+
# scale set; otherwise the template default ('Standard') is used.
928+
if self._security_type != '':
929+
parameters["securityType"] = {"value": self._security_type}
930+
931+
return template, parameters
932+
916933

917934

tests_e2e/orchestrator/lib/agent_test_suite_combinator.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ def create_environment_list(self, test_suites: List[str]) -> List[Dict[str, Any]
204204
continue
205205

206206
vm_size = self._get_vm_size(image)
207+
security_type = image.security_type
207208

208209
locations: List[str] = self._get_locations(test_suite_info, image)
209210
if len(locations) == 0:
@@ -223,6 +224,7 @@ def create_environment_list(self, test_suites: List[str]) -> List[Dict[str, Any]
223224
marketplace_image=marketplace_image,
224225
location=location,
225226
vm_size=vm_size,
227+
security_type=security_type,
226228
test_suite_info=test_suite_info)
227229
else:
228230
env = self.create_vm_environment(
@@ -232,6 +234,7 @@ def create_environment_list(self, test_suites: List[str]) -> List[Dict[str, Any]
232234
shared_gallery=shared_gallery,
233235
location=location,
234236
vm_size=vm_size,
237+
security_type=security_type,
235238
test_suite_info=test_suite_info)
236239
environments.append(env)
237240
else:
@@ -247,6 +250,7 @@ def create_environment_list(self, test_suites: List[str]) -> List[Dict[str, Any]
247250
marketplace_image=marketplace_image,
248251
location=location,
249252
vm_size=vm_size,
253+
security_type=security_type,
250254
test_suite_info=test_suite_info)
251255
else:
252256
env = self.create_vm_environment(
@@ -256,6 +260,7 @@ def create_environment_list(self, test_suites: List[str]) -> List[Dict[str, Any]
256260
shared_gallery=shared_gallery,
257261
location=location,
258262
vm_size=vm_size,
263+
security_type=security_type,
259264
test_suite_info=test_suite_info)
260265
shared_environments[env_name] = env
261266

@@ -371,7 +376,7 @@ def create_existing_vmss_environment(self, test_suites: List[str]) -> Dict[str,
371376
"c_test_suites": loader.test_suites,
372377
}
373378

374-
def create_vm_environment(self, env_name: str, marketplace_image: str, vhd: str, shared_gallery: str, location: str, vm_size: str, test_suite_info: TestSuiteInfo) -> Dict[str, Any]:
379+
def create_vm_environment(self, env_name: str, marketplace_image: str, vhd: str, shared_gallery: str, location: str, vm_size: str, test_suite_info: TestSuiteInfo, security_type: str = "") -> Dict[str, Any]:
375380
#
376381
# Custom ARM templates (to create the test VMs) require special handling. These templates are processed by the azure_update_arm_template
377382
# hook, which does not have access to the runbook variables. Instead, we use a dummy VM tag named "templates" and pass the
@@ -435,9 +440,24 @@ def create_vm_environment(self, env_name: str, marketplace_image: str, vhd: str,
435440
}
436441
]
437442
}
443+
elif security_type == "ConfidentialVM":
444+
# On the VM path LISA performs the deployment, so the security type must be expressed as a LISA feature
445+
# requirement on 'c_platform' (LISA does not look at the 'c_security_type' variable, which is consumed
446+
# only by 'AgentTestSuite' on the VMSS path). This forces LISA to deploy the image as a Confidential VM
447+
# regardless of which security profiles the image and VM size happen to support; without it, LISA's
448+
# priority-based selection may pick a non-CVM profile. Note that LISA's SecurityProfileType enum uses
449+
# the lowercase value 'cvm' (which it maps internally to ARM's 'ConfidentialVM').
450+
environment['c_platform'][0]['requirement']["features"] = {
451+
"items": [
452+
{
453+
"type": "Security_Profile",
454+
"security_profile": "cvm"
455+
}
456+
]
457+
}
438458
return environment
439459

440-
def create_vmss_environment(self, env_name: str, marketplace_image: str, location: str, vm_size: str, test_suite_info: TestSuiteInfo) -> Dict[str, Any]:
460+
def create_vmss_environment(self, env_name: str, marketplace_image: str, location: str, vm_size: str, test_suite_info: TestSuiteInfo, security_type: str = "") -> Dict[str, Any]:
441461
return {
442462
"c_platform": [
443463
{
@@ -461,6 +481,9 @@ def create_vmss_environment(self, env_name: str, marketplace_image: str, locatio
461481
"c_location": location,
462482
"c_image": marketplace_image,
463483
"c_is_vhd": False,
484+
# On the VMSS path the scale set is deployed by 'AgentTestSuite' using our own ARM template
485+
# (vmss.json), bypassing LISA.
486+
"c_security_type": security_type,
464487
"c_vm_size": vm_size,
465488
"vm_tags": {}
466489
}
@@ -484,6 +507,7 @@ def _get_runbook_images(self, loader: AgentTestLoader) -> List[VmImageInfo]:
484507
i.urn = self.runbook.image # Note that this could be a URN or the URI for a VHD, or an image from a shared gallery
485508
i.locations = []
486509
i.vm_sizes = []
510+
i.security_type = ""
487511

488512
return [i]
489513

@@ -503,6 +527,7 @@ def _get_test_suite_images(suite: TestSuiteInfo, loader: AgentTestLoader) -> Lis
503527
i.urn = image
504528
i.locations = []
505529
i.vm_sizes = []
530+
i.security_type = ""
506531
image_list = [i]
507532
else:
508533
image_list = loader.images[image]

tests_e2e/orchestrator/runbook.yml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,8 @@ variable:
4545
- agent_status
4646
- agent_update
4747
- ext_cgroups
48-
#
49-
# TODO: These tests are disabled temporarily since our test account does not have quota to create the Confidential VMs required by the tests.
50-
#
51-
# - ext_policy
52-
# - ext_policy_with_dependencies
48+
- ext_policy
49+
- ext_policy_with_dependencies
5350
- ext_sequencing
5451
- ext_signature_validation
5552
- ext_telemetry_pipeline
@@ -221,6 +218,15 @@ variable:
221218
value: false
222219
is_case_visible: true
223220

221+
#
222+
# Security type to use when deploying the VM/VMSS resource (e.g. "ConfidentialVM"). Empty means use the default
223+
# deployment behavior. Populated by the AgentTestSuiteCombinator from the 'security_type' property on the
224+
# image in images.yml.
225+
#
226+
- name: c_security_type
227+
value: ""
228+
is_case_visible: true
229+
224230
environment: $(c_environment)
225231

226232
platform: $(c_platform)

tests_e2e/orchestrator/templates/vmss.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@
2626
},
2727
"version": {
2828
"type": "string"
29+
},
30+
"vmSize": {
31+
"type": "string",
32+
"defaultValue": "Standard_D2s_v3"
33+
},
34+
"securityType": {
35+
"type": "string",
36+
"defaultValue": "Standard",
37+
"allowedValues": [
38+
"Standard",
39+
"ConfidentialVM"
40+
]
2941
}
3042
},
3143
"variables": {
@@ -167,7 +179,7 @@
167179
"[concat('Microsoft.Network/loadBalancers/', variables('lbName'))]"
168180
],
169181
"sku": {
170-
"name": "Standard_D2s_v3",
182+
"name": "[parameters('vmSize')]",
171183
"tier": "Standard",
172184
"capacity": 3
173185
},
@@ -199,7 +211,8 @@
199211
"createOption": "FromImage",
200212
"caching": "ReadWrite",
201213
"managedDisk": {
202-
"storageAccountType": "Premium_LRS"
214+
"storageAccountType": "Premium_LRS",
215+
"securityProfile": "[if(equals(parameters('securityType'), 'ConfidentialVM'), createObject('securityEncryptionType', 'DiskWithVMGuestState'), json('null'))]"
203216
},
204217
"diskSizeGB": 64
205218
},
@@ -210,6 +223,7 @@
210223
"version": "[parameters('version')]"
211224
}
212225
},
226+
"securityProfile": "[if(equals(parameters('securityType'), 'ConfidentialVM'), createObject('securityType', 'ConfidentialVM', 'uefiSettings', createObject('secureBootEnabled', true(), 'vTpmEnabled', true())), json('null'))]",
213227
"diagnosticsProfile": {
214228
"bootDiagnostics": {
215229
"enabled": true
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
#
22
# The test suite verifies that disallowed extensions are not processed, but the agent should still report status.
33
#
4+
# TODO: This test suite takes ~30 minutes to run. This should be optimized to reduce impact to pipeline run times.
45
name: "ExtensionPolicy"
56
tests:
67
- "ext_policy/ext_policy.py"
78
images:
8-
- "endorsed"
9+
- "random(endorsed,10)" # TODO: Remove randomization and run on all endorsed images once the test suite is optimized to reduce runtime.
910
- "cvm-endorsed"
10-
# This test is executed in southcentralus as a workaround for recurring fabric "ServiceUnavailableFault" issues observed in westus2.
11-
locations: "AzureCloud:southcentralus"
12-
# TODO: This test is currently failing on usgov cloud due to an issue with the GuestConfig extension. Re-enable once the extension fix has been rolled out.
13-
skip_on_clouds:
14-
- "AzureUSGovernment"
1511
owns_vm: false
12+
skip_on_images:
13+
- "AzureChinaCloud:debian_11" # The ConfigurationforLinux-1.26.109 extension is failing on Debian 11 in China cloud only; skip this image until the issue in the extension is fixed

tests_e2e/test_suites/ext_policy_with_dependencies.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
name: "ExtPolicyWithDependencies"
55
tests:
66
- "ext_policy/ext_policy_with_dependencies.py"
7-
images: "endorsed"
7+
images:
8+
- "endorsed"
9+
- "cvm-endorsed"
810
executes_on_scale_set: true
911
owns_vm: false
10-
# This test is executed in southcentralus as a workaround for recurring fabric "ServiceUnavailableFault" issues observed in westus2.
11-
locations: "AzureCloud:southcentralus"
1212

1313
# TODO: Currently AlmaLinux is not available for scale sets; enable this image when it is available.
1414
skip_on_images:
@@ -18,4 +18,4 @@ skip_on_images:
1818

1919
# TODO: The current deployment of VmAccess 1.5.22 prevents the extension from uninstalling; enable this test when the issue is fixed
2020
skip_on_clouds:
21-
- "AzureUSGovernment"
21+
- "AzureUSGovernment"

tests_e2e/test_suites/ext_signature_validation.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ tests:
77
# Extension signature is sent by CRP only for CVMs, so this test suite should run exclusively on CVMs.
88
images: "cvm-endorsed"
99
# Extension signatures are currently only available in the public cloud, so we skip this test on other clouds.
10-
locations: "AzureCloud:westeurope"
1110
skip_on_clouds:
1211
- "AzureChinaCloud"
1312
- "AzureUSGovernment"

0 commit comments

Comments
 (0)