azure kubernetes service

161 Topics
"}},"componentScriptGroups({\"componentId\":\"custom.widget.MicrosoftFooter\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageListTabs\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageListTabs-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageView/MessageViewInline\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageView/MessageViewInline-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/Pager/PagerLoadMore\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMore-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/OverflowNav\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/OverflowNav-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/nodes/NodeIcon\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageUnreadCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageUnreadCount-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageViewCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageViewCount-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/kudos/KudosCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/kudos/KudosCount-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRepliesCount\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRepliesCount-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1745505307000"}],"cachedText({\"lastModified\":\"1745505307000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505307000"}]},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Deleted","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"MMM dd yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":null,"possibleValues":["en-US","es-ES"]},"repliesSortOrder":{"__typename":"InheritableStringSettingWithPossibleValues","key":"config.user_replies_sort_order","value":"DEFAULT","localValue":"DEFAULT","possibleValues":["DEFAULT","LIKES","PUBLISH_TIME","REVERSE_PUBLISH_TIME"]}},"deleted":false},"CachedAsset:pages-1746564166245":{"__typename":"CachedAsset","id":"pages-1746564166245","value":[{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"UserBlogPermissions.Page","type":"COMMUNITY","urlPath":"/c/user-blog-permissions/page","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllEvents","type":"CUSTOM","urlPath":"/Events","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"CommunityHub.Page","type":"CUSTOM","urlPath":"/Directory","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1730819800000,"localOverride":null,"page":{"id":"AllBlogs.Page","type":"CUSTOM","urlPath":"/blogs","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"HealthCheckPage","type":"COMMUNITY","urlPath":"/health","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1746564166245,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}","userBanned":"We're sorry, but you have been banned from using this site.","userBannedReason":"You have been banned for the following reason: {reason}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:theme:customTheme1-1746564165665":{"__typename":"CachedAsset","id":"theme:customTheme1-1746564165665","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["default"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"favicon-1730836283320.png","imageLastModified":"1730836286415","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"favicon-1730836271365.png","imageLastModified":"1730836274203","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1300px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_BROWSER","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"3px","borderRadius":"3px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"16px","paddingXHero":"60px","fontStyle":"NORMAL","fontWeight":"700","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-200)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-200)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-200-h), var(--lia-bs-gray-200-s), calc(var(--lia-bs-gray-200-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"LIGHT","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.16)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.12)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.3)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-link-color)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","defaultMessageFontFamily":"var(--lia-bs-font-family-base)","forumColor":"#4099E2","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#148563","blogColor":"#1CBAA0","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#4C6B90","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#FF8000","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#D13A1F","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#333333","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#717171","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0069D4","secondary":"#333333","bodyText":"#1E1E1E","bodyBg":"#FFFFFF","info":"#409AE2","success":"#41C5AE","warning":"#FCC844","danger":"#BC341B","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#D3F5A4","#243A5E"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Segoe UI","fontStyle":"NORMAL","fontWeight":"400","h1FontSize":"34px","h2FontSize":"32px","h3FontSize":"28px","h4FontSize":"24px","h5FontSize":"20px","h6FontSize":"16px","lineHeight":"1.3","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":"","imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"40px","defaultMessageHeaderMarginBottom":"20px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"40px","specialMessageHeaderMarginBottom":"20px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Segoe UI","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.5","fontSizeBase":"16px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"14px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[{"source":"SERVER","name":"Segoe UI","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"},{"style":"NORMAL","weight":"300","__typename":"FontStyleData"},{"style":"NORMAL","weight":"600","__typename":"FontStyleData"},{"style":"NORMAL","weight":"700","__typename":"FontStyleData"},{"style":"ITALIC","weight":"400","__typename":"FontStyleData"}],"assetNames":["SegoeUI-normal-400.woff2","SegoeUI-normal-300.woff2","SegoeUI-normal-600.woff2","SegoeUI-normal-700.woff2","SegoeUI-italic-400.woff2"],"__typename":"CustomFont"},{"source":"SERVER","name":"MWF Fluent Icons","styles":[{"style":"NORMAL","weight":"400","__typename":"FontStyleData"}],"assetNames":["MWFFluentIcons-normal-400.woff2"],"__typename":"CustomFont"}],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1745505307000","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1745505307000","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-pages/tags/TagPage-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-pages/tags/TagPage-1745505307000","value":{"tagPageTitle":"Tag:\"{tagName}\" | {communityTitle}","tagPageForNodeTitle":"Tag:\"{tagName}\" in \"{title}\" | {communityTitle}","name":"Tags Page","tag":"Tag: {tagName}"},"localOverride":false},"CachedAsset:quilt:o365.prod:pages/tags/TagPage:community:gxcuf89792-1746740537181":{"__typename":"CachedAsset","id":"quilt:o365.prod:pages/tags/TagPage:community:gxcuf89792-1746740537181","value":{"id":"TagPage","container":{"id":"Common","headerProps":{"removeComponents":["community.widget.bannerWidget"],"__typename":"QuiltContainerSectionProps"},"items":[{"id":"tag-header-widget","layout":"ONE_COLUMN","bgColor":"var(--lia-bs-white)","showBorder":"BOTTOM","sectionEditLevel":"LOCKED","columnMap":{"main":[{"id":"tags.widget.TagsHeaderWidget","__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"},"__typename":"OneColumnQuiltSection"},{"id":"messages-list-for-tag-widget","layout":"ONE_COLUMN","columnMap":{"main":[{"id":"messages.widget.messageListForNodeByRecentActivityWidget","props":{"viewVariant":{"type":"inline","props":{"useUnreadCount":true,"useViewCount":true,"useAuthorLogin":true,"clampBodyLines":3,"useAvatar":true,"useBoardIcon":false,"useKudosCount":true,"usePreviewMedia":true,"useTags":false,"useNode":true,"useNodeLink":true,"useTextBody":true,"truncateBodyLength":-1,"useBody":true,"useRepliesCount":true,"useSolvedBadge":true,"timeStampType":"conversation.lastPostingActivityTime","useMessageTimeLink":true,"clampSubjectLines":2}},"panelType":"divider","useTitle":false,"hideIfEmpty":false,"pagerVariant":{"type":"loadMore"},"style":"list","showTabs":true,"tabItemMap":{"default":{"mostRecent":true,"mostRecentUserContent":false,"newest":false},"additional":{"mostKudoed":true,"mostViewed":true,"mostReplies":false,"noReplies":false,"noSolutions":false,"solutions":false}}},"__typename":"QuiltComponent"}],"__typename":"OneSectionColumns"},"__typename":"OneColumnQuiltSection"}],"__typename":"QuiltContainer"},"__typename":"Quilt"},"localOverride":false},"CachedAsset:quiltWrapper:o365.prod:Common:1746797692760":{"__typename":"CachedAsset","id":"quiltWrapper:o365.prod:Common:1746797692760","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"community.widget.navbarWidget","props":{"showUserName":true,"showRegisterLink":true,"useIconLanguagePicker":true,"useLabelLanguagePicker":true,"className":"QuiltComponent_lia-component-edit-mode__0nCcm","links":{"sideLinks":[],"mainLinks":[{"children":[],"linkType":"INTERNAL","id":"gxcuf89792","params":{},"routeName":"CommunityPage"},{"children":[],"linkType":"EXTERNAL","id":"external-link","url":"/Directory","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft365","params":{"categoryId":"microsoft365"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows","params":{"categoryId":"Windows"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-microsoft365-copilot-link","params":{"categoryId":"Microsoft365Copilot"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-teams","params":{"categoryId":"MicrosoftTeams"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-securityand-compliance","params":{"categoryId":"microsoft-security"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"azure","params":{"categoryId":"Azure"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"Common-content_management-link","params":{"categoryId":"Content_Management"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"exchange","params":{"categoryId":"Exchange"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"windows-server","params":{"categoryId":"Windows-Server"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"outlook","params":{"categoryId":"Outlook"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-endpoint-manager","params":{"categoryId":"microsoftintune"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-2","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities","url":"/","target":"BLANK"},{"children":[{"linkType":"INTERNAL","id":"a-i","params":{"categoryId":"AI"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"education-sector","params":{"categoryId":"EducationSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"partner-community","params":{"categoryId":"PartnerCommunity"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"i-t-ops-talk","params":{"categoryId":"ITOpsTalk"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"healthcare-and-life-sciences","params":{"categoryId":"HealthcareAndLifeSciences"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-mechanics","params":{"categoryId":"MicrosoftMechanics"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"public-sector","params":{"categoryId":"PublicSector"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"s-m-b","params":{"categoryId":"MicrosoftforNonprofits"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"io-t","params":{"categoryId":"IoT"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"startupsat-microsoft","params":{"categoryId":"StartupsatMicrosoft"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"driving-adoption","params":{"categoryId":"DrivingAdoption"},"routeName":"CategoryPage"},{"linkType":"EXTERNAL","id":"external-link-1","url":"/Directory","target":"SELF"}],"linkType":"EXTERNAL","id":"communities-1","url":"/","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external","url":"/Blogs","target":"SELF"},{"children":[],"linkType":"EXTERNAL","id":"external-1","url":"/Events","target":"SELF"},{"children":[{"linkType":"INTERNAL","id":"microsoft-learn-1","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"microsoft-learn-blog","params":{"boardId":"MicrosoftLearnBlog","categoryId":"MicrosoftLearn"},"routeName":"BlogBoardPage"},{"linkType":"EXTERNAL","id":"external-10","url":"https://learningroomdirectory.microsoft.com/","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-3","url":"https://docs.microsoft.com/learn/dynamics365/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-4","url":"https://docs.microsoft.com/learn/m365/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-5","url":"https://docs.microsoft.com/learn/topics/sci/?wt.mc_id=techcom_header-webpage-m365","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-6","url":"https://docs.microsoft.com/learn/powerplatform/?wt.mc_id=techcom_header-webpage-powerplatform","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-7","url":"https://docs.microsoft.com/learn/github/?wt.mc_id=techcom_header-webpage-github","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-8","url":"https://docs.microsoft.com/learn/teams/?wt.mc_id=techcom_header-webpage-teams","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-9","url":"https://docs.microsoft.com/learn/dotnet/?wt.mc_id=techcom_header-webpage-dotnet","target":"BLANK"},{"linkType":"EXTERNAL","id":"external-2","url":"https://docs.microsoft.com/learn/azure/?WT.mc_id=techcom_header-webpage-m365","target":"BLANK"}],"linkType":"INTERNAL","id":"microsoft-learn","params":{"categoryId":"MicrosoftLearn"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"community-info-center","params":{"categoryId":"Community-Info-Center"},"routeName":"CategoryPage"}]},"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","controllerHighlightColor":"hsla(30, 100%, 50%)","linkFontWeight":"400","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkBoxShadowHover":"none","linkFontSize":"14px","backgroundOpacity":0.8,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","hamburgerColor":"var(--lia-nav-controller-icon-color)","linkTextBorderBottom":"none","brandLogoHeight":"30px","linkBgHoverColor":"transparent","linkLetterSpacing":"normal","collapseMenuDividerOpacity":0.16,"dropdownPaddingBottom":"15px","paddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"1px solid var(--lia-bs-border-color)","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","collapseMenuDividerBg":"var(--lia-nav-link-color)","linkColor":"var(--lia-bs-body-color)","linkJustifyContent":"flex-start","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","controllerTextColor":"var(--lia-nav-controller-icon-color)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-body-color)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid var(--lia-bs-body-color)","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","linkPaddingX":"10px","linkPaddingY":"5px","paddingTop":"15px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkBgColor":"transparent","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkDropdownPaddingY":"9px","controllerIconColor":"var(--lia-bs-body-color)","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"var(--lia-bs-body-color)"},"showSearchIcon":false,"languagePickerStyle":"iconAndLabel"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"transparent","linkHighlightColor":"var(--lia-bs-primary)","visualEffects":{"showBottomBorder":true},"linkTextColor":"var(--lia-bs-gray-700)"},"__typename":"QuiltComponent"},{"id":"custom.widget.HeroBanner","props":{"widgetVisibility":"signedInOrAnonymous","usePageWidth":false,"useTitle":true,"cMax_items":3,"useBackground":false,"title":"","lazyLoad":false,"widgetChooser":"custom.widget.HeroBanner"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.MicrosoftFooter","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1745505307000","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.HeroBanner-en-us-1746740524198":{"__typename":"CachedAsset","id":"component:custom.widget.HeroBanner-en-us-1746740524198","value":{"component":{"id":"custom.widget.HeroBanner","template":{"id":"HeroBanner","markupLanguage":"REACT","style":null,"texts":{"searchPlaceholderText":"Search this community","followActionText":"Follow","unfollowActionText":"Following","searchOnHoverText":"Please enter your search term(s) and then press return key to complete a search.","blogs.sidebar.pagetitle":"Latest Blogs | Microsoft Tech Community","followThisNode":"Follow this node","unfollowThisNode":"Unfollow this node"},"defaults":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.HeroBanner","form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":null,"fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[{"id":"max_items","dataType":"NUMBER","list":false,"defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"control":"INPUT","__typename":"PropDefinition"}],"__typename":"ComponentProperties"},"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"},"__typename":"Component","localOverride":false},"globalCss":null,"form":{"fields":[{"id":"widgetChooser","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"title","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useTitle","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"useBackground","validation":null,"noValidation":null,"dataType":"BOOLEAN","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"widgetVisibility","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"moreOptions","validation":null,"noValidation":null,"dataType":"STRING","list":null,"control":null,"defaultValue":null,"label":null,"description":null,"possibleValues":null,"__typename":"FormField"},{"id":"cMax_items","validation":null,"noValidation":null,"dataType":"NUMBER","list":false,"control":"INPUT","defaultValue":"3","label":"Max Items","description":"The maximum number of items to display in the carousel","possibleValues":null,"__typename":"FormField"}],"layout":{"rows":[{"id":"widgetChooserGroup","type":"fieldset","as":null,"items":[{"id":"widgetChooser","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"titleGroup","type":"fieldset","as":null,"items":[{"id":"title","className":null,"__typename":"FormFieldRef"},{"id":"useTitle","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"useBackground","type":"fieldset","as":null,"items":[{"id":"useBackground","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"widgetVisibility","type":"fieldset","as":null,"items":[{"id":"widgetVisibility","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"moreOptionsGroup","type":"fieldset","as":null,"items":[{"id":"moreOptions","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"},{"id":"componentPropsGroup","type":"fieldset","as":null,"items":[{"id":"cMax_items","className":null,"__typename":"FormFieldRef"}],"props":null,"legend":null,"description":null,"className":null,"viewVariant":null,"toggleState":null,"__typename":"FormFieldset"}],"actionButtons":null,"className":"custom_widget_HeroBanner_form","formGroupFieldSeparator":"divider","__typename":"FormLayout"},"__typename":"Form"}},"localOverride":false},"CachedAsset:component:custom.widget.MicrosoftFooter-en-us-1746740524198":{"__typename":"CachedAsset","id":"component:custom.widget.MicrosoftFooter-en-us-1746740524198","value":{"component":{"id":"custom.widget.MicrosoftFooter","template":{"id":"MicrosoftFooter","markupLanguage":"HANDLEBARS","style":".context-uhf {\n min-width: 280px;\n font-size: 15px;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.c-uhff-link {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.c-uhff {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.c-uhff-nav {\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n .c-heading-4 {\n color: #616161;\n word-break: break-word;\n font-size: 15px;\n line-height: 20px;\n padding: 36px 0 4px;\n font-weight: 600;\n }\n .c-uhff-nav-row {\n .c-uhff-nav-group {\n display: block;\n float: left;\n min-height: 1px;\n vertical-align: text-top;\n padding: 0 12px;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 12px;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.c-list.f-bare {\n font-size: 11px;\n line-height: 16px;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 8px 0;\n margin: 0;\n }\n }\n }\n }\n}\n.c-uhff-base {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(1600px + 10%);\n padding: 30px 5% 16px;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.c-uhff-ccpa {\n font-size: 11px;\n line-height: 16px;\n float: left;\n margin: 3px 0;\n }\n a.c-uhff-ccpa:hover {\n text-decoration: underline;\n }\n ul.c-list {\n font-size: 11px;\n line-height: 16px;\n float: right;\n margin: 3px 0;\n color: #616161;\n li {\n padding: 0 24px 4px 0;\n display: inline-block;\n }\n }\n .c-list.f-bare {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 30px 24px 16px;\n }\n}\n\n.social-share {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n\n.sharing-options {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 43px;\n border-radius: 0px 7px 7px 0px;\n}\n.linkedin-icon {\n border-top-right-radius: 7px;\n}\n.linkedin-icon:hover {\n border-radius: 0;\n}\n.social-share-rss-image {\n border-bottom-right-radius: 7px;\n}\n.social-share-rss-image:hover {\n border-radius: 0;\n}\n\n.social-link-footer {\n position: relative;\n display: block;\n margin: -2px 0;\n transition: all 0.2s ease;\n}\n.social-link-footer:hover .linkedin-icon {\n border-radius: 0;\n}\n.social-link-footer:hover .social-share-rss-image {\n border-radius: 0;\n}\n\n.social-link-footer img {\n width: 40px;\n height: auto;\n transition: filter 0.3s ease;\n}\n\n.social-share-list {\n width: 40px;\n}\n.social-share-rss-image {\n width: 40px;\n}\n\n.share-icon {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n\n.share-icon:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n\n.share-icon:hover .label {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n\n.label {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 10px;\n top: 50%;\n transform: translateY(-50%);\n height: 40px;\n border-radius: 0 6px 6px 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px 5px 20px 8px;\n margin-left: -1px;\n}\n.linkedin {\n background-color: #0474b4;\n}\n.facebook {\n background-color: #3c5c9c;\n}\n.twitter {\n background-color: white;\n color: black;\n}\n.reddit {\n background-color: #fc4404;\n}\n.mail {\n background-color: #848484;\n}\n.bluesky {\n background-color: white;\n color: black;\n}\n.rss {\n background-color: #ec7b1c;\n}\n#RSS {\n width: 40px;\n height: 40px;\n}\n\n@media (max-width: 991px) {\n .social-share {\n display: none;\n }\n}\n","texts":{"New tab":"What's New","New 1":"Surface Laptop Studio 2","New 2":"Surface Laptop Go 3","New 3":"Surface Pro 9","New 4":"Surface Laptop 5","New 5":"Surface Studio 2+","New 6":"Copilot in Windows","New 7":"Microsoft 365","New 8":"Windows 11 apps","Store tab":"Microsoft Store","Store 1":"Account Profile","Store 2":"Download Center","Store 3":"Microsoft Store Support","Store 4":"Returns","Store 5":"Order tracking","Store 6":"Certified Refurbished","Store 7":"Microsoft Store Promise","Store 8":"Flexible Payments","Education tab":"Education","Edu 1":"Microsoft in education","Edu 2":"Devices for education","Edu 3":"Microsoft Teams for Education","Edu 4":"Microsoft 365 Education","Edu 5":"How to buy for your school","Edu 6":"Educator Training and development","Edu 7":"Deals for students and parents","Edu 8":"Azure for students","Business tab":"Business","Bus 1":"Microsoft Cloud","Bus 2":"Microsoft Security","Bus 3":"Dynamics 365","Bus 4":"Microsoft 365","Bus 5":"Microsoft Power Platform","Bus 6":"Microsoft Teams","Bus 7":"Microsoft Industry","Bus 8":"Small Business","Developer tab":"Developer & IT","Dev 1":"Azure","Dev 2":"Developer Center","Dev 3":"Documentation","Dev 4":"Microsoft Learn","Dev 5":"Microsoft Tech Community","Dev 6":"Azure Marketplace","Dev 7":"AppSource","Dev 8":"Visual Studio","Company tab":"Company","Com 1":"Careers","Com 2":"About Microsoft","Com 3":"Company News","Com 4":"Privacy at Microsoft","Com 5":"Investors","Com 6":"Diversity and inclusion","Com 7":"Accessiblity","Com 8":"Sustainibility"},"defaults":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.MicrosoftFooter","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"The Microsoft Footer","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":{"css":".custom_widget_MicrosoftFooter_context-uhf_105bp_1 {\n min-width: 17.5rem;\n font-size: 0.9375rem;\n box-sizing: border-box;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n & *,\n & *:before,\n & *:after {\n box-sizing: inherit;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-link_105bp_12 {\n color: #616161;\n word-break: break-word;\n text-decoration: none;\n }\n &a:link,\n &a:focus,\n &a:hover,\n &a:active,\n &a:visited {\n text-decoration: none;\n color: inherit;\n }\n & div {\n font-family: 'Segoe UI', SegoeUI, 'Helvetica Neue', Helvetica, Arial, sans-serif;\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff_105bp_12 {\n background: #f2f2f2;\n margin: -1.5625;\n width: auto;\n height: auto;\n}\n.custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35 {\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 0 5%;\n box-sizing: inherit;\n &:before,\n &:after {\n content: ' ';\n display: table;\n clear: left;\n }\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n .custom_widget_MicrosoftFooter_c-heading-4_105bp_49 {\n color: #616161;\n word-break: break-word;\n font-size: 0.9375rem;\n line-height: 1.25rem;\n padding: 2.25rem 0 0.25rem;\n font-weight: 600;\n }\n .custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57 {\n .custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58 {\n display: block;\n float: left;\n min-height: 0.0625rem;\n vertical-align: text-top;\n padding: 0 0.75rem;\n width: 100%;\n zoom: 1;\n &:first-child {\n padding-left: 0;\n @media only screen and (max-width: 1083px) {\n padding-left: 0.75rem;\n }\n }\n @media only screen and (min-width: 540px) and (max-width: 1082px) {\n width: 33.33333%;\n }\n @media only screen and (min-width: 1083px) {\n width: 16.6666666667%;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n margin-top: 0;\n margin-bottom: 0;\n padding-left: 0;\n list-style-type: none;\n li {\n word-break: break-word;\n padding: 0.5rem 0;\n margin: 0;\n }\n }\n }\n }\n}\n.custom_widget_MicrosoftFooter_c-uhff-base_105bp_94 {\n background: #f2f2f2;\n margin: 0 auto;\n max-width: calc(100rem + 10%);\n padding: 1.875rem 5% 1rem;\n &:before,\n &:after {\n content: ' ';\n display: table;\n }\n &:after {\n clear: both;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: left;\n margin: 0.1875rem 0;\n }\n a.custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107:hover {\n text-decoration: underline;\n }\n ul.custom_widget_MicrosoftFooter_c-list_105bp_78 {\n font-size: 0.6875rem;\n line-height: 1rem;\n float: right;\n margin: 0.1875rem 0;\n color: #616161;\n li {\n padding: 0 1.5rem 0.25rem 0;\n display: inline-block;\n }\n }\n .custom_widget_MicrosoftFooter_c-list_105bp_78.custom_widget_MicrosoftFooter_f-bare_105bp_78 {\n padding-left: 0;\n list-style-type: none;\n }\n @media only screen and (max-width: 1083px) {\n display: flex;\n flex-wrap: wrap;\n padding: 1.875rem 1.5rem 1rem;\n }\n}\n.custom_widget_MicrosoftFooter_social-share_105bp_138 {\n position: fixed;\n top: 60%;\n transform: translateY(-50%);\n left: 0;\n z-index: 1000;\n}\n.custom_widget_MicrosoftFooter_sharing-options_105bp_146 {\n list-style: none;\n padding: 0;\n margin: 0;\n display: block;\n flex-direction: column;\n background-color: white;\n width: 2.6875rem;\n border-radius: 0 0.4375rem 0.4375rem 0;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-top-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_linkedin-icon_105bp_156:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-bottom-right-radius: 7px;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162:hover {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 {\n position: relative;\n display: block;\n margin: -0.125rem 0;\n transition: all 0.2s ease;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_linkedin-icon_105bp_156 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169:hover .custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n border-radius: 0;\n}\n.custom_widget_MicrosoftFooter_social-link-footer_105bp_169 img {\n width: 2.5rem;\n height: auto;\n transition: filter 0.3s ease;\n}\n.custom_widget_MicrosoftFooter_social-share-list_105bp_188 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162 {\n width: 2.5rem;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195 {\n border: 2px solid transparent;\n display: inline-block;\n position: relative;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover {\n opacity: 1;\n border: 2px solid white;\n box-sizing: border-box;\n}\n.custom_widget_MicrosoftFooter_share-icon_105bp_195:hover .custom_widget_MicrosoftFooter_label_105bp_207 {\n opacity: 1;\n visibility: visible;\n border: 2px solid white;\n box-sizing: border-box;\n border-left: none;\n}\n.custom_widget_MicrosoftFooter_label_105bp_207 {\n position: absolute;\n left: 100%;\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all 0.2s ease;\n color: white;\n border-radius: 0 10 0 0.625rem;\n top: 50%;\n transform: translateY(-50%);\n height: 2.5rem;\n border-radius: 0 0.375rem 0.375rem 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1.25rem 0.3125rem 1.25rem 0.5rem;\n margin-left: -0.0625rem;\n}\n.custom_widget_MicrosoftFooter_linkedin_105bp_156 {\n background-color: #0474b4;\n}\n.custom_widget_MicrosoftFooter_facebook_105bp_237 {\n background-color: #3c5c9c;\n}\n.custom_widget_MicrosoftFooter_twitter_105bp_240 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_reddit_105bp_244 {\n background-color: #fc4404;\n}\n.custom_widget_MicrosoftFooter_mail_105bp_247 {\n background-color: #848484;\n}\n.custom_widget_MicrosoftFooter_bluesky_105bp_250 {\n background-color: white;\n color: black;\n}\n.custom_widget_MicrosoftFooter_rss_105bp_254 {\n background-color: #ec7b1c;\n}\n#custom_widget_MicrosoftFooter_RSS_105bp_1 {\n width: 2.5rem;\n height: 2.5rem;\n}\n@media (max-width: 991px) {\n .custom_widget_MicrosoftFooter_social-share_105bp_138 {\n display: none;\n }\n}\n","tokens":{"context-uhf":"custom_widget_MicrosoftFooter_context-uhf_105bp_1","c-uhff-link":"custom_widget_MicrosoftFooter_c-uhff-link_105bp_12","c-uhff":"custom_widget_MicrosoftFooter_c-uhff_105bp_12","c-uhff-nav":"custom_widget_MicrosoftFooter_c-uhff-nav_105bp_35","c-heading-4":"custom_widget_MicrosoftFooter_c-heading-4_105bp_49","c-uhff-nav-row":"custom_widget_MicrosoftFooter_c-uhff-nav-row_105bp_57","c-uhff-nav-group":"custom_widget_MicrosoftFooter_c-uhff-nav-group_105bp_58","c-list":"custom_widget_MicrosoftFooter_c-list_105bp_78","f-bare":"custom_widget_MicrosoftFooter_f-bare_105bp_78","c-uhff-base":"custom_widget_MicrosoftFooter_c-uhff-base_105bp_94","c-uhff-ccpa":"custom_widget_MicrosoftFooter_c-uhff-ccpa_105bp_107","social-share":"custom_widget_MicrosoftFooter_social-share_105bp_138","sharing-options":"custom_widget_MicrosoftFooter_sharing-options_105bp_146","linkedin-icon":"custom_widget_MicrosoftFooter_linkedin-icon_105bp_156","social-share-rss-image":"custom_widget_MicrosoftFooter_social-share-rss-image_105bp_162","social-link-footer":"custom_widget_MicrosoftFooter_social-link-footer_105bp_169","social-share-list":"custom_widget_MicrosoftFooter_social-share-list_105bp_188","share-icon":"custom_widget_MicrosoftFooter_share-icon_105bp_195","label":"custom_widget_MicrosoftFooter_label_105bp_207","linkedin":"custom_widget_MicrosoftFooter_linkedin_105bp_156","facebook":"custom_widget_MicrosoftFooter_facebook_105bp_237","twitter":"custom_widget_MicrosoftFooter_twitter_105bp_240","reddit":"custom_widget_MicrosoftFooter_reddit_105bp_244","mail":"custom_widget_MicrosoftFooter_mail_105bp_247","bluesky":"custom_widget_MicrosoftFooter_bluesky_105bp_250","rss":"custom_widget_MicrosoftFooter_rss_105bp_254","RSS":"custom_widget_MicrosoftFooter_RSS_105bp_1"}},"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1745505307000","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagsHeaderWidget-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagsHeaderWidget-1745505307000","value":{"tag":"{tagName}","topicsCount":"{count} {count, plural, one {Topic} other {Topics}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageListForNodeByRecentActivityWidget-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageListForNodeByRecentActivityWidget-1745505307000","value":{"title@userScope:other":"Recent Content","title@userScope:self":"Contributions","title@board:FORUM@userScope:other":"Recent Discussions","title@board:BLOG@userScope:other":"Recent Blogs","emptyDescription":"No content to show","MessageListForNodeByRecentActivityWidgetEditor.nodeScope.label":"Scope","title@instance:1722894000155":"Recent Discussions","title@instance:1727367112619":"Recent Blog Articles","title@instance:1727367069748":"Recent Discussions","title@instance:1727366213114":"Latest Discussions","title@instance:1727899609720":"","title@instance:1727363308925":"Latest Discussions","title@instance:1737115580352":"Latest Articles","title@instance:1720453418992":"Recent Discssions","title@instance:1727365950181":"Latest Blog Articles","title@instance:bmDPnI":"Latest Blog Articles","title@instance:IiDDJZ":"Latest Blog Articles","title@instance:1721244347979":"Latest blog posts","title@instance:1728383752171":"Related Content","title@instance:1722893956545":"Latest Skilling Resources","title@instance:dhcgCU":"Latest Discussions"},"localOverride":false},"Category:category:Exchange":{"__typename":"Category","id":"category:Exchange","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Outlook":{"__typename":"Category","id":"category:Outlook","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Community-Info-Center":{"__typename":"Category","id":"category:Community-Info-Center","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:EducationSector":{"__typename":"Category","id":"category:EducationSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:DrivingAdoption":{"__typename":"Category","id":"category:DrivingAdoption","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Azure":{"__typename":"Category","id":"category:Azure","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"displayId":"Azure"},"Category:category:Windows-Server":{"__typename":"Category","id":"category:Windows-Server","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftTeams":{"__typename":"Category","id":"category:MicrosoftTeams","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PublicSector":{"__typename":"Category","id":"category:PublicSector","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft365":{"__typename":"Category","id":"category:microsoft365","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:IoT":{"__typename":"Category","id":"category:IoT","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:HealthcareAndLifeSciences":{"__typename":"Category","id":"category:HealthcareAndLifeSciences","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:ITOpsTalk":{"__typename":"Category","id":"category:ITOpsTalk","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftLearn":{"__typename":"Category","id":"category:MicrosoftLearn","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Blog:board:MicrosoftLearnBlog":{"__typename":"Blog","id":"board:MicrosoftLearnBlog","blogPolicies":{"__typename":"BlogPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:AI":{"__typename":"Category","id":"category:AI","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"displayId":"AI"},"Category:category:MicrosoftMechanics":{"__typename":"Category","id":"category:MicrosoftMechanics","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:MicrosoftforNonprofits":{"__typename":"Category","id":"category:MicrosoftforNonprofits","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:StartupsatMicrosoft":{"__typename":"Category","id":"category:StartupsatMicrosoft","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:PartnerCommunity":{"__typename":"Category","id":"category:PartnerCommunity","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Microsoft365Copilot":{"__typename":"Category","id":"category:Microsoft365Copilot","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Windows":{"__typename":"Category","id":"category:Windows","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:Content_Management":{"__typename":"Category","id":"category:Content_Management","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoft-security":{"__typename":"Category","id":"category:microsoft-security","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:microsoftintune":{"__typename":"Category","id":"category:microsoftintune","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Conversation:conversation:4083413":{"__typename":"Conversation","id":"conversation:4083413","topic":{"__typename":"BlogTopicMessage","uid":4083413},"lastPostingActivityTime":"2024-03-19T16:59:21.741-07:00","solved":false},"Blog:board:Azure-AI-Services-blog":{"__typename":"Blog","id":"board:Azure-AI-Services-blog","displayId":"Azure-AI-Services-blog","nodeType":"board","conversationStyle":"BLOG","title":"AI - Azure AI services Blog","shortTitle":"AI - Azure AI services Blog","parent":{"__ref":"Category:category:AI"}},"User:user:1777264":{"__typename":"User","uid":1777264,"login":"mtoiba","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS0xNzc3MjY0LTU2MDg4M2k3MkYyM0QwRUI4MDQzOEFG"},"id":"user:1777264"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MjYxNWk1MDBEOTg0MEY2MDdCNzZF?revision=32\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MjYxNWk1MDBEOTg0MEY2MDdCNzZF?revision=32","title":"Intelligent apps thumb .jpg","associationType":"TEASER","width":864,"height":576,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MzAyMGk5QTEyNDBDQkJDRENFQjRG?revision=32\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MzAyMGk5QTEyNDBDQkJDRENFQjRG?revision=32","title":"mtoiba_1-1710870117011.png","associationType":"BODY","width":1062,"height":560,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTczMGlGNEMyQ0JBNDM1OUI3MDY1?revision=32\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTczMGlGNEMyQ0JBNDM1OUI3MDY1?revision=32","title":"mtoiba_0-1710469807901.png","associationType":"BODY","width":975,"height":511,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MzAyNmlEQzczQjE3MTM5QTE1RjZB?revision=32\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MzAyNmlEQzczQjE3MTM5QTE1RjZB?revision=32","title":"mtoiba_0-1710871478545.png","associationType":"BODY","width":1056,"height":568,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTczNWk5MUEwQTA2NkY3OTYyNDQw?revision=32\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTczNWk5MUEwQTA2NkY3OTYyNDQw?revision=32","title":"mtoiba_0-1710470441813.png","associationType":"BODY","width":975,"height":511,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTczN2lEQURGRTg2QjcyNDUwMDEz?revision=32\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTczN2lEQURGRTg2QjcyNDUwMDEz?revision=32","title":"mtoiba_0-1710471311435.png","associationType":"BODY","width":975,"height":510,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTc0MGk3MEU4MjQ4ODVERENFNkI3?revision=32\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTc0MGk3MEU4MjQ4ODVERENFNkI3?revision=32","title":"mtoiba_1-1710471590278.png","associationType":"BODY","width":767,"height":567,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTc0MWkxQURCNTY2OERGMjhENkFC?revision=32\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTc0MWkxQURCNTY2OERGMjhENkFC?revision=32","title":"mtoiba_2-1710471848692.png","associationType":"BODY","width":975,"height":511,"altText":null},"BlogTopicMessage:message:4083413":{"__typename":"BlogTopicMessage","subject":"AI in action: 5 real-world intelligent apps you can build on Azure","conversation":{"__ref":"Conversation:conversation:4083413"},"id":"message:4083413","revisionNum":32,"uid":4083413,"depth":0,"board":{"__ref":"Blog:board:Azure-AI-Services-blog"},"author":{"__ref":"User:user:1777264"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" \n Build your own copilot. Process transactions at scale. Detect fraud. Offer recommendations -- learn how to build all these AI-powered apps and more. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":45032},"postTime":"2024-03-18T14:57:34.072-07:00","lastPublishTime":"2024-03-19T16:59:21.741-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Artificial intelligence (AI) is transforming the way we interact with technology, data, and each other. AI can help us create more engaging, personalized, and efficient experiences for customers and employees. To stay ahead in the era of AI, businesses are embracing intelligent applications across industries to take advantage of new opportunities. How can you use AI to modernize and build new digital products in your field? In this blog post, we dive into 5 types of AI-powered apps you can create with Azure’s generative AI technology, cloud-scale data, and modern application platforms. We look at how industry leaders are modernizing and innovating with AI, present sample architectures, and offer solution accelerators to help you kickstart your own app development. \n   \n What are intelligent apps? \n Intelligent, or AI-powered, apps leverage AI models to enhance or automate some aspects of their functionality. AI-powered apps can leverage various capabilities, such as natural language processing, computer vision, speech recognition, machine learning, and generative AI, to provide more intelligent and responsive experiences. \n   \n You can achieve tangible and meaningful business outcomes by infusing AI into your apps. A Forrester study found that organizations using Azure managed app, data, and AI services can ship applications up to 1.5 months faster. Organizations also see an increase of up to 25% in developer productivity, allowing development teams to focus less on mundane work, and more on innovation. Azure technologies are also helping organizations reduce app downtime by up to 25%, enabling better performance and reduced risk. \n   \n Here are 5 types of apps customers are building on Azure to take advantage of these and other business benefits. \n \n Connected products \n Transaction processing at scale \n Support bots and information discovery \n Personalization and recommendations \n AI copilots \n \n Connected products \n Connected smart products interact with other devices and systems through the internet. They utilize sensors, processors, services, and communication hardware which collect data, analyze it, and take actions autonomously. AI-enhanced connected products use data gathered from devices to inform intelligent models which can adapt to user preferences and provide personalized experiences. Examples include: \n \n Smart home devices: thermostats, lighting systems, and security cameras. \n Wearable health trackers: Smartwatches, fitness trackers, and medical devices. \n Connected cars: GPS systems, real-time traffic updates, and voice control. \n Industrial IoT: Remote monitoring and asset tracking. \n Intelligent retail: Smart shelves that track inventory and self-checkout systems. \n Supply chains: Using IoT data to detect inefficiencies and forecast demand. \n \n Let’s look at a real-world example. Mercedes-Benz built their connected car platform on Azure using cloud-native services and generative AI. They first modernized their platform using Azure Cosmos DB and Azure Kubernetes Service (AKS), allowing them to quickly update and release new features, while preserving the quality and security of vehicle data. Then they brought in generative AI capabilities to transform their driver experience, creating a voice assistant that understands voice commands and engages in interactive conversations. \n   \n Build your own solution \n Azure’s modern application platform of AI, apps, and database services leverages cloud-scale data, agile development methods with DevOps, and pretrained and responsible AI needed for today’s connected smart products. Here’s a sample architecture for an AI-powered industrial IoT solution for predictive maintenance, that uses Azure AI Services, Azure Cosmos DB, and AKS. \n   \n \n This example shows an IoT platform in Azure that helps with manufacturing data analysis, and service and maintenance issues. The Intelligent Maintenance Guide uses generative AI and chat features for real-time alerts and guidance on how to resolve maintenance issues. The application runs on AKS and uses Azure Cosmos DB for machine-specific status and alert data, as well as chat history. Azure AI Search acts as the search and retrieval system, surfacing relevant data to Azure OpenAI Service.    \n Additional resources: \n \n Industrial IoT prediction patterns \n Azure Cosmos DB in IoT workloads \n Cargo logistics/vehicle telemetry scenario and architecture \n \n   \n Transaction processing at scale \n Processing billions of transactions daily is the new normal across industries, from e-commerce to healthcare. Transaction processing at scale (TPaS) refers to handling a high volume of transactions swiftly, accurately, and reliably. AI-based TPaS can analyze transactions against business rules, detect anomalies, and identify potential fraud. GenAI can be used to add natural language UX interactions and data summarization for users. Scenarios where AI-powered TPaS is used include: \n \n E-commerce/retail: Customer orders, payments, and buy online, pick up in store (BOPIS). \n Banking and finance: Deposits, withdrawals, transfers, and credit card transactions. \n Travel and hospitality: Reservations, ticketing, and payment processing. \n Healthcare: Appointment scheduling, billing, and insurance claims. \n Supply chain and logistics: Inventory management, shipping transactions, and tracking of goods. \n Digital advertising: Ad placements, impressions, clicks, and conversions. \n Fraud/anomaly detection: TPaS with AI can also be used to identify patterns, anomalies, or suspicious activities in real-time across vast amounts of transactions. \n \n In the travel industry, American Airlines modernized its Customer Hub app on Azure, allowing it to handle massive volumes of transactions including more than 16 million real-time messages and 17.4 million service calls per day. On top of this, American Airlines is applying AI and machine learning to company operations, helping reduce taxi time and provide real-time information to maintenance personnel and other airline staff. \n An example of fraud detection, Manulife migrated to the cloud and took advantage of several Azure AI services, including Azure Document Intelligence, and Azure Machine Learning to help with data correlation and fraud detection. As part of their migration, Manulife used services such as AKS and Azure SQL Managed Instance to save on costs, get to market faster, and respond to customer demands more readily. \n   \n Build your own solution \n Here is an architecture example for a real-time payments and transactions application leveraging Azure OpenAI Service, Azure Cosmos DB, AKS, Azure Functions, and Azure Event Hubs: \n   \n \n The scenario involves members who have accounts, each account with corresponding balances, overdraft limits, and credit/debit transactions. Transaction data is replicated across multiple geographic regions for both reads and writes, while maintaining consistency. Updates are made efficiently with the patch operation. Business rules govern if a transaction is allowed. An AI powered co-pilot enables agents to analyze transactions using natural language. \n Here’s another reference architecture for real-time fraud detection: \n \n In this scenario, payment transactions are processed by Azure Cosmos DB, with real-time analytics using Synapse Link/Microsoft Fabric mirroring. Financial transactions are integrated with Microsoft Fabric using Data Factory in Fabric and stored in OneLake. GenAI powers the fraud analysis tool using retrieval augmented generation (RAG), with Azure OpenAI Service for the LLM, and Azure AI Search as the retrieval system, enabling real-time fraud alerts and deeper analysis over client profiles. \n   \n Additional resources: \n \n Real-time payment and transaction processing solution accelerator \n Transaction processing demo walkthrough \n Transaction processing hackathon \n Implementation of anomaly detection process \n \n   \n Support bots and information discovery \n Service and support bot applications use AI to improve customer service interactions and processes. Such applications can provide personalized experiences to customers and help users extract key information and insights from large volumes of data. Techniques include: natural language processing (NLP) for understanding text and sentiment analysis; machine learning for identifying patterns and making predictions; knowledge mining for exploring and analyzing structured and unstructured data; and RAG for retrieving data/documents relevant to a query or task and providing them as context for the LLM. Example applications include: \n \n Chatbots and virtual assistants: Can answer questions, extract knowledge, and help with troubleshooting \n Intelligent search engines: Can provide more accurate and relevant search results \n Product catalog discovery: Use of NLP, image analysis, and user preference analysis to provide product recommendations. \n Drug discovery: AI can be used to optimize drug design and testing, predict drug properties, and enable molecular simulations. \n Automated report generation and summarization: Can analyze data, extract information, and present it in a structured format. \n Voice and speech recognition: Enable automated call routing and voice-based interactions. \n \n Let’s review some ways that real businesses are employing AI-powered support bots and information discovery. \n TomTom, a leader in maps and location technology, used GenAI to create their Digital Cockpit, a conversational automotive assistant enabling voice interaction with infotainment, location search, and vehicle commands. Using Azure OpenAI Service, Azure Cosmos DB, and AKS, they built an intelligent, fast, and highly scalable AI chatbot that can be integrated into other automotive systems. In another example, Bengo4.com Inc., a Japanese company that operates professional services websites, built an AI-powered legal consultation chatbot using Azure Cosmos DB, AKS, and Azure OpenAI Service. When users ask the chatbot a question, it retrieves and summarizes pages in law books that are relevant to the query, helping professionals cut down on legal research time. \n Lastly, by removing data silos and going fully cloud native with services such as Azure Cosmos DB, H&R Block has been able to unlock AI-powered information discovery capabilities. Aiming to streamline tax filing and make it less stressful for both clients and tax professionals, H&R Block uses Azure Machine Learning and Azure AI to provide detailed client history in seconds. Accessing this information fast allows H&R Block tax pros to provide a differentiated client experience. \n   \n Build your own solution \n Below is a sample architecture for a service and support bot in an airline customer service scenario: \n   \n \n This intelligent application has two interfaces – a customer-facing online support portal and an internal Customer Support System application. Azure Front Door provides a single-entry point (contoso.com) for multi-region architecture. Raw data from flight booking systems, luggage tracking, customer account data, and travel policies are stored in Azure Cosmos DB. AKS hosts the web UI and integrates other components of the solution. The application uses RAG, with Azure AI Search as the retrieval system and Azure OpenAI Service providing Large Language Model (LLM) capabilities, allowing customer service reps and customers to ask questions using natural language. \n   \n Additional resources: \n \n Build your own copilot/AI assistant with solution accelerator \n Build an automated document processing pipeline \n Create an insurance claims processing AI agent with solution accelerator \n Implement RAG with samples using Azure Data, Apps, and AI Services \n Try Azure AI Studio to simplify your AI app dev. Select optimal models, design and assess prompts, develop custom AI search functionalities, ensure content safety, deploy and scale, and monitor applications in production. \n \n   \n Personalization and recommendations \n AI-based personalization and recommendation apps tailor content, products, or services to individuals based on their behavior, preferences, and needs. Customers expect top-notch digital experiences today – personalization helps businesses deliver on this by providing real-time recommendations and dynamic customer engagement. Examples of personalization include: \n \n Product recommendations in e-commerce/retail: AI engines analyze customer behavior, purchase history, and preferences to provide product recommendations, enhancing the shopping experience. \n Streaming content recommendations: Platforms like Netflix and Spotify use AI to provide personalized content suggestions, helping users discover new content aligned with their interests. \n Targeted advertising: AI algorithms analyze user data, browsing behavior, and demographic information to deliver targeted and personalized ads, improving ad relevance and click-through rates. \n Financial recommendations: AI provides personalized advice on investment, retirement planning, and loan offers, based on individual financial goals, risk profiles, and spending patterns. \n Personalized learning: Educational platforms use AI to provide personalized learning paths, adaptive assessments, and customized content to students, helping improve educational outcomes. \n \n Sitting on a treasure trove of game and player data, the NBA used Azure to build an AI-powered content personalization engine to elevate the digital fan experience. The NBA CourtOptix platform leverages Azure AI services, Azure Machine Learning, AKS, and Azure Cosmos DB to turn billions of data points into insightful metrics about players. It personalizes these statistical insights into content that is tailored to fan preferences. \n   \n ASOS, a global online retailer with more than 26 million active customers, runs a microservices architecture on Azure, with Azure Cosmos DB and Azure Kubernetes Service powering a real-time recommendations engine at enormous scale for ASOS shoppers. The retailer is further enhancing its customer experience by using Azure OpenAI Service and prompt flow in Azure AI Studio to create a natural language-based conversational interface to curate product selections for shoppers. \n   \n Build your own solution \n   \n Check out this reference architecture for a product recommendation engine. \n   \n \n In this scenario, product data, customer profiles, and other information are stored in Azure Cosmos DB, while static content is stored in Azure Blob Storage. Azure AI Search creates a semantic vector index and acts as the retrieval system for Azure Machine Learning. Azure Machine Learning provides machine learning models for product recommendations, creating customer personas and identifying available products and promotions. \n   \n Additional resources: \n \n Build a real-time recommendation engine on Azure (content recommendations scenario) \n Create personalized offers for customers (e-commerce/retail scenario) \n \n   \n Copilots for everything, everyone \n AI copilots are an exciting type of intelligent application that is transforming the way we create and communicate. Copilots go beyond traditional chatbots. They enable rich and contextual interactions and can extract insights from vast amounts of data in an interactive natural language user interface. \n With the emergence and massive popularity of ChatGPT, nearly every industry is looking to take advantage of generative AI applications – and copilots are the answer. These large language model-based assistants are unlocking the art of the possible across different domains and for a variety of users by enabling them to perform tasks more efficiently and effectively. \n   \n \n The opportunities to utilize copilots are endless. They can power nearly every other use case highlighted in this blog and more. \n You can build an AI chatbot copilot, a product recommender copilot, a speech and image recognition copilot, a copilot to create and optimize code for a variety of industries, a content generation and summarization copilot, and so on. No less important, copilots can integrate with different applications and platforms to enable seamless communication, data exchange, and enhanced user experiences. \n Among the most common examples, organizations are using copilots to: \n \n Chat with their data: Interacting with data with natural language to summarize content and get faster access to critical information. \n Generate content dynamically: Employing AI to optimize and update existing creative, and build new creative assets. \n Discover information: Interactive user interface can answer common questions, provide information, and help with troubleshooting. \n Personalize experiences: Offering product and content recommendations to individual users, based on their behavior and preferences. \n \n KPMG Australia developed their own copilot app, KymChat, a conversational AI assistant, to help the firm’s 10,000 employees improve productivity. The ChatGPT-based AI assistant helps employees automate mundane tasks and surface insights from the company’s external and internal websites, knowledge bases, and Microsoft 365 files. To keep up with the growth of the solution, KPMG Australia used Azure Cosmos DB for MongoDB vCore, Azure OpenAI Service and Azure App Service, enabling KymChat to deliver faster and higher-quality search results at scale. \n   \n Build your own solution \n Here is an example architecture for an intelligent agent copilot within a consumer retail scenario. The app allows users to ask questions on vectorized product, customer, and sales order data stored in the database. \n   \n \n In this scenario, customers of a retail bike store interact with an AI agent to ask questions ranging from product recommendations to information on customer profiles and sales orders. The solution is designed to also enable fast updates to data, demonstrating how adding or updating an item in the product catalog can be used in near real-time by the AI agent. \n   \n Additional resources: \n \n Build your own copilot/AI assistant solution accelerator \n Build your own copilot (retail product catalog discovery) demo \n Intelligent agent hackathon \n Vector database and retrieval-augmented generation (RAG) \n \n   \n Getting started \n Microsoft offers AI apps solution accelerators with pre-built templates, code, and best practices to help you implement common AI copilots faster and easier. Each accelerator presents a broadly applicable solution architecture with an easily-understandable, real-world example: \n \n Retail AI agent copilot: allows users to ask questions about product, customer, and sales order data. \n Real-time payment and transaction processing copilot: enables agents to analyze transactions using natural language. \n Claims processing copilot: offers recommendations based on business rules and analysis to help users manage claims. \n \n See all solution accelerators and code samples. \n Finally, good news: You can save big when building your AI apps on Azure. Check out the offers below to accelerate your AI journey. \n \n Azure AI Advantage: Azure AI and GitHub Copilot customers can save up to $6000 on Azure Cosmos DB for 90 days. \n Azure Innovate: Get expert guidance and funding to build AI-powered and custom cloud-native apps. \n Try Azure Cosmos DB for free: Develop, test your applications, and run small production workloads for free. \n \n What intelligent apps are you building on Azure? Drop a comment to share your use case. ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"19776","kudosSumWeight":16,"repliesCount":0,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MjYxNWk1MDBEOTg0MEY2MDdCNzZF?revision=32\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MzAyMGk5QTEyNDBDQkJDRENFQjRG?revision=32\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTczMGlGNEMyQ0JBNDM1OUI3MDY1?revision=32\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MzAyNmlEQzczQjE3MTM5QTE1RjZB?revision=32\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDU","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTczNWk5MUEwQTA2NkY3OTYyNDQw?revision=32\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDY","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTczN2lEQURGRTg2QjcyNDUwMDEz?revision=32\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDc","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTc0MGk3MEU4MjQ4ODVERENFNkI3?revision=32\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDg","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDgzNDEzLTU2MTc0MWkxQURCNTY2OERGMjhENkFC?revision=32\"}"}}],"totalCount":8,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:3651516":{"__typename":"Conversation","id":"conversation:3651516","topic":{"__typename":"BlogTopicMessage","uid":3651516},"lastPostingActivityTime":"2022-10-13T18:51:15.092-07:00","solved":false},"Blog:board:AppsonAzureBlog":{"__typename":"Blog","id":"board:AppsonAzureBlog","displayId":"AppsonAzureBlog","nodeType":"board","conversationStyle":"BLOG","title":"Apps on Azure Blog","shortTitle":"Apps on Azure Blog","parent":{"__ref":"Category:category:Azure"}},"User:user:994692":{"__typename":"User","uid":994692,"login":"shashankbarsin","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS05OTQ2OTItMjY5MjA1aTlBOUY2Qzk5MkNGQkYxQkU"},"id":"user:994692"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3MmlFRTY5NzUzMTA3Mzc2RjAy?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3MmlFRTY5NzUzMTA3Mzc2RjAy?revision=1","title":"shashankbarsin_0-1665592376177.png","associationType":"BODY","width":1430,"height":537,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3MGlERkE5NEM1RDkwMDEwNzY5?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3MGlERkE5NEM1RDkwMDEwNzY5?revision=1","title":"shashankbarsin_1-1665592376184.png","associationType":"BODY","width":1348,"height":706,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3MWkxQTM4RjRENDZDNzIwRkRD?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3MWkxQTM4RjRENDZDNzIwRkRD?revision=1","title":"shashankbarsin_2-1665592376205.png","associationType":"BODY","width":1482,"height":801,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3M2lDMkZGQkU0QTc4RkI0RUVG?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3M2lDMkZGQkU0QTc4RkI0RUVG?revision=1","title":"shashankbarsin_3-1665592376212.png","associationType":"BODY","width":1511,"height":795,"altText":null},"BlogTopicMessage:message:3651516":{"__typename":"BlogTopicMessage","subject":"Azure Kubernetes Fleet Manager - Preview","conversation":{"__ref":"Conversation:conversation:3651516"},"id":"message:3651516","revisionNum":1,"uid":3651516,"depth":0,"board":{"__ref":"Blog:board:AppsonAzureBlog"},"author":{"__ref":"User:user:994692"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" To address the multi-cluster requirements of customers with large number of AKS clusters, we are excited to announce a major step forward in Azure’s Kubernetes ecosystem by introducing the public preview of Azure Kubernetes Fleet Manager. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":12946},"postTime":"2022-10-12T09:37:01.116-07:00","lastPublishTime":"2022-10-12T09:37:01.116-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Growing adoption of containers for workload deployments has seen the emergence of Kubernetes as the preferred container orchestrator tool in the Cloud Native ecosystem. Azure Kubernetes Service (AKS), the managed Kubernetes offering from Azure, allows customers to offload the operational overhead to Azure, thus letting the user focus primarily on their workloads and business logic. However, as users migrate large scale workloads to containers, they often create a large number of AKS clusters for various reasons – clusters in different environments (QA/test, staging, prod), clusters in different regions for high availability or localization/proximity, or using clusters to achieve strong isolation between workloads. But the large number of clusters may result in platform admins having to deal with the following issues across their entire fleet of clusters – managing the lifecycle of multiple clusters and ensuring they have the same configuration, consistently scheduling the same app across multiple clusters, exposing the same app from multiple clusters and multiple regions at scale, and checking the health of my app across multiple clusters and the status of those clusters itself. To address the requirements of such large-scale AKS deployments, we are excited to announce a major step forward in Azure’s Kubernetes ecosystem by introducing the public preview of Azure Kubernetes Fleet Manager. \n \n   \n Organize your AKS cluster inventory \n You can create an Azure Kubernetes Fleet Manager resource to group and organize your AKS clusters. You can join any existing AKS cluster as member cluster to the fleet and later use the metadata of these clusters in orchestrating multi-cluster scenarios like Kubernetes resource propagation and multi-cluster load balancing. Azure Kubernetes Fleet Manager supports joining existing AKS clusters from different resource groups, subscriptions, and regions. They just need to be a part of the same Azure AD tenant. \n \n   \n   \n   \n With this, the platform admins responsible for many AKS clusters now get a new landing spot in the form of Azure Kubernetes Fleet Manager, from where they can manage their fleet of clusters. One of the goals of Fleet is to enable you to treat a set of clusters more like a single cluster, so that you can re-use and expand your K8s knowledge and constructs from a single cluster to now a fleet of clusters. To achieve this, we chose to expose Fleet operations through Kubernetes itself.  So, the Azure Kubernetes Fleet Manager resource itself is a Kubernetes cluster underneath which provides you a hub Kubernetes API from which you can orchestrate scenarios like Kubernetes resource propagation to member clusters and multi-cluster load balancing. \n Kubernetes Resource Propagation \n \n   \n   \n   \n Fleet provides ClusterResourcePlacement as a mechanism to control how cluster-scoped Kubernetes resources are propagated to member clusters. ClusterResourcePlacement has two parts to it: \n \n Resource selection: Pick which Kubernetes resources (namespace, ClusterRoleBinding,…) will propagate from fleet Kubernetes cluster to member clusters based on Kubernetes native constructs like <group, version, kind, name> or labels & selectors. \n Target cluster section: Pick which member clusters of the fleet to propagate the chosen resources to. The target clusters can be all clusters (no policy) or a specific subset of member clusters either identified by name or labels & selectors \n \n Before fleet, when platform admins got requirements for namespaces from their application teams, they would manually triage those and then figure out which AKS clusters in the inventory meet those requirements or if they need to create new AKS clusters to be able to place those namespaces. This namespace creation across multiple clusters and handover of the same to application teams was a manual process before fleet. Fleet’s ClusterResourcePlacement is an important step in enabling platform admins to automate placement of their namespaces against their cluster inventory based on the requirements shared by their application teams/tenants.   \n Multi-cluster load balancing \n Large-scale AKS customers often deploy the same set of workloads and services across multiple clusters, potentially even in different regions, and then want to load balance incoming traffic across them. They do this to address problems originating from application or infrastructure failure in a single cluster or region. Other reasons for clusters deployed in multiple regions include localization and region proximity. \n \n   \n   \n Azure Kubernetes Fleet manager allows you to create a custom resource to indicate that they want to set up Layer 4 multi-cluster load balancing for incoming traffic across endpoints of this service on multiple member clusters. \n What’s next on fleet’s roadmap?   \n Now that the foundational building block of the fleet resource is in place, we have a rich roadmap we are working on over the coming few months: \n   \n Lifecycle management of member clusters: Getting your entire fleet of clusters (dev, staging, prod) in a safe way to a new Kubernetes version can be challenging. We plan to provide an aggregated experience for orchestrating upgrade all member clusters of the fleet in a controlled manner across different environments (dev, staging, prod or region-based rings) as defined by the user. We also plan to allow declarative creation of AKS clusters from its Kubernetes API so that the platform admins can fully automate their cluster inventory creation and management in response to new requirements they receive from their application teams. \n   \n Fully managed hub cluster: With fleet acting as the grouping control plane for scenarios like Kubernetes resource propagation and multi-cluster load balancing, we plan to further solidify its resiliency by adding region failover capability for business continuity and disaster recovery. \n   \n Multi-cluster networking: Fleet currently addresses Layer-4 north-south load balancing across services on multiple member clusters. We plan to provide the equivalent Layer-7 north-south HTTPS load balancing solution with Gateway API as the interface. East-west communication and multi-cluster service mesh is in the fleet roadmap too. \n   \n Arc-enabled Kubernetes as member clusters: Fleet is currently scoped to joining AKS clusters as member clusters, but it is designed in an extensible way so that Arc-enabled Kubernetes resource type can be supported in future under fleet too. This will allow us to extend the benefits of fleet to edge and hybrid clusters. \n   \n The full roadmap for Azure Kubernetes Fleet Manager can be found here, where you can share your feature asks and scenarios \n   \n Get Started and Next Steps \n You can get started with Azure Kubernetes Fleet Manager in Azure portal or Azure CLI. Getting started with fleet is as easy as navigating to Azure Portal, then to Azure Kubernetes Fleet Manager and then using the creation wizard to create the Fleet resource and pre-seed a few member clusters from existing AKS clusters you have access to. Visit the quickstart in our product documentation for more details. \n   \n You can learn more about the other AKS announcements at Ignite here. ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"7391","kudosSumWeight":11,"repliesCount":4,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3MmlFRTY5NzUzMTA3Mzc2RjAy?revision=1\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3MGlERkE5NEM1RDkwMDEwNzY5?revision=1\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3MWkxQTM4RjRENDZDNzIwRkRD?revision=1\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUxNTE2LTQxMjY3M2lDMkZGQkU0QTc4RkI0RUVG?revision=1\"}"}}],"totalCount":4,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:3983317":{"__typename":"Conversation","id":"conversation:3983317","topic":{"__typename":"BlogTopicMessage","uid":3983317},"lastPostingActivityTime":"2023-11-15T13:15:08.030-08:00","solved":false},"User:user:127828":{"__typename":"User","uid":127828,"login":"Jorge Palma","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS0xMjc4MjgtMjkxMTUyaTY0QkZFRjgzMUY4MUI2MzU"},"id":"user:127828"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ0OGk4NTc1NURFOEE5N0Q3RDU4?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ0OGk4NTc1NURFOEE5N0Q3RDU4?revision=6","title":"JorgePalma_0-1700044079419.png","associationType":"BODY","width":1496,"height":776,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ2Mmk4RjY0RDZEQTZEMEIyOEJF?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ2Mmk4RjY0RDZEQTZEMEIyOEJF?revision=6","title":"JorgePalma_4-1700044954289.png","associationType":"BODY","width":1930,"height":819,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ1OGkzRjgxRDlCMzlDNTY0NzUy?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ1OGkzRjgxRDlCMzlDNTY0NzUy?revision=6","title":"JorgePalma_1-1700044509434.png","associationType":"BODY","width":999,"height":509,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ1OWk3M0YwN0IyQjVCMjc3OEFG?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ1OWk3M0YwN0IyQjVCMjc3OEFG?revision=6","title":"JorgePalma_2-1700044769511.png","associationType":"BODY","width":1035,"height":609,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ1MGkyMDVCMTg0NjgyQzUxRjcy?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ1MGkyMDVCMTg0NjgyQzUxRjcy?revision=6","title":"JorgePalma_4-1700044079461.png","associationType":"BODY","width":2349,"height":928,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ2MGkzMTY5ODVEQjhDRkZCM0ZG?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ2MGkzMTY5ODVEQjhDRkZCM0ZG?revision=6","title":"JorgePalma_3-1700044806919.png","associationType":"BODY","width":1035,"height":695,"altText":null},"BlogTopicMessage:message:3983317":{"__typename":"BlogTopicMessage","subject":"AKS Welcomes you to Ignite 2023","conversation":{"__ref":"Conversation:conversation:3983317"},"id":"message:3983317","revisionNum":6,"uid":3983317,"depth":0,"board":{"__ref":"Blog:board:AppsonAzureBlog"},"author":{"__ref":"User:user:127828"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":9514},"postTime":"2023-11-15T09:00:00.080-08:00","lastPublishTime":"2023-11-15T13:15:08.030-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Hi everyone, and welcome to Microsoft Ignite 2023! The AKS team is looking forward to connecting in person and virtually with all the AKS community, throughout the Ignite Keynotes, Breakouts, QA sessions, expert meetups or over a beverage in the hallways! \n   \n The team has been hard at work making Azure the best platform to run Kubernetes and a truly Kubernetes-powered cloud.  And over the last year Microsoft continued to leverage AKS as a tried and test platform for its critical workloads, putting a healthy amount of pressure on the service and continuing to help us push the boundaries of what’s possible with cloud native platforms and intelligent apps. \n \n   \n   \n As Kubernetes continues to become pervasive, a lot of teams find themselves at different steps of their adoption, skillset or learning stage. At Build 2023 we showed a prototype of an assistant for AKS that would make the perfect companion for any everyday task with AKS and Kubernetes. As part of our private preview, a lot of our users told us how great it would be if they could have that for all of Azure and today, we're happy to announce that all of those capabilities and more have been rolled into the new Microsoft Copilot for Azure. This AI companion will help you design, operate, optimize and troubleshoot any service and brings every integration we showed for AKS and much more, including new handlers for log collection or permissions validation. The Microsoft Copilot for Azure will be the perfect assistant for all teams at any stage of their AKS and cloud adoption journey! Sign up for the preview here! \n   \n Improving resilience and uptime with simplified global footprint \n Nowadays, all industries, companies and solutions rely in one way or another on software and digital components, and more than ever users expect flawless services that never fail performing at a high level. This has increased a lot of the resiliency requirements of most of our existing and new users. One of the most common ways to increase availability and resilience is ensuring a global footprint across multiple regions and geographies, with the added value that you can serve your users closer to their locations while benefiting from protection in case anything goes wrong with one of the regions. However, this could increase the complexity of management and operations of multiple clusters across these regions, so we’re thrilled to announce that Azure Kubernetes Fleet Manager is now Generally Available, allowing you to create fleets of AKS clusters with a few clicks and easily distribute workloads across them while orchestrating operations like upgrades across them in a consistent manner. Fleet Manager is also very modular, allowing you to use exactly the functionality you want without requiring you to change your practices for scenarios you already solved for today. You can choose to use it with a hub (a fully managed hub cluster that controls things like namespace and workload placement without requiring any management) or hubless if you just want a central view of clusters and central management of operations like upgrades. \n   \n \n   \n As we wrapped KubeCon North America last week, 2 trends became very apparent as we talked with users and the community. The first one is how Kubernetes is uniquely positioned to power the AI revolution, providing a scalable, reliable and extensible platform that can meet the ever-changing needs of our users. The second was around the continued need for better cost visualization and optimization and more streamlined operations in order to reduce costs from all angles and allow users and business to focus on creating value for their business. These trends have long resonated with the team and we’re happy to show some of the latest things we’ve been working on in these areas. \n   \n Kubernetes powering the AI revolution \n Today you can already use kubernetes in conjunction with some of Azure’s great AI services in order to very quickly and efficiently create intelligent applications that can scale and sustain any demand. However, many scenarios with privacy or customization requirements, for example, might need you to run/host your own model and customized inferencing. This brings a lot of challenges as you need to figure out how to containerize the models, host them, find capacity and the right GPUs for them, schedule them, provide endpoints so your apps can plug into them, etc. \n So to simplify this we’re happy to announce the AI Toolchain Operator addon for AKS, based on the open source KAITO project. This addon will drastically simplify the experience and number of steps to run an OSS model from dozens and many days/weeks of work, to just a couple steps and a few minutes. It will also assist you setting up an endpoint for your applications to consume so you can quickly integrate with new or existing apps. We’re looking forward to partnering with our existing preview customers and now with all users to continue to simplify and enrich this experience and provide further integrations with the Azure ecosystem. \n   \n \n   \n   \n   \n One of the key tenets of responsible AI is ensuring privacy concerns are addressed and respected. A few months ago, we demonstrated a prototype for Confidential Containers allowing you to run any workload leveraging confidential hardware capabilities without any code changes and we’re happy to announce that Kata Confidential Containers are now in public preview. \n   \n \n   \n   \n   \n Another important aspect is ensuring the provenance of your images to ensure that your supply chain doesn’t suffer from any tampering, so last month AKS announced Image Integrity, which allows you to sign any container image in ACR and validate its signature via policy on an AKS cluster, leveraging the Ratify open-source project. \n   \n \n   \n   \n Visualize, reduce costs & streamline operations \n In our wider conjuncture, it’s of the utmost importance to ensure that teams’ infrastructure and operations are as efficient as possible and allow them to focus on their business outcomes. \n We’ve been focusing on 3 main areas: \n \n Cost Visualization: We’re announcing the cost analysis addon that allows direct integration of namespace and kubernetes assets billing with the Azure Cost Management portal. All of which builds on top of the open-source OpenCost project. \n Efficient scaling and cost reduction: For pod level scaling we’re very happy to announce the General Availability of KEDA (Kubernetes Event Driven Autoscaler) addon. For the infrastructure, one of the key pain points is knowing the best, cheapest and most readily available SKUs as well as ensure the most efficient usage of nodes by tightly binpacking pods/containers within them. So we’re very happy to be able to announce the Node Auto Provision addon, which leverage the open source Karpenter project to efficiently select the cheapest, highly available and most suited VM SKUs that allow for the most efficient bin-packing of your environments. \n Lighting fast and efficient container starts: We’re announcing Artifact Streaming for Linux, allowing faster image pulls/container starts of at least 15% (with many cases well over 50%) prioritizing the pull of the essential layers and using the containerd overlaybd project.   \n System reserved optimization: The team has worked hard on optimizing the resource usage of the kubernetes system components, allowing that every node after Kubernetes 1.28 (now GA) will have 20% more allocatable space for workloads. \n Simplifying common operations: We’ve provided over 10 new enhancements for Virtual nodes allowing for many more bursting and serverless scenarios to be possible, from LB services integration, container probes, debug containers and exec/port-forward capabilities, bringing a lot more parity to native node capabilities to this option. Additionally, for one of the most common tasks for applications, setting up routing (ingress, DNS, certificates), we’re making the Application Routing addon generally available, so you can have a fully managed and scalable bundle of all those capabilities delivered out of the box by AKS. \n \n \n   \n The are some of the latest things the teams have been working on, with many more available on the AKS Release Notes and throughout our announcements. \n   \n We can’t wait to meet you and chat about these or many other of our announcements and discuss what’s coming next and how we can help you achieve even more. \n   \n Make sure to follow our roadmap for what’s coming and the AKS community for deep dive content on AKS. \n   \n   ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"8742","kudosSumWeight":9,"repliesCount":0,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ0OGk4NTc1NURFOEE5N0Q3RDU4?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ2Mmk4RjY0RDZEQTZEMEIyOEJF?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ1OGkzRjgxRDlCMzlDNTY0NzUy?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ1OWk3M0YwN0IyQjVCMjc3OEFG?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDU","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ1MGkyMDVCMTg0NjgyQzUxRjcy?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDY","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTgzMzE3LTUyNjQ2MGkzMTY5ODVEQjhDRkZCM0ZG?revision=6\"}"}}],"totalCount":6,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:4383006":{"__typename":"Conversation","id":"conversation:4383006","topic":{"__typename":"BlogTopicMessage","uid":4383006},"lastPostingActivityTime":"2025-02-20T08:46:18.562-08:00","solved":false},"User:user:2258735":{"__typename":"User","uid":2258735,"login":"GuilhermeFrança","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS0yMjU4NzM1LW5kbXNHQg?image-coordinates=0%2C23%2C1312%2C1336"},"id":"user:2258735"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MzgzMDA2LWRJam5Hbw?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MzgzMDA2LWRJam5Hbw?revision=6","title":"moodle-high-scale.png","associationType":"BODY","width":1127,"height":400,"altText":""},"BlogTopicMessage:message:4383006":{"__typename":"BlogTopicMessage","subject":"Reference Architecture for a High Scale Moodle Environment on Azure","conversation":{"__ref":"Conversation:conversation:4383006"},"id":"message:4383006","revisionNum":6,"uid":4383006,"depth":0,"board":{"__ref":"Blog:board:AppsonAzureBlog"},"author":{"__ref":"User:user:2258735"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"This project deploys a robust infrastructure on Azure to handle a high scale moodle installation. This environment is able - and tested - to handle 400k concurrent users.","metrics":{"__typename":"MessageMetrics","views":606},"postTime":"2025-02-19T04:44:02.288-08:00","lastPublishTime":"2025-02-20T08:46:18.562-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Introduction  \n Moodle is an open-source learning platform that was developed in 1999 by Martin Dougiamas, a computer scientist and educator from Australia. Moodle stands for Modular Object-Oriented Dynamic Learning Environment, and it is written in PHP, a popular web programming language. Moodle aims to provide educators and learners with a flexible and customizable online environment for teaching and learning, where they can create and access courses, activities, resources, and assessments. Moodle also supports collaboration, communication, and feedback among users, as well as various plugins and integrations with other systems and tools.  \n Moodle is widely used around the world by schools, universities, businesses, and other organizations, with over 100 million registered users and 250,000 registered sites as of 2020. Moodle is also supported by a large and active community of developers, educators, and users, who contribute to its development, documentation, translation, and support. [URL] is the official website of the Moodle project, where anyone can download the software, join the forums, access the documentation, participate in events, and find out more about Moodle.  \n Goal  \n The goal for this architecture is to have a Moodle environment that can handle 400k concurrent users and scale in and out its application resources according to usage.   \n Using Azure managed services to minimize operational burden was a design premise because standard Moodle reference architectures are based on Virtual Machines that comes with a heavy operational cost.  \n Challenges  \n Being a monolith application, scaling Moodle in a modern cloud native environment is challenging. We choose to use Kubernetes as its computing provider due to the fact that it allow us to build a Moodle artifact in an immutable way that allows it to scale out and in when needed in a fast and automatic way and also recover from potential failures by simply recreating its Deployments without the need to maintain Virtual Machine resources, introducing the concept of pets vs cattle[1] to a scenario that at first glance wouldn't be feasible.  \n Since Moodle is written in PHP it has no concept of database polling, creating a scenario where its underlying database is heavily impacted by new client requests, making it necessary to use an external database pooling solution that had to be custom tailored in order to handle the amount of connections for a heavy-traffic setup like this instead of using Azure Database for PostgreSQL's built-in pgbouncer.  \n The same effect is also observed in its Redis implementation, where a custom Redis cluster had to be created, whereas using Azure Cache for Redis would incur prohibitive costs due to the way it is set up for a more general usage.   \n 1 - https://learn.microsoft.com/en-us/dotnet/architecture/cloud-native/definition#the-cloud   \n Architecture  \n \n   \n This architecture uses Azure managed (PaaS) components to minimize operational burden by using Azure Kubernetes Service to run Moodle, Azure Storage Account to host course content, Azure Database for PostgreSQL Flexible Server as its database and Azure Front Door to expose the application to the public as well as caching commonly used assets. The solution also leverages Azure Availability Zones to distribute its component across different zones in the region to optimize its availability.  \n Provisioning the solution  \n The provisioning has two parts: setting up the infrastructure and the application. The first part uses Terraform to deploy easily. The second part involves creating Moodle's database and configuring the application for optimal performance based on the templates, number of users, etc. and installing templates, courses, plugins etc.  \n The following steps walk you through all tasks needed to have this job done.  \n Clone the repository \n $ git clone https://github.com/Azure-Samples/moodle-high-scale \n Provision the infrastructure  \n $ cd infra/  $ az login  $ az group create --name moodle-high-scale --location <region>  $ terraform init  $ terraform plan -var moodle-environment=production  $ terraform apply -var moodle-environment=production  $ az aks get-credentials --name moodle-high-scale --resource-group moodle-high-scale  \n  Provision the Redis Cluster \n $ cd ../manifests/redis-cluster  $ kubectl apply -f redis-configmap.yaml  $ kubectl apply -f redis-cluster.yaml  $ kubectl apply -f redis-service.yaml  \n  Wait for all the replicas to be running \n $ ./init.sh \n Type 'yes' when prompted.  \n Deploy Moodle and its services  \n Change image in moodle-service.yaml and also adjust the moodle data storage account name in the nfs-pv.yaml (see commented lines in the files)  \n $ cd ../../images/moodle  $ az acr build --registry moodlehighscale<suffix> -t moodle:v0.1 --file Dockerfile .  $ cd ../../manifests  $ kubectl apply -f pgbouncer-deployment.yaml  $ kubectl apply -f nfs-pv.yaml  $ kubectl apply -f nfs-pvc.yaml  $ kubectl apply -f moodle-service.yaml  $ kubectl -n moodle get svc –watch  \n Provision the frontend configuration that will be used to expose Moodle and its assets publicly \n $ cd ../frontend  $ terraform init  $ terraform plan $ terraform apply \n Approve the private endpoint connection request from Frontdoor in moodle-svc-pls resource.  \n Private Link Services > moodle-svc-pls > Private Endpoint Connections > Select the request from Front Door and click on Approve.  \n Install database \n $ kubectl -n moodle exec -it deployment/moodle-deployment -- /bin/bash  $ php /var/www/html/admin/cli/install_database.php --adminuser=admin_user --adminpass=admin_pass --agree-license  \n Deploy Moodle Cron \n Change image in moodle-cron.yaml  \n $ cd ../manifests $ kubectl apply -f moodle-cron.yaml  \n   \n Your Moodle installation is now ready to use! \n Conclusion  \n You can create a Moodle environment that is scalable and reliable in minutes with a very simple approach, without having to deal with the hassle of operating its parts that normally comes with standard Moodle installations.  ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"6379","kudosSumWeight":8,"repliesCount":0,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MzgzMDA2LWRJam5Hbw?revision=6\"}"}}],"totalCount":1,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:4057960":{"__typename":"Conversation","id":"conversation:4057960","topic":{"__typename":"BlogTopicMessage","uid":4057960},"lastPostingActivityTime":"2024-02-19T21:26:57.279-08:00","solved":false},"User:user:565398":{"__typename":"User","uid":565398,"login":"AbdullahAbuHassan","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/m_assets/avatars/default/avatar-4.svg?time=0"},"id":"user:565398"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDU3OTYwLTU1MTg3NmkyQ0JGRUY1NTMxMTcwNjhG?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDU3OTYwLTU1MTg3NmkyQ0JGRUY1NTMxMTcwNjhG?revision=1","title":"AbdullahAbuHassan_0-1707997808635.png","associationType":"BODY","width":358,"height":355,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDU3OTYwLTU1MTg3OGlFQjgzMEVFMTUzNDgwOEU4?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDU3OTYwLTU1MTg3OGlFQjgzMEVFMTUzNDgwOEU4?revision=1","title":"AbdullahAbuHassan_1-1707997808639.jpeg","associationType":"BODY","width":945,"height":945,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDU3OTYwLTU1MTg3N2k4NTc0RjQ0QjM0QzE5QjBF?revision=1\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDU3OTYwLTU1MTg3N2k4NTc0RjQ0QjM0QzE5QjBF?revision=1","title":"AbdullahAbuHassan_2-1707997808645.png","associationType":"BODY","width":945,"height":514,"altText":null},"BlogTopicMessage:message:4057960":{"__typename":"BlogTopicMessage","subject":"Step by Step Practical Guide to Architecting Cloud Native Applications","conversation":{"__ref":"Conversation:conversation:4057960"},"id":"message:4057960","revisionNum":1,"uid":4057960,"depth":0,"board":{"__ref":"Blog:board:AppsonAzureBlog"},"author":{"__ref":"User:user:565398"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" Architecting Cloud Native Applications ","introduction":"","metrics":{"__typename":"MessageMetrics","views":14974},"postTime":"2024-02-15T03:52:32.989-08:00","lastPublishTime":"2024-02-15T03:52:32.989-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" This is a step by step, no fluff guide to building and architecting cloud native applications. \n Cloud application development introduces unique challenges: applications are distributed, scale horizontally, communicate asynchronously, have automated deployments, and are built to handle failures resiliently. This demands a shift in both technical approach and mindset. \n So Cloud Native is not about technologies, if you can do all of the above, then you are Cloud Native. You don’t have to use Kubernetes for instance, to become Cloud Native. \n   \n \n \n   \n \n \n Steps: \n Say you want to architect an application in the cloud, and let’s use an E-Commerce Website as an example, how do you go about it and what decisions do you need to make? \n Regardless of the type of application, we have to go through six distinct steps: \n \n Define Business Objectives. \n Define Functional and None Functional Requirements. \n Choose an Application Architecture. \n Make Technology Choices. \n Code using Cloud Native Design Patterns. \n Adhere to the Well Architected framework. \n \n Business Objectives: \n Before starting any development, it’s crucial to align with business objectives, ensuring every feature and decision supports these goals. While microservices are popular, their complexity isn’t always discussed. \n It’s essential to evaluate if they align with your business needs, as there’s no universal solution. For external applications, the focus is often on enhancing customer experience or generating new revenue. Internal applications, however, aim to reduce operational costs and support queries. \n For instance, in E-commerce, improving customer experience may involve enhancing user interfaces or ensuring uptime, while creating new revenue streams could require capabilities in data analytics and product recommendations. \n By first establishing and then rigorously adhering to the business objectives, we ensure that the every functionality in the application — whether serving external customers or internal users — delivers real value. \n \n \n \n   \n \n \n \n Functional and None Functional Requirements: \n Now that we understand and are aligned with the business objectives, we go one step further by getting a bit more specific. And that is by defining functional and none-functional requirements. \n Functional requirements define the functionalities you will have in your application: \n \n Users should be able to create accounts, sign in, and there should be password recovery mechanisms. \n The system should allow users to add, modify, or delete products. \n Customers should be able to search for products and filter based on various criteria. \n The checkout process should support different payment methods. \n The system should check order status from processing to delivery. \n Customers should be able to rate products & leave reviews. \n \n None functional requirements define the “quality” of the application: \n \n Application must support hundreds of concurrent users. \n The application should load pages in under 500ms even under heavy load. \n Application must be able to scale during peak times. \n All internal communication between systems should be happen through private IPs. \n Application should be responsive to adapt to different devices. \n What SLA will we support, what RTO & RPO are we comfortable with? \n \n Application Architecture: \n We understand the business objectives, we are clear on what functionalities our application will support, and we understand the constraints our applications need to adhere to. \n Now, it is time to make a decision on the Application Architecture. For simplicity, you either choose a Monolith or a Microservices architecture. \n Monolith: A big misconception is that all monoliths are big ball of muds — that is not necessary the case. Monolith simply means that the entire application with all of its functionalities are hosted in a single deployment instance. The internal architecture though, can be designed to keep the components of different subsystems isolated from each other but calls between them are in process function calls as opposed to network calls. \n Microservices: Modularity has always been a best practice in software development whether you use a Monolith (logical modularity) or Microservice (physical modularity). Microservices is when functionalities of your application are physically separate into different services communicating over network calls. \n What to pick: Choose microservices if technical debt is high and your codebase has become so large that feature releases are slow, affecting market responsiveness, or if your application components need different scaling approaches. Conversely, if your app updates infrequently and doesn’t require detailed scalability, the investment in microservices, which introduces its own challenges, might not be justified. \n Again, this is why we start with business objectives and requirements. \n Technology Choices: \n It is time to make some technology choices. We won’t be architecting yet, but we need to get clear on what technologies we will choose, which is now much easier because we understand the application architecture and requirements. \n Encompassing all technology choices, you should be thinking about containers if you are architecting cloud native applications. Away from all the fluff, this is how containers work: The code, dependencies, and run-time are all packaged into a binary (an executable package) known as an image. That binary or image is stored in a container registry and you can run this binary on any computer that has a supported container runtime (such as Docker). With that, you have a portable and lightweight deployable package. \n Compute: \n \n N-Tier: If you are going with N-tier (a simple Web, Backend, Database for instance), the recommended option for compute is to go with a PaaS Managed service such as Azure App Service. The decision point ultimately comes down to control & productivity. IaaS gives you the most control, but least productivity as you have to manage many things. It is also easier to scale managed services as they often come with an integrated load balancer as opposed to configuring your own. \n Microservices: On the other hand, the most common platform for running Microservices is Kubernetes. The reason for that is Microservices are often developed using containers, and Kubernetes is the most popular container orchestrator which can handle thing such as self healing, scale, load balancing, service-service discovery, etc. The other option, however, is using Azure Container Apps which is a layer of abstraction above Kubernetes allowing you to run multiple containers at scale without managing Kubernetes. If you require access to the Kubernetes API, Container Apps is not a good option. Many apps, however, don’t require access to the Kubernetes API so it is not worth the effort managing the cluster, hence Container Apps is a good choice. You can run microservices in a PaaS Service such as Azure App Service, but it becomes difficult to manage, specifically from a CI/CD perspective. \n \n Storage \n \n Blob Storage: Use Blobs if you want to store unstructured objects like images. Calls are done via a HTTPS and blobs are generally inexpensive. \n Files: If your applications would like native file shares, you can use services such as Azure Files which is accessible over SMB and HTTPS. For containers that want persistent volume, Azure Files is very popular. \n \n Databases: \n Most applications model data. We represent different entities in our applications (users, products) using objects with certain properties (name, title, description). \n When we pick a database, we need to take into consideration how will we represent our data model (JSON, Tables, Key Value/Pairs). In addition, we need to understand relationships between different models, scalability multi-regional replication, schema flexibility, and of course, team skillsets. \n \n Relational Databases: Use this when you want to ensure strong consistency, you want to enforce a schema, and you have a lot of relationships between data (especially many to one and many to many). \n Document Database: Use this if you want a flexible schema, you primarily have a one to many relationships i.e. a tree hierarchy (such as posts with multiple comments), and you are dealing with millions of transactions per second. \n Key/Value store: Suitable for simple lookups. They are extremely fast and extremely scalable. Caching is excellent for that. \n Graph Databases: Great for complex relationships and ones that change over time. Data is organized into nodes and edges. Building a recommendation engine for an e-commerce application to implement “frequently bought together” would probably use a Graph Database under the hood. \n \n One of the advantages of Microservices is that each service can pick its own database. A product service with reviews follows a tree like structure (one to many relationship) and would fit a document database. An inventory service on the other hand, where each product can belong to one or more category and each order can contain multiple products (many to many relationships) might use a relational database. \n Messaging: \n The difference between an event and message is that with message (apart from having a larger payload), a producer expects the message to be processed while an event is just a broadcast with no expectation of acting on it. \n For an event, it is either discrete (such as a notification) or in a sequence such as IOT streams. Streams are good for statistical evaluation. For instance, if you are tracking inventory through a stream of events, you can analyze in the last 2 hours, how much stock has been moved. \n Pick: \n \n Azure Service Bus: If you’re dealing with a message. \n Azure Event Grid: If you’re dealing with discrete events. \n Azure Event Hub: If you’re dealing with a stream of events. \n \n Many times, a combination of these services are used. Say you have an e-commerce, and when new orders come, you send a message to a queue where inventory system listens to confirm & update stock. Since orders are infrequent, the inventory system will constantly poll for no reason. To mitigate that, we can use an Event Grid listening to the Service Bus Queue, and the Event Grid triggers the inventory system whenever a new message comes in. Event Grid helps convert this inefficient polling model into an event-driven model. \n Identity: \n Identity is one of the most critical elements in your application. How you authenticate & authorize users is a considerable design decision. Often times, identity is the first thing that is considered before apps are moved to the cloud. Users need to authenticate to the application and the application itself needs to authenticate to other services like Azure. \n The recommendation is to outsource identity to an identity provider. Storing credentials in your databases makes you a target for attacks. By using an Identity as a Service (IDaaS) solution, you outsource the problem of credential storage to experts who can invest the time and resources in securely managing credentials. Whichever service you choose, make sure it supports Passwordless & MFA which is more secure. Open ID & OAuth are the standard protocols for Authentication and Authorization. \n Code using Cloud Native Design Patterns: \n We defined requirements, picked the application architecture, made some technology choices, and now it is time to think about how to design the actual application. \n No matter how good the infrastructure is and how good of a technology choice you’ve made, if the application is poorly designed or is not designed to operate in the cloud, you will not meet your requirements. \n API Design: \n \n Basic Principles: The two key principles of API design is that they should be platform independent (any client should be able to call the API) and designed for evolution (APIs should be updated without affecting clients, hence proper versioning should be implemented). \n Verbs not nouns: URLs should be around Data Models & Resources not verbs: /orders not /create-orders . \n Avoid Chatty URLs: For instance, instead of fetching product details, pricing, reviews separately, fetch them in one call. But there is a balance here, ensure the response doesn’t become too big otherwise latency will increase. \n Filtering and Pagination: It is generally not efficient to do a GET Request over a large number of resources. Hence, your API should support a filtering logic, pagination (instead of getting all orders, get a specific number), and sorting (avoid doing that on the client). \n Versioning: Maintaining multiple versions can increase complexity and costs since you have to manage multiple versions of documentation, test suites, deployment pipelines, and possibly different infrastructure configurations. It also requires a clear deprecation policy so clients know how long v1 will be available and can plan their migration to v2 but it is well worth the effort to ensure updates does not disrupt our clients. Versioning is often done on the URI, Headers, or Query Strings. \n \n Design for Resiliency: \n In the cloud, failures are inevitable. This is the nature of distributed systems, we rarely run everything on one node. Here is a checklist of things you need to account for: \n \n Retry Mechanism: A Retry mechanism is a way to deal with transient failures and you need to have retry logic in your code. If you are interacting with Azure services, most of that logic is embedded in the SDKs. \n Circuit Breaking: Retry logic is great for transient failures, but not for persistent failures. For persistent failures, implement circuit breaking. In practical terms, we monitor calls to a service, and upon a certain failure threshold, we prevent further calls, it is as simple as that. \n Throttling: The reality is, sometimes the system cannot keep up even if you have auto-scaling setup so you need throttling to ensure your service still functions. You can implement throttling in your code logic or use a service like Azure API Management. \n \n Design for Asynchronous Communication: \n Asynchronous communication is when services talk to each other using events or messages. The web was built on synchronous (direct) Request-Response communication, but it becomes problematic when you start chaining multiple requests, such as in a distributed transaction because if one call fails, the entire chain fails. \n Say we have a distributed transaction in a microservices application. A customer places an order processed by order service, which does a direct call to the payment service to process payments. If payment system is down, then the entire chain fails, and order will not go through. With asynchronous communication, a customer places an order, the order puts an order request in a queue, and when payment is up again, an order confirmation is sent to the user. You can see, such small design decisions can make massive impacts on revenues. \n Design for Scale: \n You might think scalability is as simple as defining a set of auto-scaling rules. However, your application should first be designed to become scalable. \n The most important design principle is having a stateless application, which means logic should not depend on a value stored on a specific instance such as a user session (which should be stored in a shared cache). The simple rule here is: don’t assume your request will always hit the same instance. \n Consider using connection pooling as well, which is re-using established database connections instead of creating a new connection for every request. It also helps avoid SNAT exhaustion especially when you’re operating at scale. \n Design for Loose Coupling: \n An application consists of various pieces of logic & components working together. If these are tightly coupled, it becomes hard to change the system i.e. changing one system, means coordinating with multiple other systems. \n Loosely coupled services means you can change one service without changing the other. Asynchronous communication, as explained previously, helps with designing loosely coupled components. \n Also, using a separate database per microservice is an example of loose coupling (changing the schema of one DB will not affect any other service, for instance). \n Lastly, ensure services are deployed individually without having to re-deploy the entire system. \n Design for Caching: \n If performance is crucial, then caching is a no brainer and cache management is the responsibility of the client application or intermediate server. \n Caching, essential for performance, involves storing frequently accessed data in fast storage to reduce latency and backend load. It’s suitable for data that’s often read but seldom changed, like product prices, minimizing database queries. Managing cache expiration is critical to ensure data remains current. Techniques include setting max-age headers for client-side caching and using ETags to identify when cached data should be refreshed. \n Service Side Caching: Server-side caching often employs Redis, an in-memory database ideal for fast data retrieval due to its RAM-based storage, not suitable for long-term persistence. Redis enhances performance by caching data that doesn’t frequently change, using key-value pairs and supporting expiration times (TTLs) for data. \n \n \n \n   \n \n \n \n Client Side Caching: Content Delivery Networks (CDNs) are often used to cache data closer to frontend clients, and more often, it is static data. In Web Lingo, static data refers to files that are static, such as CSS, Images, HTML, etc. Those are often stored in CDNs, which are nothing more than a set of reverse proxies (spread around the world) between the client and backend. Client will usually request these static resources from these CDN URLs (sometimes called edge servers) and the CDN will return the static content along with TTL headers and if TTL expires, CDN will request static resources again from the origin. \n \n \n \n \n \n \n   \nUpdating Media \n \n \n \n   \n \n \n Well-Architected Framework: \n You’ve defined business objectives & requirements, made technology choices, and coded your application using cloud native design patterns. \n This section is about how you architect your solution in the cloud, defined through a cloud agnostic framework known as Well-Architected framework encompassing reliability, performance, security, operational excellence, and cost optimization. \n Note that many of these are related. Having scalability will help with reliability, performance, and cost optimization. Loose coupling between services will help with both reliability and performance. \n Reliability: \n A reliable architecture must be fault tolerant and must survive outages automatically. We discussed how to increase reliability in our application code through retry mechanisms, circuit breaking patterns, etc. This is about how do we ensure reliability is at the forefront of our architecture. \n Here is a summary of things to think about when it comes to reliability: \n \n Avoid Overengineering: Simplicity should be a guiding principle. Only add elements to your architecture if they directly contribute to your business goals. For instance, if having a complex recommendation engine doesn’t significantly boost sales, consider a simpler approach. Another thing to consider is avoiding re-inventing the wheel, if you can integrate a third party payment system, why invest in building your own? \n Redundancy: This helps minimize single points of failures. Depending on your business requirements, implement zonal and/or regional redundancy. For regional redundancies, appropriately choose between active-active (maximum RTO) and active-passive (warm, cold, or redeploy) and always have an Automatic failover but manual fallback to prevent switching back to an unhealthy region. Every Azure component in your architecture should account for redundancy in case things go wrong by conducting a failure mode analysis (analyzing risk, likelihood, and effect in case things go wrong). \n Backups: Every stateful part of your system such as your database should have automatic immutable backups to meet your RPO objectives. If your RPO is 1 hour (any data loss should not exceed 1 hour), you might need to schedule backups every 30 minutes. Backups are your safety archives in case things such as bugs or security breaches happen, but for immediate recovery from a failed component, consider data replication. \n Chaos Engineering: Deliberately injecting faults into your system allows you to discover how your system responds before they become real problems for your customers. \n \n Performance: \n The design patterns you implement in your applications, will influence performance. This focuses more on the architecture. \n \n Capacity Planning: You always need to start here. How do you pick the resources (CPU, memory, storage, bandwidth) you need to satisfy your performance requirements? Best place to start is by conducting load testing on expected traffic and peak loads to validate if your capacity meets your performance needs. However, most importantly, capacity planning is an ongoing process which should be reviewed and adjusted. \n Consider Latency: Services communicating across regions or availability zones can face increased latency. Also, ensure services are placed closer to users. Lastly, use private backbone networks (Private endpoints & service endpoints) instead of traversing the public internet. \n Scale Applications: You need to choose the right auto-scaling metrics. Queue length has always been popular metric because it shows there is a long backlog of tasks to be completed. However, a better metric is now used which is critical time, that is the total time when a message is sent to a queue & processed. Yes queue length is important, but critical time actually shows you how efficiently the backend is processing it. For an e-commerce platform that sends confirmation emails based on orders on a queue, you can have 50k orders but if the critical time is 500ms (for oldest message), then we can see that the worker is keeping up despite all these messages. \n Scale Databases: A big chunk of performance problems are usually attributed to databases. If it is a none-relational database, horizontal scaling is straightforward, but often-times, you need to define a partition key to split the data (for instance, if customer address is used as a partition key, users are split into different customer address partitions). If it is a relational database, partitioning can also be done through sharding (splitting tables into separate physical nodes), but it is more challenging to implement. \n \n Security: \n Security is about embracing two mindsets, zero trust and a defense in depth approach. \n \n Zero Trust: In the past, we used to have all components in the same network so we used to trust any component that was within the network. Nowadays, we have the internet and various components that connect to our application from anyone. Zero trust is about verifying explicitly, where all users & applications must authenticate & authorize even if they are inside the network. If an application is trying to access a database in the same network, it should authenticate & authorize. Azure Managed Identities, for instance, support this mechanism without exposing secrets. The second principle is using least privelege by assigning Just in Time (JIT) and Just Enough Access (JEA) to users and applications. Lastly, always assume breach. Even if an attacker penetrated our network, how can we minimize the damage? A common methodology is to use network segmentation. Only allow specific ports open between subnets and only allow certain subnets to communicate with each other. Just because they are all in the same network, does not mean you allow all communication. \n Defense in Depth: Everything in your application & architecture should embed security. Your data should be encrypted at transit & rest, your applications should not store secrets or use vulnerable dependencies or insecure code practices (consider using a static security analysis tool to detect these), your container images should be scanned, etc. \n \n Operational Excellence: \n While the application, infrastructure, and architecture layer are important. We need to ensure we have the operations in place to support our workaloads. I boiled them down into four main practices. \n \n DevOps Practice: Set of principles & tooling to allow automated, reliable, and predictable tests to ensure faster & more stable releases. Testing & Security should be shifted to the left, and zero down-time must be achieved through blue/green deployments or canary releases. \n Everything as Code: Infrastructure should be defined using declarative code that is stored in source control repository for version control & rollbacks. IaC allows more reliable and re-usable infrastructure deployments. \n Platform Engineering Practice: Outside of buzz words, this is when a centralized platform team creates a set of self-service tools (utilizing preconfigured IaC templates under the hood) for developers to deploy resources & experiment in a more controlled environment. \n Observability: This is about gathering metrics, logs, and traces to provide our engineers with better visibility into our systems, and in-turn, fix issues faster. I wrote another article about observability so I won’t go into detail here, make sure to check it out. \n \n Cost Optimization: \n If costs are not optimized, your solution is not well architected, it is as simple as that. Here are things you should be thinking about: \n \n Plan for Services: Every service has a set of cost optimization best practices. For instance, if you are using Azure Cosmos DB, ensure you implement proper partitioning. If you are using Azure Kubernetes, ensure you define resource limits on Pods. \n Accountability: All resources should be tracked back to their owners and divisions to be linked back to a cost center. We do that by enforcing tags. \n Utilize Reserved Instances: If you know you will have predictable load on a production application that will always be on. Utilize Reserved Instances. Every cloud provider should support that. \n Leverage Automation: Switch off things during none traffic times. \n Auto-scale: Leverage dynamic auto-scaling to use less resources at low peak times. \n \n Conclusion \n I hope this overview has captured the essentials of building cloud-native applications, highlighting the shift required from traditional development practices. While not exhaustive, I’m open to exploring any specific areas in more detail based on your interest. Just let me know in the comments, and I’ll gladly delve deeper. ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"27165","kudosSumWeight":8,"repliesCount":1,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDU3OTYwLTU1MTg3NmkyQ0JGRUY1NTMxMTcwNjhG?revision=1\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDU3OTYwLTU1MTg3OGlFQjgzMEVFMTUzNDgwOEU4?revision=1\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MDU3OTYwLTU1MTg3N2k4NTc0RjQ0QjM0QzE5QjBF?revision=1\"}"}}],"totalCount":3,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:3966586":{"__typename":"Conversation","id":"conversation:3966586","topic":{"__typename":"BlogTopicMessage","uid":3966586},"lastPostingActivityTime":"2023-10-30T10:03:34.587-07:00","solved":false},"User:user:1594022":{"__typename":"User","uid":1594022,"login":"samfernandez","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/m_assets/avatars/default/avatar-7.svg?time=0"},"id":"user:1594022"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE2MGk0NTg1RjU3NkMwMDI4OUM3?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE2MGk0NTg1RjU3NkMwMDI4OUM3?revision=5","title":"Cluster Autoscaler main blade-red.png","associationType":"TEASER","width":1880,"height":800,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE2OGk0RUVFMzY3QjE2OUREMDY4?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE2OGk0RUVFMzY3QjE2OUREMDY4?revision=5","title":"filter-all.png","associationType":"BODY","width":2170,"height":1246,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE2OWkzQkVDNjI4RDkxRkMxMzMx?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE2OWkzQkVDNjI4RDkxRkMxMzMx?revision=5","title":"Cluster Autoscaler main blade-red.png","associationType":"BODY","width":1880,"height":800,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE3M2lDRTg2NkE2MDZEMTU2Q0U2?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE3M2lDRTg2NkE2MDZEMTU2Q0U2?revision=5","title":"events.png","associationType":"BODY","width":2263,"height":507,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE3Nmk1OTdBMDFGNUQzQkI2N0FF?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE3Nmk1OTdBMDFGNUQzQkI2N0FF?revision=5","title":"Node Saturation Main Blade-pii.png","associationType":"BODY","width":1381,"height":682,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE3N2k4OTgwNEUzQUIyNkQyNUI0?revision=5\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE3N2k4OTgwNEUzQUIyNkQyNUI0?revision=5","title":"Node Saturation-pii.png","associationType":"BODY","width":1762,"height":1107,"altText":null},"BlogTopicMessage:message:3966586":{"__typename":"BlogTopicMessage","subject":"Announcing New Features for Enhanced Cluster Troubleshooting","conversation":{"__ref":"Conversation:conversation:3966586"},"id":"message:3966586","revisionNum":5,"uid":3966586,"depth":0,"board":{"__ref":"Blog:board:AppsonAzureBlog"},"author":{"__ref":"User:user:1594022"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" \n   \n  Learn about new AKS features to enhance your overall cluster troubleshooting and more in this blogpost. ","introduction":"","metrics":{"__typename":"MessageMetrics","views":5185},"postTime":"2023-10-27T14:32:26.307-07:00","lastPublishTime":"2023-10-27T21:15:27.526-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" In the dynamic world of cloud-native applications and microservices, it's crucial to excel in observability and troubleshooting within your AKS clusters. Timely diagnosis and resolution of deployment issues are key to meeting service level objectives (SLOs) and service level incidents (SLIs) while reducing downtime. \n   \n Today in Azure Portal, we're introducing three new features that will redefine your cluster troubleshooting experience:  \n \n Kubernetes events: While troubleshooting your cluster, you might face problems such as pod evictions, node failures, or application crashes. Kubernetes events provide real-time notifications about these events, helping you quickly diagnose the root causes of issues. By monitoring events, you can pinpoint the exact moment when an issue occurs and take immediate corrective actions.  \n Cluster autoscaler metrics: If your cluster experiences fluctuating workloads or resource constraints, cluster autoscaler metrics can assist in identifying when and how the autoscaler is making scaling decisions. This insight helps troubleshoot scaling issues and fine-tune your cluster's resource allocation for optimal performance.  \n Node saturation metrics: In the event of application slowdowns or resource allocation issues, node saturation metrics can help identify nodes that are struggling to meet resource demands. This feature is invaluable when troubleshooting performance bottlenecks in your cluster, ensuring you can allocate resources optimally.  \n \n   \n Kubernetes Events: Real-time Cluster Signals  \n Kubernetes events provide a real-time mechanism for tracking and communicating significant occurrences and state changes within your cluster. Whether it's the creation of a new pod, a node failure, or an application deployment, events capture crucial information like event types, involved objects, reasons, and descriptive messages.  \n   \n You can browse the events of your cluster by navigating to the Events menu item under Kubernetes resources from the Azure portal overview page for your cluster. By default, all events are shown: \n \n   \n Note: Kubernetes events do not persist throughout your cluster life cycle, as there is no mechanism for retention. They are short-lived, only available for one hour after the event is generated. To store events for a longer time period, enable Container Insights. \n   \n Learn more about Kubernetes events here: Use Kubernetes events for troubleshooting \n   \n Cluster Autoscaler Metrics: Resource Allocation Fine-Tuning  \n Cluster autoscaler (CAS) is a feature that automatically adjusts the size of your AKS cluster based on workload demands. It scales up the cluster by adding nodes when there are pending pods that can't be scheduled due to resource constraints, and scales down by removing idle nodes to save resources. It helps optimize resource utilization and ensures your cluster can handle varying workloads efficiently.  To enhance troubleshooting and observability across the node pools in your cluster, we've surfaced additional metrics to inform scaling related problems you may encounter. \n   \n Navigate to the Node pools blade to see it updated with useful CAS information, entrypoints for adjusting scale parameters and CAS-events:  \n \n   \n   \n Upon clicking into any of the event cards, you will see a filtered list of CAS-specific events, allowing you to root cause node pools not reaching their target node count and other issues: \n \n   \n Learn more about cluster autoscaling here: Use the cluster autoscaler in Azure Kubernetes Service (AKS) \n   \n Optimizing Node Performance with Node Saturation Metrics  \n Maintaining the right balance of resources in your AKS cluster is essential for your applications to run smoothly. When a node becomes overloaded, it can lead to application slowdowns, process timeouts (context deadline exceeded), and even failures. To address this, we've introduced node saturation metrics for CPU, Memory, and Disk utilization, directly sourced from the Kubernetes API.   \n   \n Note below that the CPU, memory, and disk utilization metrics are colored orange if the used amount is higher than your allocatable amount, and colored red if pressure conditions were triggered. It is possible to have percentages greater than 100% due to how the Kubernetes API allocates for resource reservations, learn more: Resource reservations (AKS) | Microsoft Learn \n   \n You can browse nodes and their utilization metrics in the Nodes view of the Node pools page in AKS Portal: \n \n   \n To see any pressure conditions that may have fired on your nodes, you can click directly on their status to drill down the root cause:  \n   \n Learn more about node saturation troubleshooting: High CPU usage remediation steps | High Memory usage remediation steps \n   \n   ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"4986","kudosSumWeight":8,"repliesCount":2,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE2MGk0NTg1RjU3NkMwMDI4OUM3?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE2OGk0RUVFMzY3QjE2OUREMDY4?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE2OWkzQkVDNjI4RDkxRkMxMzMx?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE3M2lDRTg2NkE2MDZEMTU2Q0U2?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDU","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE3Nmk1OTdBMDFGNUQzQkI2N0FF?revision=5\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDY","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zOTY2NTg2LTUyMDE3N2k4OTgwNEUzQUIyNkQyNUI0?revision=5\"}"}}],"totalCount":6,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:3782789":{"__typename":"Conversation","id":"conversation:3782789","topic":{"__typename":"BlogTopicMessage","uid":3782789},"lastPostingActivityTime":"2024-02-22T10:35:08.810-08:00","solved":false},"User:user:213843":{"__typename":"User","uid":213843,"login":"Justin Davies","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS0yMTM4NDMtMjkxMjY4aUEzQkExQzExRjM4MEEzNEY"},"id":"user:213843"},"BlogTopicMessage:message:3782789":{"__typename":"BlogTopicMessage","subject":"Azure Kubernetes upgrades and Long Term Support","conversation":{"__ref":"Conversation:conversation:3782789"},"id":"message:3782789","revisionNum":12,"uid":3782789,"depth":0,"board":{"__ref":"Blog:board:AppsonAzureBlog"},"author":{"__ref":"User:user:213843"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":"","introduction":"","metrics":{"__typename":"MessageMetrics","views":29866},"postTime":"2023-04-18T00:46:46.638-07:00","lastPublishTime":"2023-04-18T05:26:41.235-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" \n \n \n Microsoft has long invested in the upstream Kubernetes community, and as our Azure team members have led and participated in the Kubernetes release process, we’ve listened to what our customers say about the pace of Kubernetes development. Today we are excited to announce the introduction of Azure Kubernetes Service (AKS) Long Term Support (LTS). \n   \n We’re hearing from customers across a variety of organizations, from healthcare to manufacturing and beyond, who need a longer window of stability.  We’ve heard from ISVs that having to be on a constant treadmill to keep their environments in sync with community releases adds a significant burden to delivering value to their customers. \n   \n For organizations with multiple teams or complex environments, staying on top of upgrades can pose a significant challenge.  With three releases happening each year and a year of support for any given release, updates require frequent action.  LTS will help teams plan and test upgrades on a longer timeline, while staying on a supported Kubernetes version. \n   \n It is critically important for all Kubernetes users that when they choose to run their applications on versions of Kubernetes that are not maintained by the community that the entire stack from the operating system to the Kubernetes components are maintained and patched by their service provider.  The only way to host your applications on a Kubernetes version that is out of community support is to either run without security updates, or to put significant effort into forking the version, and cherry picking or resolving security issues yourself. \n   \n Based on feedback from our customers, we decided to put a team together to do just that. \n   \n We will be forking and maintaining the Kubernetes codebase for the LTS version once it leaves community support and maintaining this in the open. \n   \n The first AKS version that can have Long Term Support will be 1.27, to be released in May 2023. While running a cluster at an LTS version, customers will receive support and security updates for two years from the GA date (instead of the usual one year). \n   \n We intend to restart the community’s kubernetes WG-LTS to collaborate across the ecosystem to collect requirements and define processes and tooling required for creating secure and stable long term support releases of Kubernetes in the future. https://github.com/aks-lts is a work in progress, and we welcome feedback and contributions. \n   \n Customers will be able to opt in to LTS support for Kubernetes 1.27 at any time, or spin up Kubernetes 1.27 clusters and node pools during that two year period. \n   \n Making upgrades simple and safe \n Upgrading with confidence requires an understanding of how any change will affect your continuity of cluster operations. AKS supports fully automated in-place cluster upgrades (controlled via upgrade schedules) or manual in case you need more control over when these happen.    \n   \n In order to make the upgrade process for Kubernetes minor versions easier, the objects in ETCD are automatically converted to the newer APIs.  And now AKS will detect if you are using a deprecated API anywhere (for example operators or your code), and we will prevent the upgrade, and warn you in order to stop you from inadvertently breaking your applications.  You can override to force the upgrade or correct the API usage and retry after a period of time. \n   \n You decide when to move from one Kubernetes version to another, allowing you to plan and test your migrations.  For non-LTS clusters, each Kubernetes version is supported for 12 months. After 12 months, the minor version will shift to platform support only. Our new platform support policy provides customers with Azure infrastructure support while the cluster is in an n-3 version (where n is the latest supported AKS GA minor version). Platform support does not include anything related to Kubernetes functionality and components, but provides customers with additional support beyond what was previously provided for unsupported versions. \n   \n AKS will make the automatic upgrade of out of support clusters predictable to ensure they remain within a Kubernetes supported version. When a cluster in an n-3 version is about to drop to n-4, AKS will automatically upgrade the cluster to n-2.   For example, Kubernetes v1.25 will be upgraded to v1.26 during the v1.29 GA release. For more information, see the AKS documentation. \n   \n We always recommend our customers stay within community support, and whether your needs are best served by an LTS Kubernetes release or an automatically upgraded cluster, Azure's support commitment to you is the same.  Instead of a constant race to keep up with an ever-changing API surface while worrying about unpatched CVEs, Azure Kubernetes Service customers can grow their cloud native estates in confidence of their support and continuity. \n   \n For more information on Kubernetes version support on AKS, assess your options, and for pricing information, take a look at the Supported Kubernetes section on Azure Docs. \n \n \n ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"5244","kudosSumWeight":8,"repliesCount":7,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:3751557":{"__typename":"Conversation","id":"conversation:3751557","topic":{"__typename":"BlogTopicMessage","uid":3751557},"lastPostingActivityTime":"2023-10-06T13:19:39.754-07:00","solved":false},"User:user:980258":{"__typename":"User","uid":980258,"login":"MichaelWithrow","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS05ODAyNTgtNDM5NjkwaTI1QkE3MTcxNDlCQ0IyMzA"},"id":"user:980258"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4M2kyRjFDRjNEMDdGN0NBQUUw?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4M2kyRjFDRjNEMDdGN0NBQUUw?revision=2","title":"MichaelWithrow_2-1675788298283.png","associationType":"TEASER","width":1508,"height":870,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4MmlFMkRFMEIwRjZEMUVFMTFD?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4MmlFMkRFMEIwRjZEMUVFMTFD?revision=2","title":"MichaelWithrow_0-1675788298275.png","associationType":"BODY","width":1404,"height":621,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4MWk1QTk2REFBMDlFRDY1NTBF?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4MWk1QTk2REFBMDlFRDY1NTBF?revision=2","title":"MichaelWithrow_1-1675788298278.png","associationType":"BODY","width":1061,"height":487,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4NGlDREFDM0I2RkFDNTEzMEI3?revision=2\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4NGlDREFDM0I2RkFDNTEzMEI3?revision=2","title":"MichaelWithrow_3-1675788298287.png","associationType":"BODY","width":1600,"height":722,"altText":null},"BlogTopicMessage:message:3751557":{"__typename":"BlogTopicMessage","subject":"Preview support for Kata VM Isolated Containers on AKS for Pod Sandboxing","conversation":{"__ref":"Conversation:conversation:3751557"},"id":"message:3751557","revisionNum":2,"uid":3751557,"depth":0,"board":{"__ref":"Blog:board:AppsonAzureBlog"},"author":{"__ref":"User:user:980258"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" The rise of cloud-native and shift to containerized workloads has revolutionized the velocity of application development and drastically improved the ease of deployment when building applications. While these technologies provide many benefits, they also present a security risk when the shared kernel and the container host are exposed to untrusted malicious container code. One way to mitigate this risk is by running each pod/container in a dedicated, lightweight VM with resources like compute, memory, networking carved out from the parent VM on a dedicated kernel. This is known as Pod Sandboxing.  Pod Sandboxing allows you to continue to co-locate pods on the same host but adds a layer of isolation to help mitigate shared kernel attacks and reduce risks from escaped containers when running in a shared agent node.  \n   \n ","introduction":"","metrics":{"__typename":"MessageMetrics","views":23503},"postTime":"2023-02-24T04:48:58.948-08:00","lastPublishTime":"2023-02-24T04:48:58.948-08:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Azure Kubernetes Service (AKS) now supports pod sandboxing in preview in all Azure regions on a subset of Azure VM Sizes that support Nested Virtualization.   \n   \n Pod Sandboxing compliments other security measures and data protection controls and provides the isolation needed within a single VM node, as well as to protect containers that process sensitive information on AKS. This added functionality also avoids the “operations tax” associated with running standard VM nodes per workload. Pod sandboxing on AKS seamlessly integrates with the existing AKS feature set, making it easy to transition the deployment with simple pod annotation changes to existing workloads while continuing to use existing deployment and monitoring practices. While other methods require that you recompile your code or run into other compatibility requirements, Pod Sandboxing in AKS can run any container unmodified inside a secure VM boundary.   \n   \n Microsoft Approach to Pod Sandboxing   \n \n   \n On AKS, we are adding the pod sandboxing functionality using Kata Containers to provide hypervisor-based isolation per pod. Kata containers is a popular open-source project from the OpenInfra Foundation, with a highly active contributing community and production workloads running in many organizations. Its ability to seamlessly extend the Kubernetes capabilities and provide high workload conformance with negligible performance penalty made it a suitable choice for AKS.   \n   \n Kata Containers on AKS are built on top of a security-hardened Azure hypervisor using Mariner Linux AKS Container Host (MACH). The isolation per pod is achieved by using a nested lightweight Kata VM that carves out resources from a parent VM node. In this model, each Kata pod gets its own kernel per nested Kata guest VM. This allows users to pack many Kata containers in a single guest VM, while continuing to run containers in the parent VM, providing strong Isolation boundary within a shared AKS Cluster. \n   \n Historically, AKS customers have been dependent on spinning up separate clusters or node pools to strongly isolate workloads of different teams. While multiple cluster and node pool deployment architectures may be suitable for the isolation requirements of many organizations, there are cases for which a single cluster with shared VM node pools can be more efficient, for example when running untrusted and trusted pods in the same node or co-locating daemon-sets and privilege containers on the same node for faster local communication and functional grouping. In scenarios like these where the container’s code cannot be trusted or your workloads require isolation from the parent node’s kernel, kubelet and system pods, this pod sandboxing on AKS feature can meet your requirements.  \n   \n Although pod sandboxing brings the capability to host mixed workloads/tenant level workloads within a single AKS cluster, there is more to security than just the pod sandbox. We recommend you follow the best practices, particularly when looking for control plane isolation and cluster level isolation: Azure Kubernetes Service (AKS) considerations for multitenancy - Azure Architecture Center | Microsoft Learn. \n   \n The Tech Stack Powering Pod Sandboxing  \n As part of our core operational principles at Microsoft, we have embraced the culture of contributing to and working with the OSS community, with a particular focus on the OpenInfra Foundation, CNCF and other cloud-native projects. In line with this, we have adopted two large open-source projects: Kata Containers and Cloud-Hypervisor and have committed to building services on top of them. These projects will continue to power the pod sandboxing feature on AKS and Microsoft continues to shape future releases from our customer learnings through project contributions and open sourcing the components designed to improving container security and isolation. \n   \n The technology  \n The technical stack that enables the pod sandboxing capabilities on AKS and the basic scaffolding to add confidentiality to the AKS container offering is based on the following key components:  \n \n Mariner AKS Container Host (aka Linux Container Host on AKS)  \n Microsoft Hypervisor with Linux Root Partition.  \n \n \n Open-source Cloud Hypervisor as the Virtual Machine Monitor (VMM) running within Mariner Container Host  \n Integration with Kata Container runtime   \n \n \n   \n   \n Mariner AKS Container Host - Microsoft announced preview of Mariner as Linux container host on AKS in the fall of 2022. Mariner is Microsoft’s internal Linux distribution that is optimized to run on Azure and provides operational consistency with smaller/ leaner and security hardened image. \n   \n Microsoft hypervisor - Microsoft hypervisor is a mature virtualization platform that is battletested on Azure and on-premises deployment, and the cornerstone of some of the key virtualization features in Windows.  \n   \n Linux Root Partition – Linux kernel has been adapted so that Linux can run as the root partition for Microsoft Hypervisor. It will run the management software for the stack and control the hypervisor.  \n   \n Cloud Hypervisor VMM (Virtual Machine Monitor) is the end-user facing/user space software that is used for creating and managing the lifetime of virtual machines. Microsoft will continue playing an active role stewarding in the project supporting and contributing to community efforts.  \n   \n Cloud Hypervisor brings fast boot times for the utility VM use cases (such as Kata Containers) with container-friendly optimizations, enables run time configurable VM resources, and implements a minimal set of drivers to enable container workloads on Azure. \n   \n Kata Container Integration – Kata Containers are a widely used and adopted open-source project. The project is working to build a secure container runtime with lightweight virtual machines (VM) that perform and can be operated/ managed like containers while providing stronger workload isolation leveraging hardware virtualization technology. (Reference picture from katacontainers.io)  \n \n   \n   \n How it works  \n The workflow to deploy Pod Sandboxing using Kata guest VMs is like the regular containerd workflow for deploying containers, with the following differences:  \n \n To deploy containers in the sandboxed environment, the pod specification YAML file must specify the Kata runtime class name.  \n The Kata runtime class name is pre-configured on AKS to activate the Kata Shim (containerd-shim-kata-v2) instead of the regular containerd-shim.  \n \n \n The Kata Shim executes Cloud Hypervisor and instructs it to create a lightweight Kata VM with the Kata Agent running inside it.  \n The Kata Shim delegates the creation and management of containers to the Kata Agent. The Kata Agent creates and executes these containers inside the guest VM.  \n When AKS deletes the Sandboxed Pod, the Kata Shim shuts down the guest VM, releasing the resources associated with it back to the container host.   \n \n \n  Detailed instructions on AKS deployment can be found here.  \n   \n Looking ahead  \n We are excited to learn how this feature can enable industries like Finance, Health, and SaaS/ISV Partners that are looking to optimize operations while still achieving high security with Kata VM Isolated Containers on AKS. We look forward to continuing to innovate in the open-source space of container isolation and confidential computing within Kata and make AKS the platform of choice to run your most sensitive workloads at scale.  ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"7787","kudosSumWeight":8,"repliesCount":5,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4M2kyRjFDRjNEMDdGN0NBQUUw?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4MmlFMkRFMEIwRjZEMUVFMTFD?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDM","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4MWk1QTk2REFBMDlFRDY1NTBF?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDQ","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4M2kyRjFDRjNEMDdGN0NBQUUw?revision=2\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDU","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNzUxNTU3LTQzOTU4NGlDREFDM0I2RkFDNTEzMEI3?revision=2\"}"}}],"totalCount":5,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:3650443":{"__typename":"Conversation","id":"conversation:3650443","topic":{"__typename":"BlogTopicMessage","uid":3650443},"lastPostingActivityTime":"2022-10-12T12:55:54.701-07:00","solved":false},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUwNDQzLTQxMjE1M2kzODhBOTY2Mjk3NEUyNTFD?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUwNDQzLTQxMjE1M2kzODhBOTY2Mjk3NEUyNTFD?revision=6","title":"JustinDavies_0-1665526215221.png","associationType":"BODY","width":1099,"height":746,"altText":null},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUwNDQzLTQxMjE1NGlGMEUwREI1RTM2MTAwOEQx?revision=6\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUwNDQzLTQxMjE1NGlGMEUwREI1RTM2MTAwOEQx?revision=6","title":"JustinDavies_1-1665526215221.png","associationType":"BODY","width":555,"height":382,"altText":null},"BlogTopicMessage:message:3650443":{"__typename":"BlogTopicMessage","subject":"Azure Kubernetes Service Microsoft Ignite announcements","conversation":{"__ref":"Conversation:conversation:3650443"},"id":"message:3650443","revisionNum":6,"uid":3650443,"depth":0,"board":{"__ref":"Blog:board:AppsonAzureBlog"},"author":{"__ref":"User:user:213843"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" When we talk to Azure Kubernetes Service (AKS) customers about the adoption of Kubernetes, two focus areas come up just about every time: the challenges of running at scale and the ongoing desire to improve their security posture. At Microsoft Ignite 2022, we announced a number of new features for AKS to help you operate your Kubernetes clusters and workloads at the scale you need, and we’ve continued to innovate in the open to improve the security posture and landscape, providing a seamless, and secure platform for your applications. \n   ","introduction":"","metrics":{"__typename":"MessageMetrics","views":24258},"postTime":"2022-10-12T09:10:17.481-07:00","lastPublishTime":"2022-10-12T12:55:54.701-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":" Operate at scale \n   \n Most customers tell us they prefer to run a larger number of smaller clusters, but some very large workloads can be run much more efficiently on bigger clusters. To support this, we have increased the number of nodes you can have in a single Azure Kubernetes Service (AKS) cluster from 1,000 to 5,000.  This will allow you to reduce the number of clusters needed to run your workloads, reducing the operational overhead needed to support application teams. \n   \n When using the uptime SLA you can request a quota increase across all node pools in the cluster by raising a support request.  \n   \n Networking at scale \n   \n One of the things we hear a lot from our customers is around IP address exhaustion.  The release of Dynamic IP allocation has helped to reduce the need to pre-allocate IP addresses from your virtual network by assigning IP addresses at workload creation time, but we’ve gone a step further and announced the availability of Azure CNI Overlay networking.  CNI Overlay will allocate IP addresses from a private CIDR, and translate your pod IP addresses  to your VNet address space.  This dramatically reduces the IP burden when running your workloads and keeps you in control of how you setup your networking topology.  \n   \n As your workloads scale on AKS, your egress networking needs to change, and with that you can move from Load Balancer egress to Virtual Network NAT, which increases the outbound flows per IP address to 64,000.  You can add up to 16 IP addresses, giving you a total of over a million egress flows. \n   \n \n   \n   \n Maintenance Windows and Event Grid notifications \n   \n As you increase the scale of your Cloud Native estate, the ability to manage updates and maintenance becomes even more important.  We previously announced planned maintenance windows allowing you to control the timing of cluster upgrades. We've now integrated that functionality with Azure Maintenance configurations, enabling a consistent management interface for Azure resources.  This provides you with a single place to setup maintenance across their entire Azure infrastructure through a single pane of glass. \n   \n We have supported AKS as an Event Grid source for over a year now, and based on your feedback are adding more events, starting with notifications around when new Kubernetes versions are available.  This is the start of providing customers the mechanism to automate their Azure infrastructure through events across Azure infrastructure for AKS, and will continue to onboard further events over time. \n   \n General Availability for Arm-based nodes for improved price performance \n   \n Support for ARM64 architecture is now generally available.  You can now have the confidence to run your cloud native workloads on ARM64 in production.  The power profile, and cost savings from migrating to the ARM architecture give you’re the power to choose how and where you run your applications.  Making things as simple as possible for our customers is one of the driving forces behind how we ship our features, so just by simply choosing a DP or EP series Virtual Machine for your node pool will also deploy the ARM64 version of Ubuntu and get you up and running sooner. \n   \n Security in the Open \n   \n Whilst customers can currently use Pod identity with their Kubernetes workloads, the setup process and dependencies made this difficult to implement.  We have released AAD workload identity to address this and make it much simpler to use by leveraging  Managed Identity with federated identity for your workloads. This gets rid of the need to use Custom Resource Definitions and improves on the scalability of managed identities.  Using Azure SDKs or MSAL in your workloads is now seamless and provides a level of simplification that will help application developers concentrate on delivering value through software rather than having to scaffold authentication from an operational perspective. \n   \n We also announced the General Availability of AMD SEV-SNP confidential VM nodes on AKS.  Microsoft is the first cloud provider to support AMD SEV-SNP in Kubernetes and this capability will help organizations meet their data security goals and add to defense-in-depth without adding developer and operational overhead. \n   \n Confidential VM nodes enable the full lift-and-shift of Linux workloads on Kubernetes managed infrastructure to Azure, with minimal performance degradation and full AKS feature parity. Customers can also verify the trustworthiness of the node by establishing hardware root of trust through remote attestation (reference example here). With heterogenous node pool support, a single AKS cluster can have confidential and non-confidential node pools and reduce cluster operational overhead. This capability also enables you to split your workload to process sensitive data in a confidential VM node, where memory encryption keys are generated from the chipset itself.   \n   \n You can get started today! Here is a quick-start guide to add a confidential VM node pool to your existing cluster, and learn more about our announcement here. \n   \n \n   \n What else? \n   \n Azure Kubernetes Fleet Manager is being introduced to addressed multi-cluster and at-scale scenarios like Kubernetes resource propagation and multi-cluster load balancing across multiple AKS clusters. \n   \n Kubernetes apps is a new marketplace offer that allows partners to create, publish, and manage commercial Kubernetes solutions in marketplace with click through deployments to Azure Kubernetes service with flexible billing models. \n   \n Hot on the heels of Ignite is Kubecon at the end of October where we will be announcing more AKS features, so stay tuned for those! ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"5943","kudosSumWeight":8,"repliesCount":0,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUwNDQzLTQxMjE1M2kzODhBOTY2Mjk3NEUyNTFD?revision=6\"}"}},{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDI","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS0zNjUwNDQzLTQxMjE1NGlGMEUwREI1RTM2MTAwOEQx?revision=6\"}"}}],"totalCount":2,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"Conversation:conversation:4130496":{"__typename":"Conversation","id":"conversation:4130496","topic":{"__typename":"BlogTopicMessage","uid":4130496},"lastPostingActivityTime":"2024-10-08T00:33:36.928-07:00","solved":false},"User:user:1564375":{"__typename":"User","uid":1564375,"login":"Alibengtsson","registrationData":{"__typename":"RegistrationData","status":null},"deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/dS0xNTY0Mzc1LTU3MjI0NWlFNjYzNTYyRDBBOEUzOTkx"},"id":"user:1564375"},"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MTMwNDk2LTU3NzIxOGk0OTMwRTg3MjJEMjNERjdE?revision=11\"}":{"__typename":"AssociatedImage","url":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MTMwNDk2LTU3NzIxOGk0OTMwRTg3MjJEMjNERjdE?revision=11","title":"Alibengtsson_0-1714743413367.jpeg","associationType":"TEASER","width":924,"height":780,"altText":null},"BlogTopicMessage:message:4130496":{"__typename":"BlogTopicMessage","subject":"Azure Kubernetes Service Baseline - The Hard Way","conversation":{"__ref":"Conversation:conversation:4130496"},"id":"message:4130496","revisionNum":11,"uid":4130496,"depth":0,"board":{"__ref":"Blog:board:AppsonAzureBlog"},"author":{"__ref":"User:user:1564375"},"teaser@stripHtml({\"removeProcessingText\":true,\"truncateLength\":-1})":" Are you ready to tackle Kubernetes on Azure like a pro? Embark on the “AKS Baseline - The Hard Way” and prepare for a journey that’s likely to be a mix of command line, detective work and revelations. This is a serious endeavour that will equip you with deep insights and substantial knowledge. \n   \n As you navigate through the intricacies of Azure, you’ll not only face challenges but also accumulate a wealth of learning that will sharpen your skills and broaden your understanding of cloud infrastructure. Get set for an enriching experience that’s all about mastering the ins and outs of Azure Kubernetes Service! \n   \n \n   \n   \n   ","introduction":"","metrics":{"__typename":"MessageMetrics","views":42492},"postTime":"2024-05-03T05:57:00.557-07:00","lastPublishTime":"2024-10-08T00:33:36.928-07:00","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})":"   \n Azure Kubernetes Service Baseline - The Hard Way \n   \n Welcome to \"Azure Kubernetes Service - The Hard Way\". From this blog, you will learn how to deploy a scalable and resilient Kubernetes cluster on Azure using Azure Kubernetes Service (AKS) and a number of adjacent Azure services. You will also learn how to apply best practices from the AKS baseline reference architecture, which provides a recommended starting point for a general purpose AKS cluster infrastructure. \n   \n The target audience of these instructions is intermediate to advanced Kubernetes users who want to improve their skills and knowledge about AKS and Azure. You will need to have some familiarity with Kubernetes concepts and tools such as pods, services, deployments, and kubectl. You will also need to have an Azure subscription with contributor permission and access to a bash shell. We recommend using Azure Cloud Shell for this, as it has all the necessary tools already installed. \n   \n To access the cloud shell, you can type shell.azure.com in your web browser. Bear in mind that Cloud Shell times out after around 20 minutes of inactivity. Make sure to copy all the environment variables you will be creating, to a file so that you don't loose them. \n Upon finishing, you will have a deeper understanding of how to use AKS to deploy and manage a scalable and resilient Kubernetes cluster on Azure. You will also have a working AKS cluster that follows the AKS baseline reference architecture. Expect the entire exercise to take up to eight hours. \n   \n \n Overview \n   \n The AKS baseline is a reference architecture that provides a set of best practices and recommendations for deploying a scalable and resilient Azure Kubernetes Service (AKS) cluster. One of the key components of the AKS baseline is the network design, which is divided into several subnets and virtual networks (VNets) to isolate and protect the cluster resources from external and internal threats. In this article, we will describe the purpose and configuration of each subnet and VNet in the AKS baseline, and how they work together to provide a robust network infrastructure for your AKS cluster. \n   \n IP Plan \n   \n IP planning is an important aspect of deploying an AKS cluster and Azure services in general, as it affects the scalability, performance, security, and availability of the cluster and its workloads. IP planning involves choosing the right network topology, IP address ranges, subnet sizes, and network policies for the cluster and its nodes, pods, and services. For more information on IP planning for an AKS cluster, see Plan IP addressing for your cluster and Best practices for network resources in AKS. \n This is the proposed IP design that we will adhere to throughout the documentation. \n   \n \n \n Note: IP planning is a crucial step that requires careful consideration of the number and size of subnets for your current solution, as well as the potential for future expansion. You should avoid using excessively large IP ranges, and instead be economical with IP and allocate only what you need for the present and the future. \n \n   \n Each subnet in AKS baseline has a specific purpose and configuration, further information can be found below. \n   \n Hub VNET \n   \n \n \n Azure Firewall Subnet: This subnet is where the Azure Firewall is deployed. The firewall acts as an egress controller for the AKS cluster, filtering and logging the outbound traffic from the cluster to external resources or services. It also provides network address translation (NAT) functionality, which allows the cluster to access resources that are not reachable by private IP addresses. The subnet size can be small for this particular case, as it only needs to accommodate one firewall instance. \n \n \n   \n \n \n Azure Bastion Subnet: This subnet is where the Azure Bastion service is deployed. Azure Bastion is a fully managed service that provides secure and seamless Remote Desktop Protocol (RDP) and Secure Shell (SSH) access to your virtual machines directly through the Azure portal⁴. This subnet is used for management and operations only, and it does not expose any resources to the internet. The subnet name must be AzureBastionSubnet, and the subnet size must be /26 or larger. \n \n \n   \n \n \n Jump Box Subnet: This subnet is where the jump server resides, where operation teams can login and access services in the spoke, to perform operations and maintenance. \n \n \n   \n Spoke VNET \n   \n \n \n Endpoints Subnet: This subnet is where the private endpoints for Azure services are deployed. Private endpoints are a network interface that connects you privately and securely to a service powered by Azure Private Link. Private endpoints allow you to access Azure services, such as Azure Container Registry, Azure Key Vault, or Azure Storage, without exposing them to the internet or requiring a public IP address. The subnet name can be any valid name, and the subnet size depends on the number of private endpoints you need to create. \n \n \n   \n \n \n AKS Subnet: This subnet is where the AKS cluster nodes are deployed. It uses Azure CNI networking, which assigns IP addresses from the subnet to each node and pod. The subnet size depends on the number of nodes and pods per node, and it should be large enough to accommodate the expected growth. The subnet also has a Network Security Group (NSG) that controls the inbound and outbound traffic to and from the nodes. \n \n \n   \n \n \n Azure Application Gateway Subnet: This subnet is where the Azure Application Gateway is deployed. The application gateway acts as an ingress controller for the AKS cluster, routing external traffic to the appropriate services or pods inside the cluster. It also provides web application firewall (WAF) functionality, which helps protect the applications from common web attacks. The subnet size can be small, as it only needs to accommodate one or more application gateway instances. The subnet also has a NSG that allows inbound traffic on ports 80 and 443, and outbound traffic to the AKS cluster. \n \n \n   \n \n \n Azure Loadbalancer Subnet: The load balancer subnet is a part of the network topology that supports the AKS cluster. It is where the internal load balancer (ILB) resides and assigns IP addresses to the services that are exposed within the cluster. \n \n \n   \n Prepare Environment Variables for HUB VNET and SPOKE VNET \n   \n Let’s use the IP plan to set up some environment variables for the Hub VNet and adjust its configuration accordingly to the IP Plan above. Make sure to also save your environment variables to a text file, so that you can restore them later. \n Configure the hub according to the IP Plan (see image above). \n   \n HUB_VNET_NAME=Hub_VNET\nFW_SUBNET_NAME=AzureFirewallSubnet\nBASTION_SUBNET_NAME=AzureBastionSubnet\nHUB_VNET_PREFIX=10.0.0.0/22 # IP address range of the Virtual network (VNet).\nBASTION_SUBNET_PREFIX=10.0.0.128/26 # IP address range of the Bastion subnet \nFW_SUBNET_PREFIX=10.0.0.0/26 # IP address range of the Firewall subnet\nJUMPBOX_SUBNET_PREFIX=10.0.0.64/26 # IP address range of the Jumpbox subnet\n \n Configure the spoke according to the IP Plan (see image above). \n   \n SPOKE_VNET_NAME=Spoke_VNET\nJUMPBOX_SUBNET_NAME=JumpboxSubnet\nENDPOINTS_SUBNET_NAME=endpoints-subnet\nAPPGW_SUBNET_NAME=app-gw-subnet\nAKS_SUBNET_NAME=aks-subnet\nLOADBALANCER_SUBNET_NAME=loadbalancer-subnet\nSPOKE_VNET_PREFIX=10.1.0.0/22 # IP address range of the Virtual network (VNet).\nAKS_SUBNET_PREFIX=10.1.0.0/24 # IP address range of the AKS subnet\nLOADBALANCER_SUBNET_PREFIX=10.1.1.0/28 # IP address range of the Loadbalancer subnet\nAPPGW_SUBNET_PREFIX=10.1.2.0/24 # IP address range of the Application Gateway subnet\nENDPOINTS_SUBNET_PREFIX=10.1.1.16/28 # IP address range of the Endpoints subnet\n \n Infrastructure Deployment \n   \n The objective of this part is to guide you through the process of deploying the AKS baseline infrastructure. The infrastructure consists of the essential components and configurations that are required for running a secure and scalable AKS cluster. \n   \n Prepare Environment Variables for infrastructure \n   \n This configuration sets up environment variables for the names and locations of various network and security resources, such as resource groups, virtual networks, subnets, network security groups, firewall, application gateway, route table, identity, virtual machines, AKS cluster, and ACR registry. \n   \n \n Note: Since the Azure container registry has a globally unique FQDN name, you need to assign a distinct value to the ACR_NAME environment variable, else the ACR deployment will fail. Also, the ACR name can only container lowercase letters and numbers. \n \n   \n HUB_RG=rg-hub\nSPOKE_RG=rg-spoke\nLOCATION=eastus \nBASTION_NSG_NAME=Bastion_NSG\nJUMPBOX_NSG_NAME=Jumpbox_NSG\nAKS_NSG_NAME=Aks_NSG\nENDPOINTS_NSG_NAME=Endpoints_NSG\nLOADBALANCER_NSG_NAME=Loadbalancer_NSG\nAPPGW_NSG=Appgw_NSG\nFW_NAME=azure-firewall\nAPPGW_NAME=AppGateway\nROUTE_TABLE_NAME=spoke-rt\nAKS_IDENTITY_NAME=aks-msi\nJUMPBOX_VM_NAME=Jumpbox-VM\nAKS_CLUSTER_NAME=private-aks\nACR_NAME=<Globally unique name of the azure container registry>\nSTUDENT_NAME=<e.g. your first name> # don't use spaces\n \n Create the Resource Groups for the Hub and Spoke. \n   \n az group create --name $HUB_RG --location $LOCATION\naz group create --name $SPOKE_RG --location $LOCATION\n \n Create Network Security Groups (NSG) and Virtual Network (VNET) for the Hub. \n   \n In this step, we will begin by establishing Network Security Groups (NSGs) that will subsequently be associated with their respective subnet. It is crucial to note that there are specific prerequisites concerning security rules for certain subnets that must be met before a service can be deployed. Azure Bastion is one of them. \n For Azure Bastion, we are establishing security rules to permit both the control and data plane access to the AzureBastion. For a more detailed understanding of these rules, please refer to the following resource: More Information. \n   \n \n Create the NSG for AzureBastionSubnet. \n \n az network nsg create \\\n --resource-group $HUB_RG \\\n --name $BASTION_NSG_NAME \\\n --location $LOCATION\n \n \n Associate the required inbound security rules to the NSG. \n \n az network nsg rule create --name AllowHttpsInbound \\\n --nsg-name $BASTION_NSG_NAME --priority 120 --resource-group $HUB_RG\\\n --access Allow --protocol TCP --direction Inbound \\\n --source-address-prefixes \"Internet\" \\\n --source-port-ranges \"*\" \\\n --destination-address-prefixes \"*\" \\\n --destination-port-ranges \"443\"\n\t\n \taz network nsg rule create --name AllowGatewayManagerInbound \\\n --nsg-name $BASTION_NSG_NAME --priority 130 --resource-group $HUB_RG\\\n --access Allow --protocol TCP --direction Inbound \\\n --source-address-prefixes \"GatewayManager\" \\\n --source-port-ranges \"*\" \\\n --destination-address-prefixes \"*\" \\\n --destination-port-ranges \"443\"\n\t\n\taz network nsg rule create --name AllowAzureLoadBalancerInbound \\\n --nsg-name $BASTION_NSG_NAME --priority 140 --resource-group $HUB_RG\\\n --access Allow --protocol TCP --direction Inbound \\\n --source-address-prefixes \"AzureLoadBalancer\" \\\n --source-port-ranges \"*\" \\\n --destination-address-prefixes \"*\" \\\n --destination-port-ranges \"443\"\n\t\n\t\n\taz network nsg rule create --name AllowBastionHostCommunication \\\n --nsg-name $BASTION_NSG_NAME --priority 150 --resource-group $HUB_RG\\\n --access Allow --protocol TCP --direction Inbound \\\n --source-address-prefixes \"VirtualNetwork\" \\\n --source-port-ranges \"*\" \\\n --destination-address-prefixes \"VirtualNetwork\" \\\n --destination-port-ranges 8080 5701\n \n \n Associate the required outbound security rules to the NSG. \n \n az network nsg rule create --name AllowSshRdpOutbound \\\n --nsg-name $BASTION_NSG_NAME --priority 100 --resource-group $HUB_RG\\\n --access Allow --protocol \"*\" --direction outbound \\\n --source-address-prefixes \"*\" \\\n --source-port-ranges \"*\" \\\n --destination-address-prefixes \"VirtualNetwork\" \\\n --destination-port-ranges 22 3389\n\t\n az network nsg rule create --name AllowAzureCloudOutbound \\\n --nsg-name $BASTION_NSG_NAME --priority 110 --resource-group $HUB_RG\\\n --access Allow --protocol Tcp --direction outbound \\\n --source-address-prefixes \"*\" \\\n --source-port-ranges \"*\" \\\n --destination-address-prefixes \"AzureCloud\" \\\n --destination-port-ranges 443\n\t\n\taz network nsg rule create --name AllowBastionCommunication \\\n --nsg-name $BASTION_NSG_NAME --priority 120 --resource-group $HUB_RG\\\n --access Allow --protocol \"*\" --direction outbound \\\n --source-address-prefixes \"VirtualNetwork\" \\\n --source-port-ranges \"*\" \\\n --destination-address-prefixes \"VirtualNetwork\" \\\n --destination-port-ranges 8080 5701\n\t\n\taz network nsg rule create --name AllowHttpOutbound \\\n --nsg-name $BASTION_NSG_NAME --priority 130 --resource-group $HUB_RG\\\n --access Allow --protocol \"*\" --direction outbound \\\n --source-address-prefixes \"*\" \\\n --source-port-ranges \"*\" \\\n --destination-address-prefixes \"Internet\" \\\n --destination-port-ranges 80\n \n \n Create an NSG for the JumpBox subnet. \n \n az network nsg create \\\n --resource-group $HUB_RG \\\n --name $JUMPBOX_NSG_NAME \\\n --location $LOCATION\n \n \n Create the HUB VNET with one subnet for Azure Bastion Subnet and associate it to the bastion NSG. \n \n az network vnet create \\\n --resource-group $HUB_RG \\\n --name $HUB_VNET_NAME \\\n --address-prefixes $HUB_VNET_PREFIX \\\n --subnet-name $BASTION_SUBNET_NAME \\\n --subnet-prefixes $BASTION_SUBNET_PREFIX \\\n --network-security-group $BASTION_NSG_NAME\n \n \n Create a subnet for the Azure Firewall. \n \n az network vnet subnet create \\\n --resource-group $HUB_RG \\\n --vnet-name $HUB_VNET_NAME \\\n --name $FW_SUBNET_NAME \\\n --address-prefixes $FW_SUBNET_PREFIX\n \n \n Create a subnet for the Virtual Machine that will be used as \"jumpbox\". \n \n az network vnet subnet create \\\n --resource-group $HUB_RG \\\n --vnet-name $HUB_VNET_NAME \\\n --name $JUMPBOX_SUBNET_NAME \\\n --address-prefixes $JUMPBOX_SUBNET_PREFIX \\\n --network-security-group $JUMPBOX_NSG_NAME\n \n You have successfully configured the network for your hub virtual network.You have established three subnets and two NSGs, as depicted on the image: \n   \n   \n \n \n \n To Validate your deployment, navigate to the Azure portal at https://portal.azure.com and enter your login credentials. \n \n \n Once logged in, locate and select your resource group called rg-hub where the hub vnet is deployed. \n \n \n Select your vnet called HUB_VNET. \n \n \n In the left-hand side menu, under the Settings section, select Subnets. \n \n \n Make sure that your subnets have the appropriate IP range and that Network Security Groups (NSGs) are correctly associated with their respective subnets as depicted below. \n \n \n   \n \n   \n Create Network Security Groups and Virtual Network for the Spoke. \n   \n We will now start to setup the spoke vnet, subnets and their respective NSGs. \n \n Create the NSG for AKS subnet. \n \n az network nsg create \\\n --resource-group $SPOKE_RG \\\n --name $AKS_NSG_NAME \\\n --location $LOCATION\n \n \n Create the NSG for endpoints subnet, were the endpoints will reside. \n \n az network nsg create \\\n --resource-group $SPOKE_RG \\\n --name $ENDPOINTS_NSG_NAME \\\n --location $LOCATION\n \n \n Create the NSG for load balancer subnet, were the internal load balancer will reside. \n \n az network nsg create \\\n --resource-group $SPOKE_RG \\\n --name $LOADBALANCER_NSG_NAME \\\n --location $LOCATION\n \n \n To use an NSG with your application gateway, you need to open these port ranges: \n \n Inbound rules: The Internet service tag needs access to port 65200-65535 for the backend health API. Your application traffic needs access to TCP port 80 and/or 443. for futher information refer to Required security rules for Application Gateway for more information. \n az network nsg create \\\n --resource-group $SPOKE_RG \\\n --name $APPGW_NSG \\\n --location $LOCATION\n \n \n Create the NSG rule to allow application traffic, on port 443 and 80. \n \n # Allow Internet Client request on Port 443 and 80\naz network nsg rule create \\\n --resource-group $SPOKE_RG \\\n --nsg-name $APPGW_NSG \\\n --name Allow-Internet-Inbound-HTTP-HTTPS \\\n --priority 100 \\\n --source-address-prefixes Internet \\\n --destination-port-ranges 80 443 \\\n --access Allow \\\n --protocol Tcp \\\n --description \"Allow inbound traffic to port 80 and 443 to Application Gateway from client requests originating from the Internet\"\n \n \n Create the NSG rule to allow application traffic, on port range 65200-65535. \n \n # Infrastructure ports\naz network nsg rule create \\\n --resource-group $SPOKE_RG \\\n --nsg-name $APPGW_NSG \\\n --name Allow-GatewayManager-Inbound \\\n --priority 110 \\\n --source-address-prefixes \"GatewayManager\" \\\n --destination-port-ranges 65200-65535 \\\n --access Allow \\\n --protocol Tcp \\\n --description \"Allow inbound traffic to ports 65200-65535 from GatewayManager service tag\"\n \n \n Create the spoke VNET with one subnet for AKS Subnet and associate it to the AKS NSG. \n \n az network vnet create \\\n --resource-group $SPOKE_RG \\\n --name $SPOKE_VNET_NAME \\\n --address-prefixes $SPOKE_VNET_PREFIX \\\n --subnet-name $AKS_SUBNET_NAME \\\n --subnet-prefixes $AKS_SUBNET_PREFIX \\\n\t--network-security-group $AKS_NSG_NAME\n \n \n Create the subnet for Endpoints and associate it to the endpoints NSG. \n \n az network vnet subnet create \\\n --resource-group $SPOKE_RG \\\n --vnet-name $SPOKE_VNET_NAME \\\n --name $ENDPOINTS_SUBNET_NAME \\\n --address-prefixes $ENDPOINTS_SUBNET_PREFIX \\\n\t--network-security-group $ENDPOINTS_NSG_NAME\n \n \n Create subnet for the load balancer that will be used for ingress traffic and associate it to the loadbalancer NSG. \n \n az network vnet subnet create \\\n --resource-group $SPOKE_RG \\\n --vnet-name $SPOKE_VNET_NAME \\\n --name $LOADBALANCER_SUBNET_NAME \\\n --address-prefixes $LOADBALANCER_SUBNET_PREFIX \\\n\t--network-security-group $LOADBALANCER_NSG_NAME\n \n \n Create subnet for the Application Gateway and associate it to the Application Gateway NSG. \n \n az network vnet subnet create \\\n --resource-group $SPOKE_RG \\\n --vnet-name $SPOKE_VNET_NAME \\\n --name $APPGW_SUBNET_NAME \\\n --address-prefixes $APPGW_SUBNET_PREFIX \\\n\t--network-security-group $APPGW_NSG\n \n   \n You have successfully configured the network for your spoke virtual network. You should now have established the following setup in your Azure subscription. \n   \n   \n \n   \n \n \n Navigate to the Azure portal at https://portal.azure.com again. \n \n \n Locate and select your resource group called rg-spoke where the spoke vnet is deployed. \n \n \n Select the vnet called Spoke_VNET. \n \n \n In the left-hand side menu, under the Settings section, select Subnets. \n \n \n Make sure that your subnets have the appropriate IP range and that Network Security Groups (NSGs) are correctly associated with their respective subnets. \n \n \n   \n \n   \n Create VNET Peering Between Hub and Spoke \n   \n The next step is to create a virtual network peering between the hub and spoke VNets. This will enable the communication between the VNETs and allow the AKS cluster to route traffic to the Firewall. \n   \n \n Before we can do a VNET peering we need to obtain the full resource id of the Spoke_VNET and Hub_VNET as they resides in different resource groups. \n \n SPOKE_VNET_ID=$(az network vnet show --resource-group $SPOKE_RG --name $SPOKE_VNET_NAME --query id --output tsv)\n \n HUB_VNET_ID=$(az network vnet show --resource-group $HUB_RG --name $HUB_VNET_NAME --query id --output tsv)\n \n \n Now, create a peering connection from the hub to the spoke virtual network. \n \n az network vnet peering create \\\n --resource-group $HUB_RG \\\n --name hub-to-spoke \\\n --vnet-name $HUB_VNET_NAME \\\n --remote-vnet $SPOKE_VNET_ID \\\n --allow-vnet-access\n \n \n Then create a peering connection from the spoke to hub virtual network. \n \n az network vnet peering create \\\n --resource-group $SPOKE_RG \\\n --name spoke-to-hub \\\n --vnet-name $SPOKE_VNET_NAME \\\n --remote-vnet $HUB_VNET_ID \\\n --allow-vnet-access\n \n Peering should be established and the high level design should now look like this: \n   \n   \n \n   \n \n \n Navigate to the Azure portal at https://portal.azure.com \n \n \n Locate and select the resource group called rg-spoke where the spoke vnet is deployed. \n \n \n Select the vnet called Spoke_VNET. \n \n \n In the left-hand side menu, under the Settings section, select peerings. \n \n \n Ensure that the peering status is set to Connected. \n \n \n Repeat step 4 - 7 but for Hub_VNET. \n \n \n   \n \n   \n Create Azure Bastion and Jumpbox VM \n   \n \n The Bastion Host needs a Public IP. Create the Public IP address. \n \n az network public-ip create \\\n --resource-group $HUB_RG \\\n --name Bastion-PIP \\\n --sku Standard \\\n --allocation-method Static\n \n \n Create JumpBox Virtual Machine. \n \n \n Note: Ensure you specify a password for the admin user called azureuser. The password length must be between 12 and 72. Password must have 3 of the following: 1 lower case character, 1 upper case character, 1 number and 1 special character. \n \n   \n az vm create \\\n --resource-group $HUB_RG \\\n --name $JUMPBOX_VM_NAME \\\n --image Ubuntu2204 \\\n --admin-username azureuser \\\n --admin-password <SPECIFY A PASSWORD HERE> \\\n --vnet-name $HUB_VNET_NAME \\\n --subnet $JUMPBOX_SUBNET_NAME \\\n --size Standard_B2s \\\n --storage-sku Standard_LRS \\\n --os-disk-name $JUMPBOX_VM_NAME-VM-osdisk \\\n --os-disk-size-gb 128 \\\n --public-ip-address \"\" \\\n --nsg \"\" \n \n \n Create the bastion host in hub vnet and associate it to the public IP. \n \n \n Note: Azure Bastion service requires a dedicated subnet named AzureBastionSubnet to provide secure and seamless RDP/SSH connectivity to your virtual machines. When you deploy Azure Bastion service, it will automatically create this subnet for you, if it does not exist in the target virtual network. However, if the subnet already exists, it must meet the minimum size of /26 or larger, otherwise the deployment will fail. \n \n   \n az network bastion create \\\n --resource-group $HUB_RG \\\n --name bastionhost \\\n --public-ip-address Bastion-PIP \\\n --vnet-name $HUB_VNET_NAME \\\n --location $LOCATION\n \n \n \n Upon successful installation of the Jumpbox Virtual Machine (VM). Navigate to the Azure portal at https://portal.azure.com \n \n \n Locate and select your rg-hub where the Jumpbox has been deployed. \n \n \n Within your resource group, find and click on the Jumpbox VM. \n \n \n In the left-hand side menu, under the Connect section, select ‘Bastion’. \n \n \n Enter the credentials for the Jumpbox VM and verify that you can log in successfully. \n \n \n For additional information on accessing VMs through Bastion, please refer to this Microsoft Azure Bastion tutorial \n After completing these steps, The high-level targeted architecture now matches the following diagram: \n   \n   \n \n   \n Create an Azure Firewall and Setup a User Defined Route (UDR) \n   \n To secure your outbound traffic, you can use an Azure Firewall. The following steps will help you restrict the outbound access and to certain FQDNs that are needed by the cluster. further information can be found here: Control egress traffic using Azure Firewall in Azure Kubernetes Service (AKS) \n   \n \n Create Azure Firewall, and deploy it to it to firewall subnet in hub vnet. \n \n az network firewall create \\\n --resource-group $HUB_RG \\\n --name $FW_NAME \\\n --location $LOCATION \\\n --vnet-name $HUB_VNET_NAME \\\n --enable-dns-proxy true\n\n \n \n The firewall needs a Public IP address. Create the Public IP. \n \n az network public-ip create \\\n --name fw-pip \\\n --resource-group $HUB_RG \\\n --location $LOCATION \\\n --allocation-method static \\\n --sku standard\n\n \n \n Associate the public IP address with the Firewall. \n \n az network firewall ip-config create \\\n --firewall-name $FW_NAME \\\n --name FW-config \\\n --public-ip-address fw-pip \\\n --resource-group $HUB_RG \\\n --vnet-name $HUB_VNET_NAME\n\n \n \n Update the existing Azure Firewall configuration. \n \n az network firewall update \\\n --name $FW_NAME \\\n --resource-group $HUB_RG \n \n \n Create Network rules in Azure Firewall. \n \n   \n The following network rules allows outbound traffic from any source address to certain destinations and ports. If the required destination is not specified the AKS cluster will fail to deploy. \n Please note that these transactions are slow. Expect each rule to require around 5 minutes to complete. \n az network firewall network-rule create -g $HUB_RG -f $FW_NAME --collection-name 'aksfwnr' -n 'apiudp' --protocols 'UDP' --source-addresses '*' --destination-addresses \"AzureCloud.$LOCATION\" --destination-ports 1194 --action allow --priority 100\n\n\naz network firewall network-rule create -g $HUB_RG -f $FW_NAME --collection-name 'aksfwnr' -n 'apitcp' --protocols 'TCP' --source-addresses '*' --destination-addresses \"AzureCloud.$LOCATION\" --destination-ports 9000\n\n\naz network firewall network-rule create -g $HUB_RG -f $FW_NAME --collection-name 'aksfwnr' -n 'time' --protocols 'UDP' --source-addresses '*' --destination-fqdns 'ntp.ubuntu.com' --destination-ports 123\n \n \n Create Azure Firewall application rule. \n \n This rule specifies the FQDN's which are required by AKS, AzureKubernetesService tag which include all the FQDNs listed in Outbound network and FQDN rules for AKS clusters. \n   \n For more information about required egress destinations, see Outbound network and FQDN rules for Azure Kubernetes Service (AKS) clusters \n az network firewall application-rule create -g $HUB_RG -f $FW_NAME --collection-name 'aksfwar' -n 'fqdn' --source-addresses '*' --protocols 'http=80' 'https=443' --fqdn-tags \"AzureKubernetesService\" --action allow --priority 100\n \n \n Create a route table in the spoke. \n \n az network route-table create \\\n --resource-group $SPOKE_RG \\\n --name $ROUTE_TABLE_NAME\n\n \n \n Create a route to the internet via the Azure Firewall. \n \n In order to create the route we need to obtain the private IP address of the Firewall.To get the private IP address of the Firewall, you need to run the following command: \n az network firewall show --resource-group $HUB_RG --name $FW_NAME |grep privateIPAddress\n \n Then store the output (the ip address) in an environment variable: \n FW_PRIVATE_IP=<IP Address from previous command>\n \n Create the route table to route egress traffic to the firewall in the hub VNET: \n az network route-table route create \\\n --resource-group $SPOKE_RG \\\n --name default-route \\\n --route-table-name $ROUTE_TABLE_NAME \\\n --address-prefix 0.0.0.0/0 \\\n --next-hop-type VirtualAppliance \\\n --next-hop-ip-address $FW_PRIVATE_IP\n\n \n \n Note: The route will direct all traffic (0.0.0.0/0) to the next hop type of VirtualAppliance, which is the firewall instance. The next hop IP address is the private IP address of the firewall, which is stored in the environment variable $FW_PRIVATE_IP. This way, the traffic from the AKS subnet will be routed to the firewall instance on its private endpoint. This will allow you to perform inspection on outbound traffic. \n \n   \n \n Associate the route table with the AKS subnet. \n \n az network vnet subnet update \\\n --resource-group $SPOKE_RG \\\n --vnet-name $SPOKE_VNET_NAME \\\n --name $AKS_SUBNET_NAME \\\n --route-table $ROUTE_TABLE_NAME\n \n You have successfully configured the firewall in the hub VNet, set up network and application rules, and created a route table associated with the AKS subnet to direct all internet-bound traffic through the Azure Firewall. \n   \n   \n \n   \n \n   \n \n \n To validate your deployment, navigate to the Azure portal at https://portal.azure.com \n \n \n Locate and select your resource group called rg-hub where the hub vnet is deployed. \n \n \n Select your firewall called azure-firewall. \n \n \n In the left-hand side menu, under the Settings section, select Rules. \n \n \n Click on Network rule collection \n \n \n Verify that you have a network rule collection called aksfwnr which should contain 3 rules. Inspect the rules. \n \n \n   \n \n   \n \n \n Click on Application rule collection. \n \n \n Verify that you have an application rule collection called aksfwar which should contain 1 rule. Inspect the rule. \n \n \n   \n \n \n \n Lets validate the routing between AKS subnet and Azure Firewall, in the Azure portal, in the top menu select Resource Groups. \n \n \n Select resource group rg-spoke. \n \n \n Select routing table called spoke-rt. \n \n \n Ensure that the default route has a prefix of 0.0.0.0/0 and the next hop is set to the virtual appliance with the IP address of the Azure Firewall. Also, make sure that the routing table is associated with the AKS subnet called aks-subnet. \n \n \n   \n \n   \n Deploy Azure Kubernetes Service \n   \n This part covers deploying AKS with outbound traffic configured to use a user-defined routing table, ensuring traffic passes through the Azure Firewall. A private DNS zone is also created when deploying a private AKS cluster. A user-assigned identity with necessary permissions is assigned to the cluster and load balancer subnet. This identity is a type of managed identity in Azure. \n   \n \n Create a user-assigned managed identity. \n \n az identity create \\\n --resource-group $SPOKE_RG \\\n --name $AKS_IDENTITY_NAME-${STUDENT_NAME}\n \n \n Get the id of the user managed identity. \n \n IDENTITY_ID=$(az identity show \\\n --resource-group $SPOKE_RG \\\n --name $AKS_IDENTITY_NAME-${STUDENT_NAME} \\\n --query id \\\n --output tsv)\n \n \n Get the principal id of the user managed identity. \n \n PRINCIPAL_ID=$(az identity show \\\n --resource-group $SPOKE_RG \\\n --name $AKS_IDENTITY_NAME-${STUDENT_NAME} \\\n --query principalId \\\n --output tsv)\n \n \n Get the scope of the routing table. \n \n RT_SCOPE=$(az network route-table show \\\n --resource-group $SPOKE_RG \\\n --name $ROUTE_TABLE_NAME \\\n --query id \\\n --output tsv)\n \n \n Assign permissions for the AKS user defined managed identity to the routing table. \n \n az role assignment create \\\n --assignee $PRINCIPAL_ID\\\n --scope $RT_SCOPE \\\n --role \"Network Contributor\"\n \n \n Assign permission for the AKS user defined managed identity to the load balancer subnet. \n \n LB_SUBNET_SCOPE=$(az network vnet subnet list \\\n --resource-group $SPOKE_RG \\\n --vnet-name $SPOKE_VNET_NAME \\\n --query \"[?name=='$LOADBALANCER_SUBNET_NAME'].id\" \\\n --output tsv)\n \n az role assignment create \\\n --assignee $PRINCIPAL_ID \\\n --scope $LB_SUBNET_SCOPE \\\n --role \"Network Contributor\"\n\n \n \n Note: Granting the Network Contributor role to the load balancer subnet in AKS could result in over-privileged access. To minimize security risks, it is recommended to only provide AKS with the necessary permissions to function effectively, adhering to the principle of least privilege access. For more information refer to Creating Azure custom role. \n \n   \n \n Retrieve the scope of AKS subnet, were AKS shall be deployed. \n \n AKS_SUBNET_SCOPE=$(az network vnet subnet list \\\n --resource-group $SPOKE_RG \\\n --vnet-name $SPOKE_VNET_NAME \\\n --query \"[?name=='$AKS_SUBNET_NAME'].id\" \\\n --output tsv)\n \n \n Deploy a Highly Available Private AKS Cluster. \n \n   \n To deploy a highly available private AKS cluster, you can use the following command: \n This command creates an AKS cluster with two system nodes, using the specified VNet subnet ID and cluster name. It is configured as a private cluster with user-defined routing and OIDC issuer and workload identity enabled. The network plugin and policy are set to Azure, and the public FQDN is disabled. The cluster is deployed across availability zones 1, 2, and 3. \n   \n For more information about OIDC and Workload Identity refer to Use Microsoft Entra Workload ID with Azure Kubernetes Service (AKS) \n   \n az aks create --resource-group $SPOKE_RG --node-count 2 --vnet-subnet-id $AKS_SUBNET_SCOPE --name $AKS_CLUSTER_NAME-${STUDENT_NAME} --enable-private-cluster --outbound-type userDefinedRouting --enable-oidc-issuer --enable-workload-identity --generate-ssh-keys --assign-identity $IDENTITY_ID --network-plugin azure --network-policy azure --disable-public-fqdn --zones 1 2 3\n \n \n Note: A private AKS cluster has its Kubernetes API endpoint isolated from public access, allowing access only within the same virtual network. To communicate with the private AKS cluster from a jumpbox in a different virtual network, a virtual network link must be created between the two networks for DNS resolution. This will be covered in a later section. \n \n   \n \n An additional nodepool will be created to host user workloads. Auto-scaling is enabled to allow for automatic scaling out and scaling in based on demand. The worker nodes will be distributed across three different zones to ensure higher availability. \n \n az aks nodepool add --resource-group $SPOKE_RG --cluster-name $AKS_CLUSTER_NAME-${STUDENT_NAME} --name userpool --node-count 3 --mode user --zones 1 2 3 --enable-cluster-autoscaler --min-count 1 --max-count 5\n \n \n Create a virtual network link to resolve AKS private endpoint from HUB vnet. \n \n   \n Fetch the node group of the AKS cluster, and save it in an environment variable. \n NODE_GROUP=$(az aks show --resource-group $SPOKE_RG --name $AKS_CLUSTER_NAME-${STUDENT_NAME} --query nodeResourceGroup -o tsv)\n \n Fetch the AKS DNS zone name. \n DNS_ZONE_NAME=$(az network private-dns zone list --resource-group $NODE_GROUP --query \"[0].name\" -o tsv)\n\n \n Fetch the ID of the HUB virtual network. \n HUB_VNET_ID=$(az network vnet show -g $HUB_RG -n $HUB_VNET_NAME --query id --output tsv)\n \n Create a virtual network link between the hub virtual network and the AKS private DNS zone, that was created for the AKS cluster. \n az network private-dns link vnet create --name \"hubnetdnsconfig\" --registration-enabled false --resource-group $NODE_GROUP --virtual-network $HUB_VNET_ID --zone-name $DNS_ZONE_NAME \n \n Validate your deployment in the Azure portal. \n \n \n Navigate to the Azure portal at https://portal.azure.com. \n \n \n Click on Resource groups to view all of your resource groups in your subscription. You should have 3 RGs which you have created,MC_rg-spoke_private-aks-xxxx_eastus, rg-hub and rg-spoke \n \n \n   \n \n Note: MC_rg-spoke_private-aks-xxxx_eastus is a resource group automatically created when deploying an AKS cluster. It is used by Azure to manage resources for the cluster, this particular resource group is also known as Node group. \n \n   \n   \n \n   \n \n \n Verify that a virtual network link exists between the Hub and spoke to enable the jumpbox to resolve the AKS domain name and access the cluster. Select the node group called MC_rg-spoke_private-aks-xxxxx_eastus. \n \n \n Select the Private DNS zone. \n \n \n On your left hand side menu, under Settings click on Virtual network links. \n \n \n Validate that there is a link name called hubnetdnsconfig and the link status is set to Completed and the virtual network is set to Hub_VNET. \n \n \n   \n \n   \n \n \n On the top menu click Resource groups and choose rg-spoke from the resource group list. \n \n \n Click on the AKS resource called private-aks-. Verify that the Private cluster is set to Enabled. \n \n \n   \n \n   \n \n Verify AKS control plane connectivity. \n \n In this section we will verify that we are able to connect to the AKS cluster from the jumpbox, firstly we need to connect to the cluster successfully and secondly we need to verify that the kubernetes client is able to communicate with the AKS control plane from the jumpbox. \n   \n \n \n Select resource group rg-hub where the Jumpbox has been deployed. \n \n \n Within your resource group, find and click on the virtual machine called Jumpbox VM. \n \n \n In the left-hand side menu, under Connect section, select Bastion. \n \n \n Enter the credentials for the Jumpbox VM and verify that you can log in successfully. \n \n \n Once successfully logged in to the jumpbox you need to install a few tools. Run the commands one by one, or create a bash script. \n \n \n   \n # Update apt repo\nsudo apt update \n# Install Docker\nsudo apt install docker.io -y\n# Install azure CLI\ncurl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash\n# Install AKS CLI (kubectl)\nsudo az aks install-cli\n# Add user to Docker group\nsudo usermod -aG docker $USER\n \n \n Now, login to Azure in order to obtain AKS credentials. \n \n az login\naz account set --subscription <SUBSCRIPTION ID>\n \n \n Note: To check the current subscription, run the command: az account show To change the subscription, run the command: az account set --subscription , where the ID of the desired subscription. You can find the subscription ID by running the command: az account list --output table \n \n   \n \n Add your Environment variables to the jumpbox bash shell. \n \n SPOKE_RG=rg-spoke\nAKS_CLUSTER_NAME=private-aks\nSTUDENT_NAME=<WRITE YOUR STUDENT NAME HERE>\n \n \n Download the AKS credentials onto the jumpbox. \n \n az aks get-credentials --resource-group $SPOKE_RG --name $AKS_CLUSTER_NAME-${STUDENT_NAME}\n \n \n Ensure you can list resources in AKS. \n \n kubectl get nodes\n \n The following output shows the result of running the command kubectl get nodes on with kubectl CLI. \n azureuser@Jumpbox-VM:~$ kubectl get nodes\nNAME STATUS ROLES AGE VERSION\naks-nodepool1-12240482-vmss000000 Ready agent 89m v1.27.9\naks-nodepool1-12240482-vmss000001 Ready agent 89m v1.27.9\naks-userpool-16991029-vmss000000 Ready agent 78m v1.27.9\n \n \n Log out from the Jumpbox host. \n \n Congratulations! You have completed the steps to deploy a private AKS cluster and configure its network settings. You have assigned a user assigned identity to the cluster that has the required permissions to modify the user-defined routing table and load balancer subnet. You have also created a virtual network link between the hub virtual network and the private DNS zone of the cluster. This enables the jumpbox to resolve the private API server of the cluster and access it for management and maintenance purposes. \n   \n \n   \n \n   \n Deploy Azure Container Registry \n   \n In this section, we will learn how to deploy a private Azure Container Registry that will store our container images. A private container registry is a type of container registry that is not accessible from the public internet. To enable access to the private container registry from the jumpbox, we need to create some networking resources that will allow us to resolve the container registry name and connect to it securely. These resources are: a private endpoint, a private link, and a virtual network link. We will see how to create and configure these resources in the following steps. We will also test the connection to the private container registry by pushing some images to it from the jumpbox. \n   \n   \n \n Create the Azure Container Registry, and disable public access to the registry. \n \n az acr create \\\n --resource-group $SPOKE_RG \\\n --name $ACR_NAME \\\n --sku Premium \\\n --admin-enabled false \\\n --location $LOCATION \\\n --allow-trusted-services false \\\n --public-network-enabled false\n \n \n IMPORTANT: Ensure you have a globally unique name for your ACR, or else the deployment will fail. \n \n \n Configure the private DNS zone for ACR. \n \n az network private-dns zone create \\\n --resource-group $SPOKE_RG \\\n --name \"privatelink.azurecr.io\"\n \n \n Create a virtual network link to the spoke network. \n \n az network private-dns link vnet create \\\n --resource-group $SPOKE_RG \\\n --zone-name \"privatelink.azurecr.io\" \\\n --name ACRDNSSpokeLink \\\n --virtual-network $SPOKE_VNET_NAME \\\n --registration-enabled false\n \n \n Create a virtual network link to the hub network. \n \n \n Note: The $HUB_VNET_ID variable specifies the full path to the virtual network in another resource group, allowing the command to correctly link to it. Make sure the environment variable $HUB_VNET_ID is populated before running the command below. If it is empty, just rerun the command: \n \n HUB_VNET_ID=$(az network vnet show --resource-group $HUB_RG --name $HUB_VNET_NAME --query id --output tsv)\n \n   \n \n az network private-dns link vnet create \\\n --resource-group $SPOKE_RG \\\n --zone-name \"privatelink.azurecr.io\" \\\n --name ACRDNSHubLink \\\n --virtual-network $HUB_VNET_ID \\\n --registration-enabled false\n \n \n Create ACR private endpoint. \n \n   \n To create a private endpoint for an Azure Container Registry (ACR), you need to obtain the resource ID of the container registry. This resource ID is used to specify the target resource when creating the private endpoint. \n REGISTRY_ID=$(az acr show --name $ACR_NAME \\\n --query 'id' --output tsv)\n\n \n az network private-endpoint create \\\n --name ACRPrivateEndpoint \\\n --resource-group $SPOKE_RG \\\n --vnet-name $SPOKE_VNET_NAME \\\n --subnet $ENDPOINTS_SUBNET_NAME \\\n --private-connection-resource-id $REGISTRY_ID \\\n --group-ids registry \\\n --connection-name PrivateACRConnection\n \n \n Configure DNS record for ACR. \n \n   \n In this section we will configure DNS records for an Azure Container Registry (ACR) using Azure Private Link.This is to ensure that the ACR can be accessed over a private network connection, enhancing security by eliminating exposure to the public internet. \n Before we can configure the DNS record we need to obtain the private IP address of the ACR, both the control and data plane. \n Get endpoint IP configuration: \n   \n NETWORK_INTERFACE_ID=$(az network private-endpoint show \\\n --name ACRPrivateEndpoint \\\n --resource-group $SPOKE_RG \\\n --query 'networkInterfaces[0].id' \\\n --output tsv)\n \n Fetch the private IP address associated with the ACR. These IP addresses are used for data and control of the container registry. \n az network nic show --ids $NETWORK_INTERFACE_ID |grep azurecr.io -B 7\n \n In the output you should see two IP addresses, and their associated FQDNS. It should look similar to this: \n \"name\": \"privateEndpointIpConfig.9c4c0ee4-c187-4094-aede-fc0dabb70236\",\n \"primary\": true,\n \"privateIPAddress\": \"10.1.1.20\",\n \"privateIPAddressVersion\": \"IPv4\",\n \"privateIPAllocationMethod\": \"Dynamic\",\n \"privateLinkConnectionProperties\": {\n \"fqdns\": [\n \"acrforakssecurity.westus2.data.azurecr.io\"\n--\n \"name\": \"privateEndpointIpConfig.7ffb814c-aacc-4199-a07d-35f61df0ea1f\",\n \"primary\": false,\n \"privateIPAddress\": \"10.1.1.21\",\n \"privateIPAddressVersion\": \"IPv4\",\n \"privateIPAllocationMethod\": \"Dynamic\",\n \"privateLinkConnectionProperties\": {\n \"fqdns\": [\n \"acrforakssecurity.azurecr.io\"\n \n Note down the privateIPAddress and fqdns as it will be used in a later step (when creating DNS zones). \n \n Create a new 'A' record set for control in the private DNZ zone. \n \n az network private-dns record-set a create \\\n --name $ACR_NAME \\\n --zone-name privatelink.azurecr.io \\\n --resource-group $SPOKE_RG\n \n \n Create a new 'A' record set for data in the private DNZ zone. \n \n az network private-dns record-set a create \\\n --name $ACR_NAME.$LOCATION.data \\\n --zone-name privatelink.azurecr.io \\\n --resource-group $SPOKE_RG\n \n \n Update the 'A' record to contain the data IP address of the ACR. \n \n az network private-dns record-set a add-record \\\n --record-set-name $ACR_NAME.$LOCATION.data \\\n --zone-name privatelink.azurecr.io \\\n --resource-group $SPOKE_RG \\\n --ipv4-address <IP address assicoated with FQDN \"$ACR_NAME.$LOCATION.data.azurecr.io\">\n \n \n Update the 'A' record to contain the control IP address of the ACR. \n \n az network private-dns record-set a add-record \\\n --record-set-name $ACR_NAME \\\n --zone-name privatelink.azurecr.io \\\n --resource-group $SPOKE_RG \\\n --ipv4-address <IP address associated with FQDN \"$ACR_NAME.azurecr.io\">\n \n Validate your deployment in the Azure portal. \n \n \n Navigate to the Azure portal at https://portal.azure.com and enter your login credentials. \n \n \n log in and select the rg-spoke resource group. Verify that you have a container registry and a private endpoint named ACRPrivateEndpoint deployed in your resource group, as well as a network card named ACRPrivateEndpoint.nic.xxxxx. \n \n \n   \n \n   \n \n Select the private DNS zone named privatelink.azurecr.io. Ensure that you have two ‘A’ records, one for control and one for data, and that the correct IP addresses are configured. \n \n   \n \n \n In the left-hand side menu, under Settings section, select Virtual Network links. Ensure you have the link status set to completed for both hub and spoke. \n \n   \n \n \n Test the connection to ACR from the Jumpbox. \n \n In this section, you will learn how to check if you can access your private Azure Container Registry (ACR) and push Docker images to it. You will need to have the Azure CLI installed and logged in to your Azure account. You will also need to have Docker installed and running on your Jumpbox. Here are the steps to follow: \n   \n \n \n Select resource group rg-hub where the Jumpbox has been deployed. \n \n \n Within your resource group, find and click on the Jumpbox VM. \n \n \n In the left-hand side menu, under the Connect section, select ‘Bastion’. \n \n \n Enter the credentials for the Jumpbox VM and verify that you can log in successfully. \n \n \n Once successfully logged in to the jumpbox login to Azure if you have not already done so in previous steps. \n \n \n az login\n \n Identify your subscription id from the list, if you have several subscriptions. \n az account list -o table\n \n Set your subscription id to be the default subscription. \n az account set --subscription <SUBSCRIPTION ID>\n \n \n Validate private link connection. \n \n List your ACR in your subscription and note down the ACR name. \n az acr list -o table\n \n Example output: \n azureuser@Jumpbox-VM:~$ az acr list -o table\nNAME RESOURCE GROUP LOCATION SKU LOGIN SERVER CREATION DATE ADMIN ENABLED\n---------- ---------------- ---------- ------- --------------------- -------------------- ---------------\nalibaksacr rg-spoke eastus Premium alibaksacr.azurecr.io 2024-03-03T07:56:00Z False\n \n dig <REGISTRY NAME>.azurecr.io\n \n Example output shows the registry's private IP address in the address space of the subnet: \n \nazureuser@Jumpbox-VM:~$ dig alibaksacr.azurecr.io\n\n; <<>> DiG 9.18.18-0ubuntu0.22.04.2-Ubuntu <<>> alibaksacr.azurecr.io\n;; global options: +cmd\n;; Got answer:\n;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3738\n;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1\n\n;; OPT PSEUDOSECTION:\n; EDNS: version: 0, flags:; udp: 65494\n;; QUESTION SECTION:\n;alibaksacr.azurecr.io. IN A\n\n;; ANSWER SECTION:\nalibaksacr.azurecr.io. 60 IN CNAME alibaksacr.privatelink.azurecr.io.\nalibaksacr.privatelink.azurecr.io. 1800 IN A 10.1.1.21\n\n;; Query time: 8 msec\n;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)\n;; WHEN: Sun Mar 03 09:04:31 UTC 2024\n;; MSG SIZE rcvd: 103\n \n \n Test the connection to the container registry, you will push a container to it. You will need to create a Dockerfile, build the docker image, authenticate towards ACR and push the image to the container registry. \n \n vim Dockerfile\n \n Add the following content to the Dockerfile. \n FROM nginx\nEXPOSE 80\n \n Build the Docker image. \n docker build --tag nginx .\n \n Example output: \n azureuser@Jumpbox-VM:~$ docker build --tag nginx .\n\nSending build context to Docker daemon 222.7kB\nStep 1/3 : FROM nginx\nlatest: Pulling from library/nginx\na803e7c4b030: Pull complete \n8b625c47d697: Pull complete \n4d3239651a63: Pull complete \n0f816efa513d: Pull complete \n01d159b8db2f: Pull complete \n5fb9a81470f3: Pull complete \n9b1e1e7164db: Pull complete \nDigest: sha256:32da30332506740a2f7c34d5dc70467b7f14ec67d912703568daff790ab3f755\nStatus: Downloaded newer image for nginx:latest\n ---> 61395b4c586d\nStep 2/3 : EXPOSE 80\n ---> Running in d7267ee641b6\nRemoving intermediate container d7267ee641b6\n ---> 06a5ac2e4ba6\nStep 3/3 : CMD [“nginx”, “-g”, “daemon off;”]\n ---> Running in c02c94dc283c\nRemoving intermediate container c02c94dc283c\n ---> 49a47448ba86\nSuccessfully built 49a47448ba86\nSuccessfully tagged nginx:latest\n \n Create an alias of the image. \n docker tag nginx <CONTAINER REGISTRY NAME>.azurecr.io/nginx\n \n Authenticate to ACR with your AD user. \n az acr login --name <CONTAINER REGISTRY NAME> \n \n Upload the docker image to the ACR repository. \n docker push <CONTAINER REGISTRY NAME>.azurecr.io/nginx\n \n Example output: \n azureuser@Jumpbox-VM:~$ docker push acraksbl.azurecr.io/nginx\nUsing default tag: latest\nThe push refers to repository [acraksbl.azurecr.io/nginx]\nd26d4f0eb474: Pushed \na7e2a768c198: Pushed \n9c6261b5d198: Pushed \nea43d4f82a03: Pushed \n1dc45c680d0f: Pushed \neb7e3384f0ab: Pushed \nd310e774110a: Pushed \nlatest: digest: sha256:3dc6726adf74039f21eccf8f3b5de773080f8183545de5a235726132f70aba63 size: 1778\n \n \n To enable AKS to pull images from ACR, you can attach AKS to the ACR. This command updates the existing AKS cluster and attaches it to the ACR. \n \n az aks update \\\n --resource-group $SPOKE_RG \\\n --name $AKS_CLUSTER_NAME-${STUDENT_NAME} \\\n --attach-acr $ACR_NAME\n \n \n Validate AKS is able to pull images from ACR, by deploying a simple application to the AKS cluster. During deployment, the AKS cluster will pull the container image of the application from ACR. \n \n On the Jumpbox VM create a yaml file. \n vim test-pod.yaml\n \n Pro-tip: when you copy to vim, prevent vim from auto-indenting the text you paste. \n :set paste\n \n Press enter. \n Paste in the following manifest file which creates a pod named internal-test-app which fetches the docker images from our internal container registry, created in previous step. \n apiVersion: v1\nkind: Pod\nmetadata:\n name: internal-test-app\n labels:\n app: internal-test-app\nspec:\n containers:\n - name: nginx\n image: <ACR NAME>.azurecr.io/nginx\n ports:\n - containerPort: 80\n \n Create the pod. \n kubectl apply -f test-pod.yaml\n \n Verify that the pod is in running state. \n kubectl get po --show-labels\n \n Example output: \n azureuser@Jumpbox-VM:~$ kubectl get po \nNAME READY STATUS RESTARTS AGE\ninternal-test-app 1/1 Running 0 8s\n \n The next step is to set up an internal load balancer that will direct the traffic to our internal pod. The internal load balancer will be deployed in the load balancer subnet of the spoke-vnet. \n vim internal-app-service.yaml\n \n :set paste\n \n Press enter. \n Copy the following manifest to expose the pod to the internet. Replace with your subnet name stored in your local shell environment variable $LOADBALANCER_SUBNET_NAME. \n apiVersion: v1\nkind: Service\nmetadata:\n name: internal-test-app-service\n annotations:\n service.beta.kubernetes.io/azure-load-balancer-internal: \"true\"\n service.beta.kubernetes.io/azure-load-balancer-internal-subnet: \"<LOADBALANCER SUBNET NAME>\"\nspec:\n type: LoadBalancer\n ports:\n - port: 80\n selector:\n app: internal-test-app\n \n Deploy the service object in AKS. \n kubectl create -f internal-app-service.yaml\n \n Verify that your service object is created and associated with the pod that you have created, also ensure that you have recieved an external IP, which should be a private IP address range from the load balancer subnet. \n kubectl get svc -o wide\n \n Example output: \n azureuser@Jumpbox-VM:~$ kubectl get svc -o wide\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR\ninternal-test-app-service LoadBalancer 10.0.22.55 10.1.1.4 80:31644/TCP 112s app=internal-test-app\nkubernetes ClusterIP 10.0.0.1 <none> 443/TCP 13h <none>\n \n \n Note: Note down the EXTERNAL-IP (Private IP of the load balancer), as this will be used for creating the application gateway. \n \n   \n Verify that you are able to access the exposed Nginx pod from your jumpbox VM. \n azureuser@Jumpbox-VM:~$ curl <EXTERNAL-IP>\n \n Example output: \n azureuser@Jumpbox-VM:~$ curl 10.1.1.4\n<!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to nginx!</title>\n<style>\nhtml { color-scheme: light dark; }\nbody { width: 35em; margin: 0 auto;\nfont-family: Tahoma, Verdana, Arial, sans-serif; }\n</style>\n</head>\n<body>\n<h1>Welcome to nginx!</h1>\n<p>If you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.</p>\n\n<p>For online documentation and support please refer to\n<a href=\"http://nginx.org/\">nginx.org</a>.<br/>\nCommercial support is available at\n<a href=\"http://nginx.com/\">nginx.com</a>.</p>\n\n<p><em>Thank you for using nginx.</em></p>\n</body>\n</html>\n \n You have successfully deployed a private Azure Container Registry that is accessible from the jumpbox host. You also built and deployed the nginx image, which is only exposed over the private network. \n   \n \n   \n Deploy Azure Application Gateway. \n   \n In this section, you will set up an application gateway that will terminate TLS connections at its ingress. You will also learn how to perform these tasks: upload a certificate to Application Gateway, configure AKS as a backend pool by routing traffic to its internal load balancer, create a health probe to check the health of the AKS backend pool, and set up a WAF (Web Application Firewall) to defend against common web attacks. \n   \n \n Create public IP address with a domain name associated to the public IP resource. \n \n   \n The public IP address will be associated with a fully qualified domain name (FQDN) based on the location of your IP address and a unique name that you provide. For example, if you create an IP address in westeurope, the FQDN would look similar to this: \n myveryuniquename.westeurope.cloudapp.azure.com\n \n Lets make an environment variable of the uniqe name, and call it $DNS_NAME. \n DNS_NAME=<your unique name>\n \n az network public-ip create -g $SPOKE_RG -n AGPublicIPAddress --dns-name $DNS_NAME --allocation-method Static --sku Standard --location $LOCATION\n \n \n Create WAF policy. \n \n az network application-gateway waf-policy create --name ApplicationGatewayWAFPolicy --resource-group $SPOKE_RG\n \n \n Create self signed certificate. \n \n In order to expose your services to internet using HTTPs, you need to add a certificate to Application Gateway. In a production setting, this would be a trusted certificate from a certificate authority such as letsencrypt. In the interest of simplicity, you will instead create a self signed certificate, and upload to Application Gateway. \n Following are short instructions on how to create the self signed certificate. If you want to understand the details, or need more information, please review this page: https://learn.microsoft.com/en-us/azure/application-gateway/self-signed-certificates \n Step one is to create a Root CA Certificate. During the creation, you will need to provide an FQDN. This FQDN will be the one associated with the Public IP address created above. \n   \n To get the FQDN you can run the following command: \n az network public-ip show -g $SPOKE_RG -n AGPublicIPAddress --query dnsSettings.fqdn\n \n After this, use the following commands to create a key and sign the key (self signed). \n openssl genrsa -out my.key 2048\nopenssl req -new -x509 -sha256 -key my.key -out my.crt -days 365\n \n When prompted, type the password for the root key (and note it down), and the organizational information for the custom CA such as Country/Region, State, Org, OU, and the fully qualified domain name from the step above. Here is an example of how it might look: \n peter [ ~ ]$ openssl req -new -x509 -sha256 -key my.key -out my.crt -days 365\nYou are about to be asked to enter information that will be incorporated\ninto your certificate request.\nWhat you are about to enter is what is called a Distinguished Name or a DN.\nThere are quite a few fields but you can leave some blank\nFor some fields there will be a default value,\nIf you enter '.', the field will be left blank.\n-----\nCountry Name (2 letter code) [AU]:SE\nState or Province Name (full name) [Some-State]:\nLocality Name (eg, city) []:\nOrganization Name (eg, company) [Internet Widgits Pty Ltd]:\nOrganizational Unit Name (eg, section) []:\nCommon Name (e.g. server FQDN or YOUR name) []:uniqueappgwname.eastus.cloudapp.azure.com\nEmail Address []:johndoe@contoso.com\n \n Now, combine the private key and the certificate into a single .pfx file. Choose a good certificate password and make a note of it, as it will be used when creating the Application Gateway. \n openssl pkcs12 -export -out my.pfx -inkey my.key -in my.crt -password pass:<CERTIFICATE PASSWORD>\n \n \n Create Application Gateway. \n \n \n Note: Before executing the command below, make sure the certificate is located in your working directory. Replace with the password you used when creating the certificate and with the private IP of the load balancer. \n \n   \n az network application-gateway create \\\n --name AppGateway \\\n --location $LOCATION \\\n --resource-group $SPOKE_RG \\\n --vnet-name $SPOKE_VNET_NAME \\\n --subnet $APPGW_SUBNET_NAME \\\n --capacity 1 \\\n --sku WAF_v2 \\\n --http-settings-cookie-based-affinity Disabled \\\n --frontend-port 443 \\\n --http-settings-port 80 \\\n --http-settings-protocol Http \\\n --priority \"1\" \\\n --public-ip-address AGPublicIPAddress \\\n --cert-file my.pfx \\\n --cert-password \"<CERTIFICATE PASSWORD>\" \\\n --waf-policy ApplicationGatewayWAFPolicy \\\n --servers <LOAD BALANCER PRIVATE IP>\n \n \n Create a custom probe for the application gateway that will monitor the health of the AKS backend pool. \n \n az network application-gateway probe create \\\n --gateway-name $APPGW_NAME \\\n --resource-group $SPOKE_RG \\\n --name health-probe \\\n --protocol Http \\\n --path / \\\n --interval 30 \\\n --timeout 120 \\\n --threshold 3 \\\n --host 127.0.0.1\n \n \n Associate the health probe to the backend pool. \n \n az network application-gateway http-settings update -g $SPOKE_RG --gateway-name $APPGW_NAME -n appGatewayBackendHttpSettings --probe health-probe\n \n Validate your deployment in the Azure portal. \n \n \n Select the resource group called rg-spoke where the application gateway is deployed. \n \n \n Select your Azure Application Gateway called AppGateway. Ensure you have a Public IP address and Tier set to WAF v2. \n \n \n   \n \n \n \n In the left-hand side menu, under the Settings section, select Backend pools and choose from the list appGatewayBackendPool. \n \n \n Ensure the target type is set to IP address or FQDN and target is set to the IP address of your internal load balancer. \n \n \n   \n \n \n \n On the top menu click on AppGateway | Backend pools. \n \n \n Lets verify the backend settings of Application Gateway, in the left-hand side menu choose *Backend settings. \n \n \n From the list click on appGatewayBackendHttpSettings validate that the backend port is configured for port 80, and that health probe called health-probe is associated to the backend. \n \n \n   \n \n \n \n Press Cancel \n \n \n Verify that we have Web application rules configured. In the left-hand side menu choose *Web Application Firewall. \n \n \n Click on ApplicationGatewayWAFPolicy In the left-hand side menu choose *Managed rules. \n \n \n   \n \n We have successfully completed the deployment and configuration of the network and cluster resources. The following diagram shows the high-level architecture of the solution. As you can see, there is a test pod running in AKS that can receive traffic from the internet through the Azure Application Gateway and the Azure Internal Load Balancer. We can also access the private API server of the AKS cluster and the private container registry from the jumpbox using the private endpoints and links. We have also enabled outbound traffic from the AKS subnet to go through the Azure Firewall for inspection and filtering. In the next section, we will validate if we can access our test pod securely from the Internet. \n   \n \n   \n Validate Ingress Connection. \n   \n Open your web browser and access the domain created above: https://<application gateway FQDN> \n \n Note: The certificate used was self-signed, so the browser will issue a warning that the content is potentially unsafe. In a production setting, a certificate from a well known certificate authority should be used, but this is beyond the scope of this tutorial. \n \n   \n If you discard the warning, you should see a similar output as to the one below. \n   \n \n You have now verified connectivity from the public IP address, through the Application Gateway to the nginx pod running in your private AKS cluster. Well done! \n   \n Clean Up Resources in Azure \n   \n Once you have verified that everything works as depicted earlier you can issue the following commands to delete all of the Azure resources that you have created while working with these instructions.  The easiest way is to delete the resource groups which you have created your resources in. \n   \n az group delete -n $HUB_RG\naz group delete -n $SPOKE_RG \n   ","body@stripHtml({\"removeProcessingText\":true,\"removeSpoilerMarkup\":true,\"removeTocMarkup\":true,\"truncateLength\":-1})@stringLength":"62330","kudosSumWeight":7,"repliesCount":6,"readOnly":false,"images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://techcommunity.microsoft.com/t5/s/gxcuf89792/images/bS00MTMwNDk2LTU3NzIxOGk0OTMwRTg3MjJEMjNERjdE?revision=11\"}"}}],"totalCount":1,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"videos":{"__typename":"VideoConnection","edges":[],"totalCount":0,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"coverImage":null,"coverImageProperties":{"__typename":"CoverImageProperties","style":"STANDARD","titlePosition":"BOTTOM","altText":""}},"CachedAsset:text:en_US-components/community/Navbar-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1745505307000","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","gxcuf89792":"Tech Community","external-1":"Events","s-m-b":"Nonprofit Community","windows-server":"Windows Server","education-sector":"Education Sector","driving-adoption":"Driving Adoption","Common-content_management-link":"Content Management","microsoft-learn":"Microsoft Learn","s-q-l-server":"Content Management","partner-community":"Microsoft Partner Community","microsoft365":"Microsoft 365","external-9":".NET","external-8":"Teams","external-7":"Github","products-services":"Products","external-6":"Power Platform","communities-1":"Topics","external-5":"Microsoft Security","planner":"Outlook","external-4":"Microsoft 365","external-3":"Dynamics 365","azure":"Azure","healthcare-and-life-sciences":"Healthcare and Life Sciences","external-2":"Azure","microsoft-mechanics":"Microsoft Mechanics","microsoft-learn-1":"Community","external-10":"Learning Room Directory","microsoft-learn-blog":"Blog","windows":"Windows","i-t-ops-talk":"ITOps Talk","external-link-1":"View All","microsoft-securityand-compliance":"Microsoft Security","public-sector":"Public Sector","community-info-center":"Lounge","external-link-2":"View All","microsoft-teams":"Microsoft Teams","external":"Blogs","microsoft-endpoint-manager":"Microsoft Intune","startupsat-microsoft":"Startups at Microsoft","exchange":"Exchange","a-i":"AI and Machine Learning","io-t":"Internet of Things (IoT)","Common-microsoft365-copilot-link":"Microsoft 365 Copilot","outlook":"Microsoft 365 Copilot","external-link":"Community Hubs","communities":"Products"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1745505307000","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1745505307000","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1745505307000","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1745505307000","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1745505307000","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagSubscriptionAction-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagSubscriptionAction-1745505307000","value":{"success.follow.title":"Following Tag","success.unfollow.title":"Unfollowed Tag","success.follow.message.followAcrossCommunity":"You will be notified when this tag is used anywhere across the community","success.unfollowtag.message":"You will no longer be notified when this tag is used anywhere in this place","success.unfollowtagAcrossCommunity.message":"You will no longer be notified when this tag is used anywhere across the community","unexpected.error.title":"Error - Action Failed","unexpected.error.message":"An unidentified problem occurred during the action you took. Please try again later.","buttonTitle":"{isSubscribed, select, true {Unfollow} false {Follow} other{}}","unfollow":"Unfollow"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1745505307000","value":{"title":"Query Handler"},"localOverride":false},"Category:category:top":{"__typename":"Category","id":"category:top","nodeType":"category"},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1745505307000","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageListTabs-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageListTabs-1745505307000","value":{"mostKudoed":"{value, select, IDEA {Most Votes} other {Most Likes}}","mostReplies":"Most Replies","mostViewed":"Most Viewed","newest":"{value, select, IDEA {Newest Ideas} OCCASION {Newest Events} other {Newest Topics}}","newestOccasions":"Newest Events","mostRecent":"Most Recent","noReplies":"No Replies Yet","noSolutions":"No Solutions Yet","solutions":"Solutions","mostRecentUserContent":"Most Recent","trending":"Trending","draft":"Drafts","spam":"Spam","abuse":"Abuse","moderation":"Moderation","tags":"Tags","PAST":"Past","UPCOMING":"Upcoming","sortBymostRecent":"Sort By Most Recent","sortBymostRecentUserContent":"Sort By Most Recent","sortBymostKudoed":"Sort By Most Likes","sortBymostReplies":"Sort By Most Replies","sortBymostViewed":"Sort By Most Viewed","sortBynewest":"Sort By Newest Topics","sortBynewestOccasions":"Sort By Newest Events","otherTabs":" Messages list in the {tab} for {conversationStyle}","guides":"Guides","archives":"Archives"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewInline-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewInline-1745505307000","value":{"bylineAuthor":"{bylineAuthor}","bylineBoard":"{bylineBoard}","anonymous":"Anonymous","place":"Place {bylineBoard}","gotoParent":"Go to parent {name}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Pager/PagerLoadMore-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Pager/PagerLoadMore-1745505307000","value":{"loadMore":"Show More"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/OverflowNav-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/OverflowNav-1745505307000","value":{"toggleText":"More"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1745505307000","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1745505307000","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1745505307000","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/nodes/NodeIcon-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/nodes/NodeIcon-1745505307000","value":{"contentType":"Content Type {style, select, FORUM {Forum} BLOG {Blog} TKB {Knowledge Base} IDEA {Ideas} OCCASION {Events} other {}} icon"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageUnreadCount-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageUnreadCount-1745505307000","value":{"unread":"{count} unread","comments":"{count, plural, one { unread comment} other{ unread comments}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageViewCount-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageViewCount-1745505307000","value":{"textTitle":"{count, plural,one {View} other{Views}}","views":"{count, plural, one{View} other{Views}}"},"localOverride":false},"CachedAsset:text:en_US-components/kudos/KudosCount-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/kudos/KudosCount-1745505307000","value":{"textTitle":"{count, plural,one {{messageType, select, IDEA{Vote} other{Like}}} other{{messageType, select, IDEA{Votes} other{Likes}}}}","likes":"{count, plural, one{like} other{likes}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRepliesCount-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRepliesCount-1745505307000","value":{"textTitle":"{count, plural,one {{conversationStyle, select, IDEA{Comment} OCCASION{Comment} other{Reply}}} other{{conversationStyle, select, IDEA{Comments} OCCASION{Comments} other{Replies}}}}","comments":"{count, plural, one{Comment} other{Comments}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1745505307000","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1745505307000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1745505307000","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false}}}},"page":"/tags/TagPage/TagPage","query":{"messages.widget.messagelistfornodebyrecentactivitywidget-tab-main-messages-list-for-tag-widget-0":"mostKudoed","tagName":"azure kubernetes service"},"buildId":"-gVUpXaWnPcjlrLJZ92B7","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"o365","openTelemetryServiceVersion":"25.3.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/customComponent/CustomComponent/CustomComponent.tsx","./components/tags/TagsHeaderWidget/TagsHeaderWidget.tsx","./components/messages/MessageListForNodeByRecentActivityWidget/MessageListForNodeByRecentActivityWidget.tsx","./components/tags/TagSubscriptionAction/TagSubscriptionAction.tsx","./components/external/components/ExternalComponent.tsx","../shared/client/components/common/List/ListGroup/ListGroup.tsx","./components/messages/MessageView/MessageView.tsx","./components/messages/MessageView/MessageViewInline/MessageViewInline.tsx","../shared/client/components/common/Pager/PagerLoadMore/PagerLoadMore.tsx","./components/customComponent/CustomComponentContent/TemplateContent.tsx"],"appGip":true,"scriptLoader":[{"id":"analytics","src":"https://techcommunity.microsoft.com/t5/s/gxcuf89792/pagescripts/1730819800000/analytics.js?page.id=TagPage","strategy":"afterInteractive"}]}