Hi I've followed the guide and I've gone over it twice now and I don't know where I messed up. I can run the "Create a Build IaC Pipeline" just fine and I get no errors. But when I run the "azdo-ci-build-train.yml" script it fails on the unit test and subsequent "Publish linting and unit test".
What do I need to do? I really want to complete this tutorial.
I'm on the Free Trial Sub for the next 33 days, but I'm not sure if I have to sign up for the full services for this to work.
In the guide it states the following below (Note). Does that mean I need to sign up for the Azure AD P1/P2 service?
When I go to Sign-ins in the Azure portal I see:
Access denied
You do not have access
To see sign-in data, upgrade your organization's subscription to include Azure AD P1 or P2. Your current license status: Azure AD Free
Start a free Premium Trial
Note: You must have sufficient permissions to register an application with your Azure AD tenant, and assign the application to a role in your Azure subscription. Contact your subscription administrator if you don't have the permissions. Normally a subscription admin can create a Service principal and can provide you the details.
`##[section]Starting: Run unit tests
Task : Command line
Description : Run a command line script using Bash on Linux and macOS and cmd.exe on Windows
Version : 2.151.2
Author : Microsoft Corporation
Help : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/command-line
Generating script.
Script contents:
pytest --junitxml=/__w/1/b/unit-testresults.xml /__w/1/s/tests/unit
========================== Starting Command Output ===========================
[command]/bin/bash --noprofile --norc /__w/_temp/50f20f82-d423-44ee-9ba0-8d5181b2cc57.sh
============================= test session starts ==============================
platform linux -- Python 3.7.4, pytest-4.3.0, py-1.8.0, pluggy-0.13.0
rootdir: /__w/1/s, inifile:
collected 5 items
tests/unit/code_test.py F [ 20%]
tests/unit/data_test.py .... [100%]
=================================== FAILURES ===================================
______________________________ test_get_workspace ______________________________
self = <msrestazure.azure_active_directory.AdalAuthentication object at 0x7f4d536acb50>
session = <requests.sessions.Session object at 0x7f4d536acb10>
def signed_session(self, session=None):
"""Create requests session with any required auth headers applied.
If a session object is provided, configure it directly. Otherwise,
create a new session and return it.
:param session: The session to configure for authentication
:type session: requests.Session
:rtype: requests.Session
"""
session = super(AdalAuthentication, self).signed_session(session)
try:
raw_token = self._adal_method(*self._args, **self._kwargs)
/usr/local/lib/python3.7/site-packages/msrestazure/azure_active_directory.py:448:
self = <adal.authentication_context.AuthenticationContext object at 0x7f4d536ac950>
resource = 'https://management.core.windows.net/', client_id = ''
client_secret = ''
def acquire_token_with_client_credentials(self, resource, client_id, client_secret):
'''Gets a token for a given resource via client credentials.
:param str resource: A URI that identifies the resource for which the
token is valid.
:param str client_id: The OAuth client id of the calling application.
:param str client_secret: The OAuth client secret of the calling application.
:returns: dict with several keys, include "accessToken".
'''
def token_func(self):
token_request = TokenRequest(self._call_context, self, client_id, resource)
return token_request.get_token_with_client_credentials(client_secret)
return self._acquire_token(token_func)
/usr/local/lib/python3.7/site-packages/adal/authentication_context.py:179:
self = <adal.authentication_context.AuthenticationContext object at 0x7f4d536ac950>
token_func = <function AuthenticationContext.acquire_token_with_client_credentials..token_func at 0x7f4d536a9680>
correlation_id = None
def _acquire_token(self, token_func, correlation_id=None):
self._call_context['log_context'] = log.create_log_context(
correlation_id or self.correlation_id, self._call_context.get('enable_pii', False))
self.authority.validate(self._call_context)
/usr/local/lib/python3.7/site-packages/adal/authentication_context.py:128:
self = <adal.authentication_context.AuthenticationContext object at 0x7f4d536ac950>
def token_func(self):
token_request = TokenRequest(self._call_context, self, client_id, resource)
return token_request.get_token_with_client_credentials(client_secret)
/usr/local/lib/python3.7/site-packages/adal/authentication_context.py:177:
self = <adal.token_request.TokenRequest object at 0x7f4d536aed90>
client_secret = ''
def get_token_with_client_credentials(self, client_secret):
self._log.debug("Getting token with client credentials.")
try:
token = self._find_token_from_cache()
if token:
return token
except AdalError:
self._log.exception('Attempt to look for token in cache resulted in Error')
oauth_parameters = self._create_oauth_parameters(OAUTH2_GRANT_TYPE.CLIENT_CREDENTIALS)
oauth_parameters[OAUTH2_PARAMETERS.CLIENT_SECRET] = client_secret
token = self._oauth_get_token(oauth_parameters)
/usr/local/lib/python3.7/site-packages/adal/token_request.py:310:
self = <adal.token_request.TokenRequest object at 0x7f4d536aed90>
oauth_parameters = {'client_secret': '', 'grant_type': 'client_credentials', 'resource': 'https://management.core.windows.net/'}
def _oauth_get_token(self, oauth_parameters):
client = self._create_oauth2_client()
return client.get_token(oauth_parameters)
/usr/local/lib/python3.7/site-packages/adal/token_request.py:112:
self = <adal.oauth2_client.OAuth2Client object at 0x7f4d536aedd0>
oauth_parameters = {'client_secret': '', 'grant_type': 'client_credentials', 'resource': 'https://management.core.windows.net/'}
def get_token(self, oauth_parameters):
token_url = self._create_token_url()
url_encoded_token_request = urlencode(oauth_parameters)
post_options = util.create_request_options(self, _REQ_OPTION)
operation = "Get Token"
try:
resp = requests.post(token_url.geturl(),
data=url_encoded_token_request,
headers=post_options['headers'],
verify=self._call_context.get('verify_ssl', None),
proxies=self._call_context.get('proxies', None),
timeout=self._call_context.get('timeout', None))
util.log_return_correlation_id(self._log, operation, resp)
except Exception:
self._log.exception("%(operation)s request failed", {"operation": operation})
raise
if util.is_http_success(resp.status_code):
return self._handle_get_token_response(resp.text)
else:
if resp.status_code == 429:
resp.raise_for_status() # Will raise requests.exceptions.HTTPError
return_error_string = _ERROR_TEMPLATE.format(operation, resp.status_code)
error_response = ""
if resp.text:
return_error_string = u"{} and server response: {}".format(return_error_string,
resp.text)
try:
error_response = resp.json()
except ValueError:
pass
raise AdalError(return_error_string, error_response)
E adal.adal_error.AdalError: Get Token request returned http error: 404
/usr/local/lib/python3.7/site-packages/adal/oauth2_client.py:289: AdalError
During handling of the above exception, another exception occurred:
name = 'RHML-AML-WS', resource_group = 'RHML-AML-RG', subscription_id = ''
tenant_id = '', app_id = '', app_secret = ''
def get_workspace(
name: str,
resource_group: str,
subscription_id: str,
tenant_id: str,
app_id: str,
app_secret: str):
service_principal = ServicePrincipalAuthentication(
tenant_id=tenant_id,
service_principal_id=app_id,
service_principal_password=app_secret)
try:
aml_workspace = Workspace.get(
name=name,
subscription_id=subscription_id,
resource_group=resource_group,
ml_service/util/workspace.py:23:
name = 'RHML-AML-WS'
auth = <azureml.core.authentication.ServicePrincipalAuthentication object at 0x7f4d536ace50>
subscription_id = '', resource_group = 'RHML-AML-RG'
@staticmethod
def get(name, auth=None, subscription_id=None, resource_group=None):
"""Return a workspace object for an existing Azure Machine Learning Workspace.
Throws an exception if the workspace does not exist or the required fields
do not uniquely identify a workspace.
:param name: The name of the workspace to get.
:type name: str
:param auth: The authentication object. For more details refer to https://aka.ms/aml-notebook-auth.
If None, the default Azure CLI credentials will be used or the API will prompt for credentials.
:type auth: azureml.core.authentication.ServicePrincipalAuthentication or
azureml.core.authentication.InteractiveLoginAuthentication
:param subscription_id: The subscription ID to use.
The parameter is required if the user has access to more than one subscription.
:type subscription_id: str
:param resource_group: The resource group to use.
If None, the method will search all resource groups in the subscription.
:type resource_group: str
:return: The workspace object.
:rtype: azureml.core.Workspace
"""
if not auth:
auth = InteractiveLoginAuthentication()
# If everything is specified then we use the get operation, which is faster than the list
# operation.
if subscription_id and resource_group:
return Workspace(subscription_id, resource_group, name, auth=auth)
if not subscription_id:
subscription_id = Workspace._fetch_subscription(auth)
/usr/local/lib/python3.7/site-packages/azureml/core/workspace.py:372:
auth = <azureml.core.authentication.ServicePrincipalAuthentication object at 0x7f4d536ace50>
@staticmethod
def _fetch_subscription(auth):
"""Get all subscriptions a user has access to.
If a user has access to only one subscription than that is returned, otherwise an exception is thrown.
:param auth: The authentication object. For more details refer to https://aka.ms/aml-notebook-auth.
:type auth: azureml.core.authentication.AbstractAuthentication
:return: A subscription id
:rtype: str
"""
all_subscriptions = auth._get_all_subscription_ids()
/usr/local/lib/python3.7/site-packages/azureml/core/workspace.py:760:
self = <azureml.core.authentication.ServicePrincipalAuthentication object at 0x7f4d536ace50>
def _get_all_subscription_ids(self):
"""Return a list of subscriptions that are accessible through this authentication.
:return: Returns a list of SubscriptionInfo named tuples.
:rtype: list, str
"""
arm_token = self._get_arm_token()
/usr/local/lib/python3.7/site-packages/azureml/core/authentication.py:842:
self = <azureml.core.authentication.ServicePrincipalAuthentication object at 0x7f4d536ace50>
args = (), kwargs = {}, field_name = '_cached_arm_token'
def wrapper(self, *args, **kwargs):
"""Wrapper.
:param args:
:type args: list
:param kwargs:
:type kwargs: dict
:return: Returns the test function.
:rtype: object
"""
field_name = ServicePrincipalAuthentication._token_type_to_field_dict[token_type]
if self._enable_caching:
cached_token = getattr(self, field_name)
if not cached_token or self._is_token_expired(cached_token):
with ServicePrincipalAuthentication._sp_auth_lock:
# Getting it again after acquiring the lock in case some other thread might have updated it.
cached_token = getattr(self, field_name)
if not cached_token or self._is_token_expired(cached_token):
s = time.time()
module_logger.debug("Calling {} in ServicePrincipalAuthentication "
"to get token.".format(actual_function))
new_token = actual_function(self, *args, **kwargs)
module_logger.debug("{} call completed in {} s".format(
actual_function, (time.time()-s)))
setattr(self, field_name, new_token)
return new_token
else:
return cached_token
else:
return cached_token
else:
return actual_function(self, *args, **kwargs)
/usr/local/lib/python3.7/site-packages/azureml/core/authentication.py:755:
self = <azureml.core.authentication.ServicePrincipalAuthentication object at 0x7f4d536ace50>
@_sp_auth_caching_decorator("ARM_TOKEN")
def _get_arm_token(self):
"""Return arm access token.
:return: Returns arm token from sp credential object
:rtype: str
"""
header = self._get_sp_credential_object().signed_session().headers['Authorization']
/usr/local/lib/python3.7/site-packages/azureml/core/authentication.py:797:
self = <msrestazure.azure_active_directory.AdalAuthentication object at 0x7f4d536acb50>
session = <requests.sessions.Session object at 0x7f4d536acb10>
def signed_session(self, session=None):
"""Create requests session with any required auth headers applied.
If a session object is provided, configure it directly. Otherwise,
create a new session and return it.
:param session: The session to configure for authentication
:type session: requests.Session
:rtype: requests.Session
"""
session = super(AdalAuthentication, self).signed_session(session)
try:
raw_token = self._adal_method(*self._args, **self._kwargs)
except adal.AdalError as err:
# pylint: disable=no-member
if 'AADSTS70008:' in ((getattr(err, 'error_response', None) or {}).get('error_description') or ''):
raise Expired("Credentials have expired due to inactivity.")
else:
raise AuthenticationError(err)
E msrest.exceptions.AuthenticationError: Get Token request returned http error: 404
/usr/local/lib/python3.7/site-packages/msrestazure/azure_active_directory.py:454: AuthenticationError
During handling of the above exception, another exception occurred:
def test_get_workspace():
workspace_name = os.environ.get("BASE_NAME")+"-AML-WS"
resource_group = os.environ.get("BASE_NAME")+"-AML-RG"
subscription_id = os.environ.get("SUBSCRIPTION_ID")
tenant_id = os.environ.get("TENANT_ID")
app_id = os.environ.get("SP_APP_ID")
app_secret = os.environ.get("SP_APP_SECRET")
aml_workspace = get_workspace(
workspace_name,
resource_group,
subscription_id,
tenant_id,
app_id,
tests/unit/code_test.py:23:
name = 'RHML-AML-WS', resource_group = 'RHML-AML-RG', subscription_id = ''
tenant_id = '', app_id = '', app_secret = ''
def get_workspace(
name: str,
resource_group: str,
subscription_id: str,
tenant_id: str,
app_id: str,
app_secret: str):
service_principal = ServicePrincipalAuthentication(
tenant_id=tenant_id,
service_principal_id=app_id,
service_principal_password=app_secret)
try:
aml_workspace = Workspace.get(
name=name,
subscription_id=subscription_id,
resource_group=resource_group,
auth=service_principal)
return aml_workspace
except Exception as caught_exception:
print("Error while retrieving Workspace...")
print(str(caught_exception))
E SystemExit: 1
ml_service/util/workspace.py:29: SystemExit
----------------------------- Captured stdout call -----------------------------
Error while retrieving Workspace...
Get Token request returned http error: 404
=============================== warnings summary ===============================
/usr/local/lib/python3.7/site-packages/socks.py:58
/usr/local/lib/python3.7/site-packages/socks.py:58: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import Callable
/usr/local/lib/python3.7/site-packages/azureml/data/dataset_type_definitions.py:69
/usr/local/lib/python3.7/site-packages/azureml/data/dataset_type_definitions.py:69: DeprecationWarning: FileType Enum is Deprecated in > 1.0.39. Use strings instead.
category=DeprecationWarning)
/usr/local/lib/python3.7/site-packages/azureml/_base_sdk_common/utils.py:11
/usr/local/lib/python3.7/site-packages/azureml/_base_sdk_common/utils.py:11: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import Iterable
-- Docs: https://docs.pytest.org/en/latest/warnings.html
-------------- generated xml file: /__w/1/b/unit-testresults.xml ---------------
================ 1 failed, 4 passed, 3 warnings in 1.68 seconds ================
##[error]Bash exited with code '1'.
##[section]Finishing: Run unit tests
`
`##[section]Starting: Publish linting and unit test results
Timestamp is not available for one or more testsuites. Total run duration is being calculated as the sum of time durations of detected testsuites
Timestamp is not available for one or more testsuites. Total run duration is being calculated as the sum of time durations of detected testsuites
##[section]Async Command Start: Publish test results
Publishing test results to test run '22'
Test results remaining: 17. Test run id: 22
Published Test Run : https://tfsprodcus4.visualstudio.com/Aabd9a587-291d-437a-9967-95c61ab46f08/RH-Project/_TestManagement/Runs?runId=22&_a=runCharts
Publishing test results to test run '24'
Test results remaining: 5. Test run id: 24
Published Test Run : https://tfsprodcus4.visualstudio.com/Aabd9a587-291d-437a-9967-95c61ab46f08/RH-Project/_TestManagement/Runs?runId=24&_a=runCharts
##[error]There are one or more test failures detected in result files. Detailed summary of published test results can be viewed in the Tests tab.
##[section]Async Command End: Publish test results
##[section]Finishing: Publish linting and unit test results
`