AZ-301: Microsoft Azure Architect Design

OMG, I got this exam passed in the second attempt. I found this exam is much harder than AZ300, probably because I am quite familiar with Azure Portal so that I can gain more points from labs sections.

In addition, there might be more than one options that can fit for the requirements, you need to select the most appropriate one.

In my first attempt, I used the same strategy as AZ300 - answer questions ASAP and not review to save time for Case Study. However, AZ301 is different, there is plenty of time to analyze the context and review your answers.

The most tricky type of question is True / False, you don’t have chance to go to the previous question, there might be multiple True in one section. DON’T assume the first one always be False and the last one always be True.

Useful resources to prepare the exam

  1. Homepage of AZ 301 - https://www.microsoft.com/en-us/learning/exam-az-301.aspx

  2. Microsoft Hands On Labs - https://handsonlabs.microsoft.com/

  3. Github
  4. Blog - https://pixelrobots.co.uk/2018/10/study-resources-for-the-az-301/

  5. Videos

Lastly, because I bought the Certify with Confidence with Practice Test, I took the advantage of “free” retake once.

AZ-300: Microsoft Azure Architect Technologies

Fortunately I passed AZ-300 today, there were 5 sections including 2 labs on Azure portal. I spent almost 2.5 hours on the first 4 sections, when I started the last case study, less than 2 mins left, so I randomly picked the answers from dropdown.

A few dramas happened:

  • I arrived at the test center 8AM for the 8:15AM test. However, nobody at the concierge until 8:15AM. About 5 people were waiting there, then the test was kicked off about 5 mins late.
  • *One question appeared twice in the first section, I am sure I didn’t click “previous” button by accident.
  • When submitting, the labs’ questions were counted as “not answered”.
  • When submitting, an exception dialog prompted “no internet connection”.

I was very nervous about so many (19) “not answered” red cross icons, I thought I must fail the exam until I got me the “pass” paper.

I am still not sure how labs are calculated, I suppose they should be real time, but why they are marked as “not answered”?

In addition, there was a question exactly the same as my AZ203 test.

Useful resources to prepare the exam

  1. Homepage of AZ 300 - https://www.microsoft.com/en-us/learning/exam-az-300.aspx

  2. Microsoft Hands On Labs - https://handsonlabs.microsoft.com

  3. Github
  4. Blog - https://pixelrobots.co.uk/2018/09/study-resources-for-the-az-300/

  5. Log Analytics Query Demos - https://portal.loganalytics.io/demo#/discover/query/main

  6. Videos

Again practice, practice, practice……

Here are some labs that I’v done before the exam:

  • VNET Peering
  • S2S VPN
  • Sync between AAD Premium V2 and AD on Windows 2016 Data Centre
  • Azure Site Recovery to backup / migrate VMs

NOTE: I bought the Certify with Confidence with Practice Test, because it's a difficult exam and I didn't expect to pass it in the first attempt.

AZ-203: Developing Solutions for Microsoft Azure – What I learned

AZ-203 is my first Microsoft certificate, how awkward? With more than 15 years of working experience on Microsoft stack. Well, this one needs broad knowledge of massive services in Azure, best practices and sometimes the most cost effective way for customers, rather than a particular technique e.g. ASP.NET or SQL Server.

The biggest mistake I made during the exam was that I thought the “Finish” button in each section was to terminate the whole exam. I asked the reception, she had no idea about it. That’s why I spent too much time reviewing all the answers in section 2 and hesitated to click that button. When I jumped to the next section, I had less than 1 hour to complete all the other case studies.

In the exam, be careful about the questions that you can’t review especially True / False ones. It can be partially true, but according to the user story, it might not be appropriate.

Here are some knowledge that I didn’t cover from either work or study:

What you need to remember:

  1. Azure CLI + Powershell, both scripts are needed in test
  2. Security is very important e.g. Encrypt Rest, Always Encrypt, Dynamic Masking, Service Principal, MSI

Tips: Take a glance at questions first, you could exclude some obvious inappropriate answers

Lastly, good luck!!!

AZ-203: Developing Solutions for Microsoft Azure - Resources

Why AZ-203?

  • I have been using Azure for a few years, but I mainly focus on PaaS and Storage (e.g. Azure SQL, Azure Search, CosmosDB, Azure Storage, etc). I would like to test how well I know Microsoft Azure.
  • My goal is to get Azure Solution Architect certificate. In my opinion, Solution Architect must be a good developer.
  • I planned to get 70-532 last year, but the certificate had been re-structured at the end of 2018, instead of getting another transitioning certificate, why not getting the most recent one.

Useful resources to prepare the exam

  1. Homepage of AZ 203 - https://www.microsoft.com/en-us/learning/exam-az-203.aspx

    In “Prepare for exam” section, you can link to Microsoft Learning, which is quite similar to Salesforce Trailhead, it can startup a lab for you to practice for free. I earned 44 badges and level 9 there.

  2. Github
  3. Blog
  4. Videos
    1. Pluralsight - https://app.pluralsight.com/paths/certificate/developing-solutions-for-microsoft-azure-az-203

      There are a few useful videos from my point of view, it might because I was not so familiar with those areas:

    2. Udemy - Scott Duffy - https://www.udemy.com/70532-azure/

Lastly, practice, practice and practice

I have MSDN subscription, I deleted the Resource Group every night when I finished playing. And I have Azure CLI and Powershell installed on my Mac, and my favorite IDE - VSCode.

MusicStore – Part5 – Authorization

Let’s authorize users by their types - ONLY “Musician” can access to Values API.

  1. Include UserType in claims in IdentityServer4

     // ProfileService.cs
     public Task GetProfileDataAsync(ProfileDataRequestContext context)
     {
       var user = _userManager.GetUserAsync(context.Subject).Result;
       if (user != null)
       {
         var claims = new List<Claim>();
         claims.Add(new Claim(AuthorizeClaim.FirstName, string.IsNullOrEmpty(user.FirstName) ? string.Empty : user.FirstName));
         claims.Add(new Claim(AuthorizeClaim.LastName, string.IsNullOrEmpty(user.LastName) ? string.Empty : user.LastName));
         claims.Add(new Claim(AuthorizeClaim.UserType, user.UserType.ToString()));
         context.IssuedClaims.AddRange(claims);
       }
       return Task.FromResult(0);
     }
    
  2. Add authorization policies in WebAPI

    Policies can be built by claim, role, scope or assertion with conditions.

     // Startup.cs
     public void ConfigureServices(IServiceCollection services)
     {
       var svcBuilder = services
         .AddMvcCore()
         .AddApiExplorer()
         .AddJsonFormatters();
    
       svcBuilder = svcBuilder.AddAuthorization(
         options => BuildAuthorizationPolicies(options)
       );
       ......
     }
    
     private void BuildAuthorizationPolicies(AuthorizationOptions options)
     {
       //Basic Policies
       foreach (var userType in Enum.GetNames(typeof(EnumUserType)))
       {
         options.AddPolicy(userType, policy => policy.RequireClaim(AuthorizeClaim.UserType, userType));
       }
     }
    
  3. Add policy to ValuesController to ONLY allow “Musician”

     [Authorize(Policy = AuthorizePolicy.Musician)]
     [Route("api/[controller]")]
     [ApiController]
     public class ValuesController : ControllerBase
     {
         ......
     }
    
  4. Test

    Login with Microsoft account will return 403 when clicking on Sample, as external users are “Audience”.

    However, Alice can get results from Values API, because she belongs to “Musician”.

  5. Lock down permissions for WebUI

    • Add authguard.service.ts to validate UserType from claims

        // authguard.service.ts
        import { Injectable } from '@angular/core';
        import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
        import { OAuthService } from 'angular-oauth2-oidc';
      
        @Injectable()
        export class AuthGuardService implements CanActivate {
            constructor(
                private _oauthService: OAuthService,
                private _router: Router
            )
            {
            }
      
            canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
                var isRoleValid = this._oauthService.hasValidIdToken();
                if (isRoleValid)
                {
                    var expectedRole = route.data.expectedRole;
                    var claims = this._oauthService.getIdentityClaims();
                    if (claims && expectedRole) {
                        if (expectedRole.indexOf(",") >= 0) {
                            var roleArray = expectedRole.split(",");
                            isRoleValid = roleArray.indexOf(claims["UserType"]) >= 0
                        }
                        else {
                            isRoleValid = claims["UserType"] == expectedRole;
                        }
                    }
                }
                if (!isRoleValid) {
                  alert("Sorry, you don't have access to this module!");
                  this._router.navigate(['/']);
                }
                return isRoleValid;
            }
        }
      
    • Apply AuthGuard service to validate role for sample component

        // app.module.ts
        import { BrowserModule } from '@angular/platform-browser';
        import { NgModule } from '@angular/core';
        import { FormsModule } from '@angular/forms';
        import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
        import { RouterModule } from '@angular/router';
      
        //OAuth2 OIDC Client
        import { OAuthModule } from 'angular-oauth2-oidc';
        //Components
        import { AppComponent } from './app.component';
        import { NavMenuComponent } from './nav-menu/nav-menu.component';
        import { HomeComponent } from './home/home.component';
        import { CounterComponent } from './counter/counter.component';
        import { FetchDataComponent } from './fetch-data/fetch-data.component';
        import { SampleComponent } from './sample/sample.component';
        //Http Interceptor
        import { TokenInterceptor } from './http/token.interceptor';
        //Services
        import { UserProfileService } from './userprofile/userprofile.service';
        //Security
        import { AuthGuardService } from './security/authguard.service';
      
        @NgModule({
          declarations: [
            AppComponent,
            NavMenuComponent,
            HomeComponent,
            CounterComponent,
            FetchDataComponent,
            SampleComponent
          ],
          imports: [
            BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
            HttpClientModule,
            FormsModule,
            OAuthModule.forRoot(),
            RouterModule.forRoot([
              { path: '', component: HomeComponent, pathMatch: 'full' },
              { path: 'counter', component: CounterComponent },
              { path: 'fetch-data', component: FetchDataComponent },
              {
                path: 'sample',
                component: SampleComponent,
                canActivate: [AuthGuardService],
                data: {
                  expectedRole: 'Musician'
                }
              }
            ])
          ],
          providers: [
            AuthGuardService,
            UserProfileService,
            {
              provide: HTTP_INTERCEPTORS,
              useClass: TokenInterceptor,
              multi: true,
            }
          ],
          bootstrap: [AppComponent]
        })
        export class AppModule { }
      
  6. Test again

    Login as Microsoft account will see this error message, as it’s been blocked by AuthGuard from front-end part.

    Test User Role