Reuse custom authorizer for AWS ApiGW using CDK - aws-api-gateway

I would like to reuse a custom authorizer that was created using CDK in one repository for a new AWS ApiGW method that was created in another repo. Currently, there is no CDK built-in method for importing an existing authorizer.

I have found a way to overcome the problem:
# Import rest api from the environment using ids
rest_api = RestApi.from_rest_api_attributes(self, "fromrestapiid",
rest_api_id=rest_api_id,
root_resource_id=resource_id)
# Retrieve or create an API method
method_resource = rest_api.root.resource_for_path(endpoint_path)
# Change the property of the resource using the existing authorizer id
method_resource = method.node.find_child('Resource')
method_resource.add_property_override('AuthorizationType', 'CUSTOM')
method_resource.add_property_override('AuthorizerId', authorizer_id)

Related

How to modify the service endpoint of an Azure Pipeline via API?

I want to modify the service endpoint of a pipeline in Azure DevOps via API.
Example:
Pipeline "build-a-release" uses my personal service endpoint "hello1". But I want it to use existing service endpoint "my-companys-global-service-endpoint" instead.
The documentation https://learn.microsoft.com/en-us/rest/api/azure/devops/pipelines/pipelines?view=azure-devops-rest-6.0 does not show any "update" function, but I can update the service endpoint of a pipeline in the Azure DevOps GUI.
How can I automate this process via a script and API?
To update a service endpoint, you should use Endpoints - Update Service Endpoint API:
PUT https://dev.azure.com/{organization}/_apis/serviceendpoint/endpoints/{endpointId}?api-version=6.0-preview.4
To update a pipeline defintion, you could use Definitions - Update api to update it. When you capture the network log, you could see there is connectedServiceId in properties of repository parameter. You could update the connectedServiceId to change the service connection.
From my test, something you need to notice:
Make sure the request headers include the following items:
Make sure you have the correct "revision" value (the latest revision) in the body.

Using CodePipeline - deploy a CloudFormation stack to another account

I am configuring a CodePipeline in Account 00000000000.
I would like to deploy a CloudFormation stack
by executing a CloudFromation template via the CodePipeline
but not in account 123456789123 and not in 00000000000
Question
How do I configure the CodePipeline action of type "Deploy" to do so?
Especially how do I point it to the account 123456789123 ?
What I did so far
I assume it works via roles.123456789123.
I created an IAM role in account 123456789123,
with trust to the account 00000000000,
with trust to the service cloudformation.
I named it arn:aws:iam::123456789123:role/CFDep
Below is the configuration of my CodePipeline-Action.
I am getting an error The role name is invalid. Check that the specified role exists and can be assumed by AWS CloudFormation. Why?
From the docs:
You cannot use the AWS CodePipeline console to create or edit a
pipeline that uses resources associated with another AWS account.
However, you can use the console to create the general structure of
the pipeline, and then use the AWS CLI to edit the pipeline and add
those resources. Alternatively, you can use the structure of an
existing pipeline and manually add the resources to it.
You can do one of the following 2 things:
Use aws codepipeline cli to edit the pipeline
aws codepipeline update-pipeline --cli-input-json file://pipeline.json
OR
Create the pipeline itself using cloudformation
You can use this pipeline definition from aws reference architecture for cross account pipeline as a starting point for your template.

How to use Azure Managed Identity in Azure Function to access Service Bus with a trigger?

I have created a ServiceBus namespace in Azure, along with a topic and a subscription. I also have a simple Azure version 1 function that triggers on a received topic in the ServiceBus, like this:
[FunctionName("MyServiceBusTriggerFunction")]
public static void Run([ServiceBusTrigger("myTopic", "mySubscription", Connection = "MyConnection")]string mySbMsg, TraceWriter log)
{
log.Info($"C# ServiceBus topic trigger function processed message: {mySbMsg}");
}
The function triggers nicely for the topics in the ServiceBus when I define the connection string in functions Application Settings by using Shared Access Policy for topic, like this:
Endpoint=sb://MyNamespace.servicebus.windows.net/;SharedAccessKeyName=mypolicy;SharedAccessKey=UZ...E0=
Now, instead of Shared Access Keys, I would like to use Managed Service Identity (MSI) for accessing the ServiceBus. According to this (https://learn.microsoft.com/en-us/azure/active-directory/managed-service-identity/services-support-msi) it should be possible, unless I have misunderstood something. I haven't managed to get it working though.
What I tried, was to
set the Managed Service Identity "On" for my function in Azure portal
give Owner role for the function in ServiceBus Access Control section in Azure Portal
set the connection string for MyFunction like this: Endpoint=sb://MyNamespace.servicebus.windows.net/
The function is not triggering in this set-up, so what am I missing or what am I doing wrong?
I'd be grateful for any advice to help me get further. Thanks.
Update for Microsoft.Azure.WebJobs.Extensions.ServiceBus version 5.x
There is now an offical docs for the latest version of the package in here.
{
"Values": {
"<connection_name>__fullyQualifiedNamespace": "<service_bus_namespace>.servicebus.windows.net"
}
}
Previous answer:
This actually seems to be possible now, at least worked just fine for me. You need to use this connection string:
Endpoint=sb://service-bus-namespace-name.servicebus.windows.net/;Authentication=ManagedIdentity
I have not actually found any documentation about this on Microsoft site, but in a blog here.
Microsoft does have documentation though on roles that you can use and how to limit them to scope in here. Example:
az role assignment create \
--role $service_bus_role \
--assignee $assignee_id \
--scope /subscriptions/$subscription_id/resourceGroups/$resource_group/providers/Microsoft.ServiceBus/namespaces/$service_bus_namespace/topics/$service_bus_topic/subscriptions/$service_bus_subscription
what am I missing or what am I doing wrong?
You may mix up with MSI and Shared Access Policy.They are using different provider to access to Azure servicebus. You could just use connectionstring or just use MSI to authenticate.
When you use Managed Service Identity(MSI) to authenticate, you need to create a token provider for the managed service identity with the following code.
TokenProvider.CreateManagedServiceIdentityTokenProvider(ServiceAudience.ServiceBusAudience).
This TokenProvider's implementation uses the AzureServiceTokenProvider found in the Microsoft.Azure.Services.AppAuthentication library. AzureServiceTokenProvider will follow a set number of different methods, depending on the environment, to get an access token. And then initialize client to operate the servicebus.
For more details, you could refer to this article.
When you use servicebus connectionstring to access which using the Shared Access Token (SAS) token provider, so you can operate directly.
Agreed that from azure function we cannot access the resource like ASB directly. However, one still does not need to put in the password in this case "SharedAccessKeyName" in the connectionstring directly.
Azure function can work with Azure KeyVault. Thus one can store the connectionstring with sensitive information as a secret in the KeyVault and then grant System assigned identity from azure functions access over KeyVault and then specify the value for the settings in the portal as
#Microsoft.KeyVault(SecretUri={theSecretUri})
Details on how to achieve the above is mentioned in the following blog.
https://medium.com/statuscode/getting-key-vault-secrets-in-azure-functions-37620fd20a0b
This will still avoid specifying the connectionstring directly in Azure functions and provides with single point of access via Vault to be disabled in case of a security breach

How to get the auto generated RestApi from my AWS SAM template? To use in another SAM template

I used AWS SAM to generate my Lambda/APIs. But I want to be able to get this RestApi so I can use it in another SAM template.
The idea is to have 1 base infra CloudFormation/SAM template that creates the network, ALB, API Gateway things
Then each "micro-service" will have its own SAM template and it will create API endpoints referencing this "root" RestApi by specifying the RestApiId attribute
Is this a correct approach? Wonder if when I deploy each service, will it remove the APIs for the other services?
You can access default auto generated RestApi as ServerlessRestApi. This is logical resource id for auto generated RestApi resource.
ServerlessRestApi access example in template.yaml is as follows.
Outputs:
ApiRootURL:
Description: API Root URL
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/${ServerlessRestApi.Stage}"
You can see ServerlessRestApi in the resource list of you CloudFormation stack. ServerlessRestApi is not documented, so it might be changed in the future version.

Access VSTS Service Endpoint credentials from extension

I'm developing a VSTS extension.
I have configured a VSTS Service Endpoint through the portal.
I need to use the credentials of the configured endpoint in my extension code.
Does anybody know how to do this?
-Thanks in advance.
You need to add the service endpoint you want to use into the task.json of your build extension and then you can use it in the build task. Refer to this link for details: Service Endpoints in Team Services.
And you can also look at the VSTS Agent Task in GitHub for how to use the service endpoint in a build task like this one.
Thanks Eddie,
I found a solution for this with your help,
I was using 0.5.8 version of the vsts-task-lib library and update it to 0.9.7 and did the following,
//Import the task lib 0.9.7
import tl = require('vsts-task-lib/task');
//Get the endpoint ID (a guid)
serverEndpoint = tl.getInput('serverEndpoint', true);
//Get the enpoint URL for the retrieved end point id and parse it to URL type
serverEndpointUrl: url.Url = url.parse(tl.getEndpointUrl(this.serverEndpoint, false));
//Extract authentication details from url
serverEndpointAuth = tl.getEndpointAuthorization(this.serverEndpoint, false);
//Read parameters to variable
//NOTE: You cant write this data to console, if you do write, it will write //asterisk (****) instead of real values.
username = this.serverEndpointAuth['parameters']['username'];
password = this.serverEndpointAuth['parameters']['password'];
//Pass the variables as parameters.