Skip to content

Commit

Permalink
Better integration of ACR and AKS (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
hongooi73 committed Jul 12, 2019
1 parent 444a59a commit 06cb21e
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 16 deletions.
16 changes: 16 additions & 0 deletions R/az_container_registry.R
Expand Up @@ -6,6 +6,7 @@
#' @section Methods:
#' The following methods are available, in addition to those provided by the [AzureRMR::az_resource] class:
#' - `new(...)`: Initialize a new ACR object. See 'Details'.
#' - `add_role_assignment(principal, role, scope=NULL, ...)`: Adds a role for the specified principal. This is an override mainly to handle AKS objects, so that the Kubernetes cluster can be granted access to the registry. You can use the `...` arguments to supply authentication details for AzureGraph, which is used to retrieve the cluster service principal.
#' - `list_credentials`: Return the username and passwords for this registry. Only valid if the Admin user for the registry has been enabled.
#' - `list_policies`: Return the policies for this registry.
#' - `list_usages`: Return the usage for this registry.
Expand Down Expand Up @@ -46,6 +47,10 @@
#' # see who has push and pull access
#' myacr$list_role_assignments()
#'
#' # grant a Kubernetes cluster pull access
#' myaks <- rg$get_aks("myaks")
#' myacr$add_role_assignment(myaks, "Acrpull")
#'
#' # get the registry endpoint (for interactive use)
#' myacr$get_docker_registry()
#'
Expand All @@ -59,6 +64,17 @@ acr <- R6::R6Class("az_container_registry", inherit=AzureRMR::az_resource,

public=list(

add_role_assignment=function(principal, role, scope=NULL, ...)
{
if(is_aks(principal))
{
tenant <- self$token$tenant
gr <- graph_login(tenant, ...)
principal <- gr$get_app(principal$properties$servicePrincipalProfile$clientId)
}
super$add_role_assignment(principal, role, scope)
},

list_credentials=function()
{
creds <- private$res_op("listCredentials", http_verb="POST")
Expand Down
6 changes: 1 addition & 5 deletions README.md
Expand Up @@ -40,11 +40,7 @@ aks <- resgroup$create_aks("myakscluster",
agent_pools=aks_pools("pool1", 2, "Standard_DS2_v2", "Linux"))

# give the cluster pull access to the registry
aks_app <- aks$properties$servicePrincipalProfile$clientId
acr$add_role_assignment(
principal=AzureGraph::get_graph_login()$get_app(aks_app),
role="Acrpull"
)
acr$add_role_assignment(aks, "Acrpull")

# get cluster endpoint, deploy from ACR to AKS with predefined yaml definition file
clus <- aks$get_cluster()
Expand Down
5 changes: 5 additions & 0 deletions man/acr.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 1 addition & 6 deletions tests/testthat/test03_aks.R
Expand Up @@ -55,12 +55,7 @@ test_that("AKS works with RBAC",
aks <- rg$create_aks(aksname, agent_pools=aks_pools("pool1", 2))
expect_true(is_aks(aks))

aks_app <- aks$properties$servicePrincipalProfile$clientId

acr$add_role_assignment(
principal=AzureGraph::get_graph_login(tenant)$get_app(aks_app),
role="Acrpull"
)
acr$add_role_assignment(aks, "Acrpull")

clus <- aks$get_cluster()
expect_true(is_kubernetes_cluster(clus))
Expand Down
29 changes: 24 additions & 5 deletions vignettes/vig03_rbac.Rmd
Expand Up @@ -45,21 +45,40 @@ rg$create_aci("myinstance", image="myacr.azurecr.io/myimage",

## Authenticating with a service principal from AKS to ACR

This is the corresponding scenario for a Kubernetes cluster. We'll reuse the registry from the above example.
The corresponding scenario for a Kubernetes cluster is much simpler: we simply call the `add_role_assignment` method for the ACR object, passing it the AKS object. We'll reuse the registry from the above example.

```r
# create the AKS resource
aks <- rg$create_aks("myaks", agent_pools=aks_pools("pool1", 2), enable_rbac=TRUE)

# get the app ID for the cluster service principal
aks_app_id <- aks$properties$servicePrincipalProfile$clientID

# give the app pull access to the registry
reg$add_role_assignment(gr$get_app(aks_app_id), "Acrpull")
reg$add_role_assignment(aks, "Acrpull")
```

After giving the cluster service principal the necessary permissions, you can then deploy images from the registry as normal.

## Creating an AKS resource and reusing an existing service principal

This scenario is most relevant when creating an AKS resource in an automated environment, ie without a logged-in user's credentials. Currently, creating an AKS resource also involves creating an associated service principal, for the cluster to manage its sub-resources. In turn, creating this service principal will attempt to get the credentials for the logged-in user, which fails if there is no user present.

To avoid this, you can create an app ahead of time and pass it to `create_aks`:

```r
# login to ARM and MS Graph with client credentials flow
# your app must have the right permissions to work with ARM and Graph
az <- AzureRMR::create_azure_login("mytenant", app="app_id", password="clientsecret")
gr <- AzureGraph::create_graph_login("mytenant", app="app_id", password="clientsecret")

app <- gr$create_app("myaksapp")

az$
get_subscription("sub_id")$
get_resource_group("rgname")$
create_aks("myaks",
cluster_service_principal=app,
agent_pools=aks_pools("pool1", 2, "Standard_DS2_v2", "Linux"))
```

## Integrating AKS with Azure Active Directory

Integrating AKS and AAD requires creating two registered apps, the client and server, and giving them permissions to talk to each other. Most of the work here is actually done using the AzureGraph package; once the apps are correctly configured, we then pass them to the `create_aks` method. You'll need to be an administrator for your AAD tenant to carry out these steps.
Expand Down

0 comments on commit 06cb21e

Please sign in to comment.