You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by pr...@apache.org on 2021/12/08 03:12:55 UTC
[ranger] branch master updated: RANGER-2967: Add support for Amazon CloudWatch Logs as an Audit Store
This is an automated email from the ASF dual-hosted git repository.
pradeep pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 25def39 RANGER-2967: Add support for Amazon CloudWatch Logs as an Audit Store
25def39 is described below
commit 25def39b1c833b4e18ff657929656be3c37bcd8f
Author: Yao Zhou <zh...@gmail.com>
AuthorDate: Tue Aug 25 10:53:50 2020 +0530
RANGER-2967: Add support for Amazon CloudWatch Logs as an Audit Store
Signed-off-by: pradeep <pr...@apache.org>
---
agents-audit/pom.xml | 15 ++
.../AmazonCloudWatchAuditDestination.java | 182 +++++++++++++++++++++
.../audit/provider/AuditProviderFactory.java | 2 +
hbase-agent/conf/ranger-hbase-audit-changes.cfg | 5 +
hbase-agent/scripts/install.properties | 12 ++
hdfs-agent/conf/ranger-hdfs-audit-changes.cfg | 5 +
hdfs-agent/scripts/install.properties | 12 ++
hive-agent/conf/ranger-hive-audit-changes.cfg | 5 +
hive-agent/scripts/install.properties | 12 ++
kms/scripts/install.properties | 12 ++
knox-agent/conf/ranger-knox-audit-changes.cfg | 5 +
knox-agent/scripts/install.properties | 12 ++
plugin-atlas/conf/ranger-atlas-audit-changes.cfg | 6 +
plugin-atlas/scripts/install.properties | 12 ++
.../conf/ranger-elasticsearch-audit-changes.cfg | 5 +
plugin-elasticsearch/scripts/install.properties | 12 ++
plugin-kafka/conf/ranger-kafka-audit-changes.cfg | 5 +
plugin-kafka/scripts/install.properties | 12 ++
plugin-kms/conf/ranger-kms-audit-changes.cfg | 5 +
plugin-kylin/conf/ranger-kylin-audit-changes.cfg | 5 +
plugin-kylin/scripts/install.properties | 12 ++
plugin-ozone/conf/ranger-ozone-audit-changes.cfg | 5 +
plugin-ozone/scripts/install.properties | 12 ++
plugin-presto/conf/ranger-presto-audit-changes.cfg | 5 +
plugin-presto/scripts/install.properties | 12 ++
plugin-solr/conf/ranger-solr-audit-changes.cfg | 5 +
plugin-solr/scripts/install.properties | 12 ++
plugin-sqoop/conf/ranger-sqoop-audit-changes.cfg | 5 +
plugin-sqoop/scripts/install.properties | 12 ++
plugin-yarn/conf/ranger-yarn-audit-changes.cfg | 5 +
plugin-yarn/scripts/install.properties | 12 ++
.../AmazonCloudWatchAuditDestinationTest.java | 79 +++++++++
storm-agent/conf/ranger-storm-audit-changes.cfg | 5 +
storm-agent/scripts/install.properties | 12 ++
34 files changed, 534 insertions(+)
diff --git a/agents-audit/pom.xml b/agents-audit/pom.xml
index 5607242..33fa256 100644
--- a/agents-audit/pom.xml
+++ b/agents-audit/pom.xml
@@ -31,6 +31,17 @@
<version>3.0.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>com.amazonaws</groupId>
+ <artifactId>aws-java-sdk-bom</artifactId>
+ <version>1.11.327</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.ranger</groupId>
@@ -334,5 +345,9 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>com.amazonaws</groupId>
+ <artifactId>aws-java-sdk-logs</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git a/agents-audit/src/main/java/org/apache/ranger/audit/destination/AmazonCloudWatchAuditDestination.java b/agents-audit/src/main/java/org/apache/ranger/audit/destination/AmazonCloudWatchAuditDestination.java
new file mode 100644
index 0000000..b236a26
--- /dev/null
+++ b/agents-audit/src/main/java/org/apache/ranger/audit/destination/AmazonCloudWatchAuditDestination.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.audit.destination;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+import com.amazonaws.services.logs.AWSLogs;
+import com.amazonaws.services.logs.AWSLogsClientBuilder;
+import com.amazonaws.services.logs.model.CreateLogStreamRequest;
+import com.amazonaws.services.logs.model.InputLogEvent;
+import com.amazonaws.services.logs.model.InvalidSequenceTokenException;
+import com.amazonaws.services.logs.model.PutLogEventsRequest;
+import com.amazonaws.services.logs.model.PutLogEventsResult;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.audit.model.AuditEventBase;
+import org.apache.ranger.audit.provider.MiscUtil;
+
+import javax.annotation.concurrent.ThreadSafe;
+
+/**
+ * Writes audit events to Amazon CloudWatch Logs.
+ * <p>
+ * Two properties are required: LogGroupName and LogStreamPrefix
+ * <p>
+ * Thread-safety is ensured by making the log method synchronized.
+ * This is to avoid possible race condition on {@link #sequenceToken} which is required in PutLogEvents API.
+ * @see <a href="https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html">PutLogEvents API Reference</a>
+ * <p>
+ * Note: Amazon CloudWatch has limits on the payload size and request rate.
+ * Based on the traffic, adjust the batch size and flush interval accordingly.
+ * <p>
+ *
+ * @see <a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html">Amazon CloudWatch Logs Service Limits</a>
+ */
+@ThreadSafe
+public class AmazonCloudWatchAuditDestination extends AuditDestination {
+
+ private static Log LOG = LogFactory.getLog(AmazonCloudWatchAuditDestination.class);
+
+ public static final String PROP_LOG_GROUP_NAME = "log_group";
+ public static final String PROP_LOG_STREAM_PREFIX = "log_stream_prefix";
+ public static final String CONFIG_PREFIX = "ranger.audit.amazon_cloudwatch";
+
+ private String logGroupName;
+ private String logStreamName;
+ private AWSLogs logsClient;
+ private String sequenceToken;
+
+ @Override
+ public void init(Properties props, String propPrefix) {
+ LOG.info("init() called for CloudWatchAuditDestination");
+ super.init(props, propPrefix);
+
+ this.logGroupName = MiscUtil.getStringProperty(props, propPrefix + "."
+ + PROP_LOG_GROUP_NAME);
+ this.logStreamName = MiscUtil.getStringProperty(props, propPrefix + "."
+ + PROP_LOG_STREAM_PREFIX) + MiscUtil.generateUniqueId();
+
+ logsClient = getClient(); // Initialize client
+ createLogStream();
+ }
+
+ @Override
+ public void stop() {
+ super.stop();
+ logStatus();
+ }
+
+ @Override
+ synchronized public boolean log(Collection<AuditEventBase> collection) {
+ boolean ret = false;
+ AWSLogs client = getClient();
+
+ PutLogEventsRequest req = new PutLogEventsRequest()
+ .withLogEvents(toInputLogEvent(collection))
+ .withLogGroupName(logGroupName)
+ .withLogStreamName(logStreamName)
+ .withSequenceToken(sequenceToken);
+
+ try {
+ sequenceToken = pushLogEvents(req, false, client);
+ addSuccessCount(collection.size());
+ ret = true;
+ } catch (Throwable e) {
+ addFailedCount(collection.size());
+ LOG.error("Failed to send audit events", e);
+ }
+
+ return ret;
+ }
+
+ private String pushLogEvents(PutLogEventsRequest req,
+ boolean retryingOnInvalidSeqToken,
+ AWSLogs client) {
+ String sequenceToken;
+ try {
+ PutLogEventsResult re = client.putLogEvents(req);
+ sequenceToken = re.getNextSequenceToken();
+ } catch (InvalidSequenceTokenException ex) {
+ if (retryingOnInvalidSeqToken) {
+ LOG.error("Unexpected invalid sequence token. Possible race condition occurred");
+ throw ex;
+ }
+
+ // LogStream may exist before first push attempt, re-obtain the sequence token
+ LOG.info("Invalid sequence token. Plugin possibly restarted. " +
+ "Updating the sequence token and retrying");
+ sequenceToken = ex.getExpectedSequenceToken();
+ req.setSequenceToken(sequenceToken);
+ return pushLogEvents(req, true, client);
+ }
+
+ return sequenceToken;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.ranger.audit.provider.AuditProvider#flush()
+ */
+ @Override
+ public void flush() {
+
+ }
+
+ static Collection<InputLogEvent> toInputLogEvent(Collection<AuditEventBase> collection) {
+ return collection.stream()
+ .map(e -> new InputLogEvent()
+ .withMessage(MiscUtil.stringify(e))
+ .withTimestamp(e.getEventTime().getTime()))
+ .sorted(Comparator.comparingLong(InputLogEvent::getTimestamp))
+ .collect(Collectors.toList());
+ }
+
+ private void createLogStream() {
+ AWSLogs client = getClient();
+ CreateLogStreamRequest req = new CreateLogStreamRequest()
+ .withLogGroupName(logGroupName)
+ .withLogStreamName(logStreamName);
+
+ LOG.info(String.format("Creating Log Stream `%s` in Log Group `%s`",
+ logStreamName, logGroupName));
+ client.createLogStream(req);
+ }
+
+ private AWSLogs getClient() {
+ if (logsClient == null) {
+ synchronized (AmazonCloudWatchAuditDestination.class) {
+ if (logsClient == null) {
+ logsClient = newClient();
+ }
+ }
+ }
+
+ return logsClient;
+ }
+
+ private AWSLogs newClient() {
+ return AWSLogsClientBuilder.standard().build();
+ }
+}
diff --git a/agents-audit/src/main/java/org/apache/ranger/audit/provider/AuditProviderFactory.java b/agents-audit/src/main/java/org/apache/ranger/audit/provider/AuditProviderFactory.java
index 7a3c7f6..7846879 100644
--- a/agents-audit/src/main/java/org/apache/ranger/audit/provider/AuditProviderFactory.java
+++ b/agents-audit/src/main/java/org/apache/ranger/audit/provider/AuditProviderFactory.java
@@ -421,6 +421,8 @@ public class AuditProviderFactory {
provider = new SolrAuditDestination();
} else if (providerName.equalsIgnoreCase("elasticsearch")) {
provider = new ElasticSearchAuditDestination();
+ } else if (providerName.equalsIgnoreCase("amazon_cloudwatch")) {
+ provider = new AmazonCloudWatchAuditDestination();
} else if (providerName.equalsIgnoreCase("kafka")) {
provider = new KafkaAuditProvider();
} else if (providerName.equalsIgnoreCase("log4j")) {
diff --git a/hbase-agent/conf/ranger-hbase-audit-changes.cfg b/hbase-agent/conf/ranger-hbase-audit-changes.cfg
index 26bd2fa..a6c7ffd 100644
--- a/hbase-agent/conf/ranger-hbase-audit-changes.cfg
+++ b/hbase-agent/conf/ranger-hbase-audit-changes.cfg
@@ -56,6 +56,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/hbase-agent/scripts/install.properties b/hbase-agent/scripts/install.properties
index 2ce8822..87a2481 100644
--- a/hbase-agent/scripts/install.properties
+++ b/hbase-agent/scripts/install.properties
@@ -99,6 +99,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
#
diff --git a/hdfs-agent/conf/ranger-hdfs-audit-changes.cfg b/hdfs-agent/conf/ranger-hdfs-audit-changes.cfg
index 9e099e6..92d2a4b 100644
--- a/hdfs-agent/conf/ranger-hdfs-audit-changes.cfg
+++ b/hdfs-agent/conf/ranger-hdfs-audit-changes.cfg
@@ -53,6 +53,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/hdfs-agent/scripts/install.properties b/hdfs-agent/scripts/install.properties
index 4c5e0fb..323b878 100644
--- a/hdfs-agent/scripts/install.properties
+++ b/hdfs-agent/scripts/install.properties
@@ -93,6 +93,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
#
diff --git a/hive-agent/conf/ranger-hive-audit-changes.cfg b/hive-agent/conf/ranger-hive-audit-changes.cfg
index c396d5d..52c715e 100644
--- a/hive-agent/conf/ranger-hive-audit-changes.cfg
+++ b/hive-agent/conf/ranger-hive-audit-changes.cfg
@@ -54,6 +54,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/hive-agent/scripts/install.properties b/hive-agent/scripts/install.properties
index b88d642..3720b66 100644
--- a/hive-agent/scripts/install.properties
+++ b/hive-agent/scripts/install.properties
@@ -96,6 +96,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
diff --git a/kms/scripts/install.properties b/kms/scripts/install.properties
index 4935536..6b6b662 100755
--- a/kms/scripts/install.properties
+++ b/kms/scripts/install.properties
@@ -216,6 +216,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
diff --git a/knox-agent/conf/ranger-knox-audit-changes.cfg b/knox-agent/conf/ranger-knox-audit-changes.cfg
index c396d5d..52c715e 100644
--- a/knox-agent/conf/ranger-knox-audit-changes.cfg
+++ b/knox-agent/conf/ranger-knox-audit-changes.cfg
@@ -54,6 +54,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/knox-agent/scripts/install.properties b/knox-agent/scripts/install.properties
index 939fd88..4704004 100644
--- a/knox-agent/scripts/install.properties
+++ b/knox-agent/scripts/install.properties
@@ -91,6 +91,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
diff --git a/plugin-atlas/conf/ranger-atlas-audit-changes.cfg b/plugin-atlas/conf/ranger-atlas-audit-changes.cfg
index 39d1d10..2d8251b 100644
--- a/plugin-atlas/conf/ranger-atlas-audit-changes.cfg
+++ b/plugin-atlas/conf/ranger-atlas-audit-changes.cfg
@@ -33,6 +33,12 @@ xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARC
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
+#Amazon CloudWatch configuration
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
#log4j configuration
xasecure.audit.log4j.is.enabled %XAAUDIT.LOG4J.ENABLE% mod create-if-not-exists
xasecure.audit.log4j.is.async %XAAUDIT.LOG4J.IS_ASYNC% mod create-if-not-exists
diff --git a/plugin-atlas/scripts/install.properties b/plugin-atlas/scripts/install.properties
index 94a8023..3b777bd 100644
--- a/plugin-atlas/scripts/install.properties
+++ b/plugin-atlas/scripts/install.properties
@@ -94,6 +94,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
#
diff --git a/plugin-elasticsearch/conf/ranger-elasticsearch-audit-changes.cfg b/plugin-elasticsearch/conf/ranger-elasticsearch-audit-changes.cfg
index c396d5d..52c715e 100644
--- a/plugin-elasticsearch/conf/ranger-elasticsearch-audit-changes.cfg
+++ b/plugin-elasticsearch/conf/ranger-elasticsearch-audit-changes.cfg
@@ -54,6 +54,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/plugin-elasticsearch/scripts/install.properties b/plugin-elasticsearch/scripts/install.properties
index 7e752c3..4111afe 100644
--- a/plugin-elasticsearch/scripts/install.properties
+++ b/plugin-elasticsearch/scripts/install.properties
@@ -93,6 +93,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
#
diff --git a/plugin-kafka/conf/ranger-kafka-audit-changes.cfg b/plugin-kafka/conf/ranger-kafka-audit-changes.cfg
index dfd27f3..bc5a089 100644
--- a/plugin-kafka/conf/ranger-kafka-audit-changes.cfg
+++ b/plugin-kafka/conf/ranger-kafka-audit-changes.cfg
@@ -47,6 +47,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/plugin-kafka/scripts/install.properties b/plugin-kafka/scripts/install.properties
index facbc79..1e325e0 100644
--- a/plugin-kafka/scripts/install.properties
+++ b/plugin-kafka/scripts/install.properties
@@ -94,6 +94,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
#
diff --git a/plugin-kms/conf/ranger-kms-audit-changes.cfg b/plugin-kms/conf/ranger-kms-audit-changes.cfg
index 8d5ca34..e5e9ae4 100644
--- a/plugin-kms/conf/ranger-kms-audit-changes.cfg
+++ b/plugin-kms/conf/ranger-kms-audit-changes.cfg
@@ -56,6 +56,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/plugin-kylin/conf/ranger-kylin-audit-changes.cfg b/plugin-kylin/conf/ranger-kylin-audit-changes.cfg
index c396d5d..52c715e 100644
--- a/plugin-kylin/conf/ranger-kylin-audit-changes.cfg
+++ b/plugin-kylin/conf/ranger-kylin-audit-changes.cfg
@@ -54,6 +54,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/plugin-kylin/scripts/install.properties b/plugin-kylin/scripts/install.properties
index b08f0ed..0134338 100644
--- a/plugin-kylin/scripts/install.properties
+++ b/plugin-kylin/scripts/install.properties
@@ -93,6 +93,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
diff --git a/plugin-ozone/conf/ranger-ozone-audit-changes.cfg b/plugin-ozone/conf/ranger-ozone-audit-changes.cfg
index 8cd5e39..0eace6d 100644
--- a/plugin-ozone/conf/ranger-ozone-audit-changes.cfg
+++ b/plugin-ozone/conf/ranger-ozone-audit-changes.cfg
@@ -47,6 +47,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/plugin-ozone/scripts/install.properties b/plugin-ozone/scripts/install.properties
index a160ec1..1891d56 100644
--- a/plugin-ozone/scripts/install.properties
+++ b/plugin-ozone/scripts/install.properties
@@ -94,6 +94,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
#
diff --git a/plugin-presto/conf/ranger-presto-audit-changes.cfg b/plugin-presto/conf/ranger-presto-audit-changes.cfg
index dfd27f3..bc5a089 100644
--- a/plugin-presto/conf/ranger-presto-audit-changes.cfg
+++ b/plugin-presto/conf/ranger-presto-audit-changes.cfg
@@ -47,6 +47,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/plugin-presto/scripts/install.properties b/plugin-presto/scripts/install.properties
index 9565335..ce162a2 100644
--- a/plugin-presto/scripts/install.properties
+++ b/plugin-presto/scripts/install.properties
@@ -93,6 +93,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
diff --git a/plugin-solr/conf/ranger-solr-audit-changes.cfg b/plugin-solr/conf/ranger-solr-audit-changes.cfg
index d4588ff..ffa0a76 100644
--- a/plugin-solr/conf/ranger-solr-audit-changes.cfg
+++ b/plugin-solr/conf/ranger-solr-audit-changes.cfg
@@ -48,6 +48,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/plugin-solr/scripts/install.properties b/plugin-solr/scripts/install.properties
index 88e8056..d1852e6 100644
--- a/plugin-solr/scripts/install.properties
+++ b/plugin-solr/scripts/install.properties
@@ -94,6 +94,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
#
diff --git a/plugin-sqoop/conf/ranger-sqoop-audit-changes.cfg b/plugin-sqoop/conf/ranger-sqoop-audit-changes.cfg
index c396d5d..52c715e 100644
--- a/plugin-sqoop/conf/ranger-sqoop-audit-changes.cfg
+++ b/plugin-sqoop/conf/ranger-sqoop-audit-changes.cfg
@@ -54,6 +54,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/plugin-sqoop/scripts/install.properties b/plugin-sqoop/scripts/install.properties
index b7b1187..81b4526 100644
--- a/plugin-sqoop/scripts/install.properties
+++ b/plugin-sqoop/scripts/install.properties
@@ -93,6 +93,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
diff --git a/plugin-yarn/conf/ranger-yarn-audit-changes.cfg b/plugin-yarn/conf/ranger-yarn-audit-changes.cfg
index c396d5d..52c715e 100644
--- a/plugin-yarn/conf/ranger-yarn-audit-changes.cfg
+++ b/plugin-yarn/conf/ranger-yarn-audit-changes.cfg
@@ -54,6 +54,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/plugin-yarn/scripts/install.properties b/plugin-yarn/scripts/install.properties
index 71bab49..e73ab8b 100644
--- a/plugin-yarn/scripts/install.properties
+++ b/plugin-yarn/scripts/install.properties
@@ -93,6 +93,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties
diff --git a/security-admin/src/test/java/org/apache/ranger/audit/destination/AmazonCloudWatchAuditDestinationTest.java b/security-admin/src/test/java/org/apache/ranger/audit/destination/AmazonCloudWatchAuditDestinationTest.java
new file mode 100644
index 0000000..dde8bb5
--- /dev/null
+++ b/security-admin/src/test/java/org/apache/ranger/audit/destination/AmazonCloudWatchAuditDestinationTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.audit.destination;
+
+import org.apache.ranger.audit.model.AuthzAuditEvent;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Properties;
+
+import static org.apache.ranger.audit.destination.AmazonCloudWatchAuditDestination.CONFIG_PREFIX;
+
+public class AmazonCloudWatchAuditDestinationTest {
+
+ @Test
+ @Ignore // For manual execution only
+ public void testWrite() {
+ AmazonCloudWatchAuditDestination amazonCloudWatchAuditDestination = new AmazonCloudWatchAuditDestination();
+ Properties properties = new Properties();
+ properties.put(CONFIG_PREFIX + "." + AmazonCloudWatchAuditDestination.PROP_LOG_GROUP_NAME, "test-log-group");
+ properties.put(CONFIG_PREFIX + "." + AmazonCloudWatchAuditDestination.PROP_LOG_STREAM_PREFIX, "test-log-stream");
+
+ amazonCloudWatchAuditDestination.init(properties, CONFIG_PREFIX);
+
+ assert amazonCloudWatchAuditDestination.log(Arrays.asList(getAuthzAuditEvent()));
+ }
+
+ private AuthzAuditEvent getAuthzAuditEvent() {
+ AuthzAuditEvent event = new AuthzAuditEvent();
+ event.setAccessResult((short) 1);
+ event.setAccessType("");
+ event.setAclEnforcer("");
+ event.setAction("");
+ event.setAdditionalInfo("");
+ event.setAgentHostname("");
+ event.setAgentId("");
+ event.setClientIP("");
+ event.setClusterName("");
+ event.setClientType("");
+ event.setEventCount(1);
+ event.setEventDurationMS(1);
+ event.setEventId("");
+ event.setEventTime(new Date());
+ event.setLogType("");
+ event.setPolicyId(1);
+ event.setPolicyVersion(1l);
+ event.setRepositoryName("");
+ event.setRequestData("");
+ event.setRepositoryType(1);
+ event.setResourcePath("");
+ event.setResultReason("");
+ event.setSeqNum(1);
+ event.setSessionId("");
+ event.setTags(new HashSet<>());
+ event.setUser("");
+ event.setZoneName("");
+ return event;
+ }
+}
diff --git a/storm-agent/conf/ranger-storm-audit-changes.cfg b/storm-agent/conf/ranger-storm-audit-changes.cfg
index c396d5d..52c715e 100644
--- a/storm-agent/conf/ranger-storm-audit-changes.cfg
+++ b/storm-agent/conf/ranger-storm-audit-changes.cfg
@@ -54,6 +54,11 @@ xasecure.audit.destination.elasticsearch.index %XAAUDIT.ELASTICSEARCH.I
xasecure.audit.destination.elasticsearch.port %XAAUDIT.ELASTICSEARCH.PORT% mod create-if-not-exists
xasecure.audit.destination.elasticsearch.protocol %XAAUDIT.ELASTICSEARCH.PROTOCOL% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch %XAAUDIT.AMAZON_CLOUDWATCH.ENABLE% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_group %XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.log_stream_prefix %XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX% mod create-if-not-exists
+xasecure.audit.destination.amazon_cloudwatch.batch.filespool.dir %XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR% mod create-if-not-exists
+
xasecure.audit.destination.hdfs %XAAUDIT.HDFS.ENABLE% mod create-if-not-exists
xasecure.audit.destination.hdfs.batch.filespool.dir %XAAUDIT.HDFS.FILE_SPOOL_DIR% mod create-if-not-exists
xasecure.audit.destination.hdfs.dir %XAAUDIT.HDFS.HDFS_DIR% mod create-if-not-exists
diff --git a/storm-agent/scripts/install.properties b/storm-agent/scripts/install.properties
index 109300f..d219abf 100644
--- a/storm-agent/scripts/install.properties
+++ b/storm-agent/scripts/install.properties
@@ -93,6 +93,18 @@ XAAUDIT.LOG4J.ASYNC.MAX.FLUSH.INTERVAL.MS=30000
XAAUDIT.LOG4J.DESTINATION.LOG4J=true
XAAUDIT.LOG4J.DESTINATION.LOG4J.LOGGER=xaaudit
+# Enable audit logs to Amazon CloudWatch Logs
+#Example
+#XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=true
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=ranger_audits
+#XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM={instance_id}
+#XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=/var/log/hive/audit/amazon_cloudwatch/spool
+
+XAAUDIT.AMAZON_CLOUDWATCH.ENABLE=false
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_GROUP=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.LOG_STREAM_PREFIX=NONE
+XAAUDIT.AMAZON_CLOUDWATCH.FILE_SPOOL_DIR=NONE
+
# End of V3 properties