Can anybody please help shine some light on how I can go about logging/storing API calls to Azure Subscriptions via Terraform?
I've found the "azurerm_monitor_diagnostic_setting", but this doesn't seem to cover Subscriptions. And I'm just banging my head against a wall here...
Ultimately I want to achieve some alerting on certain api calls (nsg deletes, edits & other 'important events') which I believe I can acheive with "azure_monitor_activity_log_alert" via an SA. But I'm just struggling to find how to get at these logs via Terraform in the first instance?
Any help would be much appreciated.
Thanks
But I'm just struggling to find how to get at these logs via Terraform
in the first instance?
AFAIK, there is no supported terraform block to directly get these logs from a storage account.
As a workaround, you could access Activity log events using the following methods:
Use the Get-AzLog cmdlet to retrieve the Activity Log from PowerShell. See Azure Monitor PowerShell samples.
Use az monitor activity-log to retrieve the Activity Log from CLI. See Azure Monitor CLI samples.
Use the Azure Monitor REST API to retrieve the Activity Log from a REST client
in this case, you can mix the CLI or PowerShell scripts in your terraform code with local-exec Provisioner or remote-exec provisioner. This would be possible to get the logs. For storage stored diagnostic logs, you may need to get the blob content via Get-AzureStorageBlob.
I've been searching on this for a while now and I've found a solution or better yet explanation to this problem or confusion.
The portal is a bit unclear on this , but the activity log you see on your resources is actually the full activity log for your subscription, with filters (!!).
This means that when you open your Activity Log on the resource page in the portal it will show you all Activity for that resource but that doesn't mean you can send an Activity Log of that resource alone to your Log Analytics Workspace , or wherever you want to send that data.
You can actually see this by creating a Activity Log Diagnostic Setting on your resource in the Azure Portal and then go to the subscription page, where you will find the same Diagnostic Setting on that level.
So instead of configuring a Diagnostic Setting that send Activity Logs to Log Analytics Workspace for each Resource in your Subscription, you should only configure one on the Subscription level , that will contain all Activity on all the underlying Resource Groups & Resources.
In Terraform this can look like this :
resource "azurerm_monitor_diagnostic_setting" "activity-logs" {
name = "subscription-activitylogs"
target_resource_id = data.azurerm_subscription.current.id
log_analytics_workspace_id = data.azurerm_log_analytics_workspace.monitoring.id
log_analytics_destination_type = "Dedicated"
enabled_log {
category = "Security"
retention_policy {
enabled = true
days = 180
}
}
enabled_log {
category = "Administrative"
retention_policy {
enabled = true
days = 180
}
}
enabled_log {
category = "ServiceHealth"
retention_policy {
enabled = true
days = 180
}
}
enabled_log {
category = "Alert"
retention_policy {
enabled = true
days = 180
}
}
enabled_log {
category = "Recommendation"
retention_policy {
enabled = true
days = 180
}
}
enabled_log {
category = "Policy"
retention_policy {
enabled = true
days = 180
}
}
enabled_log {
category = "Autoscale"
retention_policy {
enabled = true
days = 180
}
}
enabled_log {
category = "ResourceHealth"
retention_policy {
enabled = true
days = 180
}
}
}
Related
Intro:
was created a Google Smart Home project
was configured a proxy server via ngrok to redirect the Google request to my local machine
I develop an IoT project that has the ability to open/close a lock. I need to implement Google integration to use the Google Assistant to control the user locks. I have implemented OAuth Server for Google. Also I have implemented some controllers to handle Google Action Intents: SYNC, QUERY and EXECUTE. Google send a request with the SYNC intent and App response a payload that contain devices list with specific settings. Instance:
{
requestId: 'requestIdOfGoogle', // contains in the request body
payload: {
agentUserId: 'userId123', // matches user id inside app system
devices: [
{
id: 1,
type: 'action.devices.types.LOCK', // device type
traits: ['action.devices.traits.LockUnlock'], // feature that has a device
name: {
name: 'Kos Lock'
},
willReportState: true,
roomHint: 'Main Door',
deviceInfo: { // Test data
manufacturer: 'smart-home-inc',
model: 'hs1234',
hwVersion: '3.2',
swVersion: '11.4'
}
}
]
}
}
Then Google send requests to my server with QUERY intent to get info about state of a devices, instance
{
requestId: 'requestIdOfGoogle', // contains in the request body
payload: {
devices: {
1: {
status: 'SUCCESS',
online: true,
isLocked: true,
// isJammed - Boolean. Whether the device is currently jammed and therefore its
// locked state cannot be determined.
isJammed: false
}
}
}
}
But after sending a response a test lock isn't configured and a user can't control one with Google Assistant.
enter image description here
I have tried to add other traits for a lock but it didn't help me. Also I have the same problem when I try to configure a Door device. But when I send to Google a Light device it works successfully. When you use the LockUnlock trait then Google Doc recommends to setup secondary user verification but it's optional.
I don't understand that do incorrect. If someone faced such a problem and solved it then could you help me, please
Prerequisites:
use node ^14.0.0
programming language - js
Touch controls are not supported for every device, and locks are not a device type that can be controlled directly. But they will still respond to voice commands.
Just FYI I posted this question originally in the AWS AppSync forum (in case in the future AWS answers it).
I have been trying to make a simple Posts app like the one in the docs but I have found no documentation or guides that handle multiple subscriptions in one view controller.
Three mutations: onCreatePost, onUpdatePost, onDeletePost
(and of course three subscriptions to those mutations)
In Xcode, I have three functions called during viewDidLoad(): subscribeToNewPosts(), subscribeToUpdatedPosts(), subscribeToDeletedPosts()
Each subscription function works and creates a subscription with the correct functionality and updates the table view accordingly if used alone. But, if called one after the other, only the last subscription will actually receive data and update the table view. I put a breakpoint to check out topicSubscribersDictionary in AppSyncMQTTClient.swift after subscribing to all three mutations
func startNewSubscription(subscriptionInfo: AWSSubscriptionInfo) {
var topicQueue = [String]()
let mqttClient = MQTTClient<AnyObject, AnyObject>()
mqttClient.clientDelegate = self
for topic in subscriptionInfo.topics {
if topicSubscribersDictionary[topic] != nil {
// if the client wants subscriptions and is allowed we add it to list of subscribe
topicQueue.append(topic)
}
}
mqttClients.append(mqttClient)
mqttClientsWithTopics[mqttClient] = topicQueue
mqttClient.connect(withClientId: subscriptionInfo.clientId, toHost: subscriptionInfo.url, statusCallback: nil)
}
and all three subscriptions are in fact in the dictionary...
Do I need multiple instances of appSyncClient, one for each subscription? Is it a problem with the schema design?
schema.graphql
schema.json
mutations.graphql
queries.graphql
subscriptions.graphql
Example use case: simple chat app. New conversation started = OnCreatePostSubscription; new incoming message in that conversation = OnUpdatePostSubscription
Are you using API Key for authorization in AppSync? If you are using API Key only one subscription is supported by the SDK at this point. Could you switch to IAM (Cognito Identity) or Cognito UserPools based auth and see if multiple subscriptions work for you?
I managed to have several subscriptions working with API Key by replacing the call startSubscriptions to startNewSubscription inside AWSAppSyncSubscriptionWatcher
if let subscriptionInfo = subscriptionResult.subscrptionInfo {
self.subscriptionTopic = subscriptionResult.newTopics
self.client?.addWatcher(watcher: self, topics: subscriptionResult.newTopics!, identifier: self.uniqueIdentifier)
//self.client?.startSubscriptions(subscriptionInfo: subscriptionInfo)
subscriptionInfo.forEach { self.client?.startNewSubscription(subscriptionInfo: $0) }
}
Couldn't find any side effect with this approach yet, apart from requiring to fork the iOS SKD
I'm trying to get notification work on my ios app using SNS. I follow the instruction on AWS mobile hub integration page. I checked the SNS page and I can see my app subscribes to the topic. But when I publish notification from the console by selecting the topic, my app does not get any notification. I've been trying for hours now and I appreciate any clue and theory on this matter.
This is the output log from my app after subscribing to the topic :
<SubscribeResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
<SubscribeResult>
<SubscriptionArn>arn:aws:sns:****:NotifySharing:****</SubscriptionArn>
</SubscribeResult>
<ResponseMetadata>
<RequestId>***</RequestId>
</ResponseMetadata>
</SubscribeResponse>
I replaced some info with **** just to make sure that I'm not disclosing sensitive data. Anyway, what could be the problem?
This is my code that does subscription :
class PushNotificationHandler: NSObject {
func setupPushManager() {
let pushManager: AWSPushManager = AWSPushManager.defaultPushManager()
pushManager.delegate = self
pushManager.registerForPushNotifications()
if let topicARNs = pushManager.topicARNs {
pushManager.registerTopicARNs(topicARNs)
}
if pushManager.enabled {
for topic in pushManager.topics {
topic.subscribe()
}
}
}
}
I'm creating a VPN profile through my app and I have the following rules and set up:
let newIPSec = NEVPNProtocolIPSec()
newIPSec.serverAddress = AppConfiguration.getVPNEndPoint()
newIPSec.authenticationMethod = NEVPNIKEAuthenticationMethod.sharedSecret
newIPSec.username = VPNCredentialsModel.instance.vpnUserName()
newIPSec.passwordReference = VPNCredentialsModel.instance.vpnPasswordReference() as Data?
newIPSec.sharedSecretReference = VPNCredentialsModel.instance.vpnPresharedKeyReference() as Data?
newIPSec.useExtendedAuthentication = true
newIPSec.disconnectOnSleep = false
self.manager.protocolConfiguration = newIPSec
let connectRule = NEOnDemandRuleConnect()
connectRule.interfaceTypeMatch = .any
let ignoreRule = NEOnDemandRuleIgnore()
ignoreRule.interfaceTypeMatch = .any
ignoreRule.probeURL = URL(string:probeURL)
self.manager.onDemandRules = [ignoreRule,connectRule]
self.manager.isOnDemandEnabled = true
self.manager.isEnabled = true
Update
My probeURL is a rest API call which updates the backend and returns 200 or 500 based on the user status. There is some latency since there are some sql querying being carried out. The probeURL expects a 200 OK else invalidates the ignore rule. The ignore rule becomes invalid and it tries to connect to the VPN but the user can't connect anymore since the VPN blocked the user. The iOS device keeps trying in an infinite loops and blocks the internet access from other applications pushing the device to a brick state. Is there a better way to handle this case?
Suggestion
I can update the DB with a file endpoint that points the user status like a flag - (each user has a file endpoint). If the file is available it returns a 200 OK and if its removed returns 404. This way probe url can receive a 200 OK with no latency when needed. However this might be an extra layer of implementation and file management. Whats your view on this? Can someone recommend a better way to handle this test case?
Testing
I was testing a successful scenario with the following probe URL:
httpstat.us/200 for ignoreRule to be valid and not connect
httpstat.us/500 for ignoreRUle to be invalid and continue connecting to the VPN
We're trying to find a way to detect revoked permissions through Google APIs without continuously polling the provider to get status updates. Does Google have any sort of notification system for this (a webhook, etc)?
The most recent post I found regarding this was over 2 years ago.
Look here and search for Check For Permissions
Android Permissions
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}