activerecord-aurora-serverless-adapter 6.0.0 → 6.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -3
- data/activerecord-aurora-serverless-adapter.gemspec +4 -1
- data/lib/active_record/connection_adapters/aurora_serverless/client.rb +25 -0
- data/lib/active_record/connection_adapters/aurora_serverless/version.rb +1 -1
- data/test/aasa_helper.rb +160 -0
- data/test/aurora-serverless/bin/aurora-serverless.ts +17 -0
- data/test/aurora-serverless/cdk.context.json +3 -0
- data/test/aurora-serverless/cdk.json +3 -0
- data/test/aurora-serverless/lib/aurora-serverless-stack.ts +194 -0
- data/test/aurora-serverless/package-lock.json +6485 -0
- data/test/aurora-serverless/package.json +21 -0
- data/test/aurora-serverless/tsconfig.json +23 -0
- data/test/bin/_deploy-aurora +8 -0
- data/test/bin/_wakeup +17 -0
- data/test/bin/deploy-aurora +8 -0
- data/test/bin/wakeup +8 -0
- data/test/cases/aasa/mysql_client_test.rb +59 -0
- data/test/cases/aasa/mysql_result_test.rb +63 -0
- data/test/cases/aasa/mysql_types_test.rb +135 -0
- data/test/cases/coerced_tests.rb +142 -0
- data/test/config.yml +20 -0
- data/test/support/aasa_coerceable.rb +53 -0
- data/test/support/aasa_env.rb +11 -0
- data/test/support/aasa_fixtures.rb +9 -0
- data/test/support/aasa_minitest.rb +39 -0
- data/test/support/aasa_paths.rb +47 -0
- data/test/support/aasa_rake.rb +102 -0
- metadata +39 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0eb80620f3d44cff64b9263ffb94bec8cfc5507794fc4318892655a229ec3981
|
4
|
+
data.tar.gz: f4d986df84720fc51d62412328959fbdefa9e16203b9dfc537670fa50e9d54eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: caa6fce9998662d5446e5f26c54afffa92c3560ce64cc79b43167a3eb10e426147a66750d064cdfcbad9331eb31346c24f61a49abb99463414b5a17123c08b8c
|
7
|
+
data.tar.gz: e28ee33496c94f9814b1a644dbf6a730b5db87bddcfe67cca0dcac3707d9564b444401562b192262d7e51eea3ef5d5677ebffbeac69735d1671c0ce186089fe4
|
data/Gemfile.lock
CHANGED
@@ -83,9 +83,10 @@ GIT
|
|
83
83
|
PATH
|
84
84
|
remote: .
|
85
85
|
specs:
|
86
|
-
activerecord-aurora-serverless-adapter (6.0.
|
86
|
+
activerecord-aurora-serverless-adapter (6.0.1)
|
87
87
|
activerecord (>= 6.0)
|
88
88
|
aws-sdk-rdsdataservice
|
89
|
+
retriable
|
89
90
|
|
90
91
|
GEM
|
91
92
|
remote: https://rubygems.org/
|
@@ -96,8 +97,8 @@ GEM
|
|
96
97
|
rake
|
97
98
|
thor (>= 0.14.0)
|
98
99
|
aws-eventstream (1.0.3)
|
99
|
-
aws-partitions (1.
|
100
|
-
aws-sdk-core (3.
|
100
|
+
aws-partitions (1.265.0)
|
101
|
+
aws-sdk-core (3.89.1)
|
101
102
|
aws-eventstream (~> 1.0, >= 1.0.2)
|
102
103
|
aws-partitions (~> 1, >= 1.239.0)
|
103
104
|
aws-sigv4 (~> 1.1)
|
@@ -152,6 +153,7 @@ GEM
|
|
152
153
|
rails-html-sanitizer (1.3.0)
|
153
154
|
loofah (~> 2.3)
|
154
155
|
rake (13.0.1)
|
156
|
+
retriable (3.1.2)
|
155
157
|
ruby-progressbar (1.10.1)
|
156
158
|
sprockets (4.0.0)
|
157
159
|
concurrent-ruby (~> 1.0)
|
@@ -12,13 +12,16 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.homepage = 'https://github.com/customink/activerecord-aurora-serverless-adapter'
|
13
13
|
spec.license = 'MIT'
|
14
14
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
15
|
-
`git ls-files -z`.split("\x0").reject
|
15
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features|docker)/i})
|
17
|
+
end
|
16
18
|
end
|
17
19
|
spec.bindir = 'exe'
|
18
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
21
|
spec.require_paths = ['lib']
|
20
22
|
spec.add_runtime_dependency 'activerecord', '>= 6.0'
|
21
23
|
spec.add_runtime_dependency 'aws-sdk-rdsdataservice'
|
24
|
+
spec.add_runtime_dependency 'retriable'
|
22
25
|
spec.add_development_dependency 'appraisal'
|
23
26
|
spec.add_development_dependency 'dotenv'
|
24
27
|
spec.add_development_dependency 'minitest'
|
@@ -23,6 +23,14 @@ module ActiveRecord
|
|
23
23
|
"#<#{self.class} database: #{database.inspect}, raw_client: #{raw_client.inspect}>"
|
24
24
|
end
|
25
25
|
|
26
|
+
def execute_statement_retry(sql)
|
27
|
+
if @connected
|
28
|
+
execute_statement(sql)
|
29
|
+
else
|
30
|
+
auto_paused_retry { execute_statement(sql) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
26
34
|
def execute_statement(sql)
|
27
35
|
id = @transactions.first
|
28
36
|
debug_transactions "EXECUTE: #{sql}", id
|
@@ -34,6 +42,7 @@ module ActiveRecord
|
|
34
42
|
include_result_metadata: true,
|
35
43
|
transaction_id: id
|
36
44
|
}).tap do |r|
|
45
|
+
@connected = true
|
37
46
|
@affected_rows = affected_rows_result(r)
|
38
47
|
@last_id = last_id_result(r)
|
39
48
|
end
|
@@ -100,6 +109,22 @@ module ActiveRecord
|
|
100
109
|
field.long_value || field.string_value || field.double_value
|
101
110
|
end
|
102
111
|
|
112
|
+
def auto_paused_retry
|
113
|
+
error_klass = Aws::RDSDataService::Errors::BadRequestException
|
114
|
+
error_msg = /last packet sent successfully to the server was/
|
115
|
+
retry_msg = 'Aurora auto paused, retrying...'
|
116
|
+
on_retry = Proc.new { sleep(1) ; ::Rails.logger.info(retry_msg) }
|
117
|
+
Retriable.retriable({
|
118
|
+
on: { error_klass => error_msg },
|
119
|
+
on_retry: on_retry,
|
120
|
+
tries: auto_paused_retry_count
|
121
|
+
}) { yield }
|
122
|
+
end
|
123
|
+
|
124
|
+
def auto_paused_retry_count
|
125
|
+
10
|
126
|
+
end
|
127
|
+
|
103
128
|
def debug_transactions(name, id = 'NOID')
|
104
129
|
return unless @debug_transactions
|
105
130
|
ActiveRecord::Base.logger.debug " \e[36m#{name} #{id} #{object_id}\e[0m"
|
data/test/aasa_helper.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
ENV['AASA_ENV'] = 'test'
|
2
|
+
require 'bundler/setup'
|
3
|
+
Bundler.require :default, :development
|
4
|
+
Dotenv.load('.env')
|
5
|
+
require 'minitest/spec'
|
6
|
+
require 'minitest/autorun'
|
7
|
+
require 'minitest/retry'
|
8
|
+
require 'minitest/reporters'
|
9
|
+
require 'cases/helper' unless ENV['TEST_FILES'] || ENV['ONLY_AASA']
|
10
|
+
require_relative 'support/aasa_coerceable'
|
11
|
+
require_relative 'support/aasa_env'
|
12
|
+
require_relative 'support/aasa_fixtures'
|
13
|
+
require_relative 'support/aasa_minitest'
|
14
|
+
Rails.backtrace_cleaner.remove_silencers! if ENV['REMOVE_SILENCERS']
|
15
|
+
|
16
|
+
module ActiveRecord
|
17
|
+
module ConnectionAdapters
|
18
|
+
module AuroraServerless
|
19
|
+
class TestCase < Minitest::Spec
|
20
|
+
|
21
|
+
before { setup_table }
|
22
|
+
after { drop_table }
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def client
|
27
|
+
@client ||= AuroraServerless::Client.new(
|
28
|
+
'activerecord_unittest',
|
29
|
+
ENV['AASA_RESOURCE_ARN'],
|
30
|
+
ENV['AASA_SECRET_ARN']
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def execute(sql)
|
35
|
+
r = client.execute_statement(sql)
|
36
|
+
# TODO: [PG] Make this a conditional result wrapper.
|
37
|
+
AuroraServerless::Mysql2::Result.new(r)
|
38
|
+
end
|
39
|
+
|
40
|
+
def setup_table
|
41
|
+
# TODO: [PG] Make this a conditional for constant SQL.
|
42
|
+
execute MYSQL_CREATE_TABLE_SQL
|
43
|
+
execute MYSQL_INSERT_SQL
|
44
|
+
end
|
45
|
+
|
46
|
+
def drop_table
|
47
|
+
execute 'DROP TABLE IF EXISTS aurora_test'
|
48
|
+
end
|
49
|
+
|
50
|
+
MYSQL_CREATE_TABLE_SQL = %[
|
51
|
+
CREATE TABLE IF NOT EXISTS aurora_test (
|
52
|
+
id int NOT NULL AUTO_INCREMENT,
|
53
|
+
PRIMARY KEY (id),
|
54
|
+
null_test VARCHAR(10),
|
55
|
+
bit_test BIT,
|
56
|
+
tiny_int_test TINYINT,
|
57
|
+
small_int_test SMALLINT,
|
58
|
+
medium_int_test MEDIUMINT,
|
59
|
+
int_test INT,
|
60
|
+
big_int_test BIGINT,
|
61
|
+
float_test FLOAT(10,3),
|
62
|
+
float_zero_test FLOAT(10,3),
|
63
|
+
double_test DOUBLE(10,3),
|
64
|
+
decimal_test DECIMAL(10,3),
|
65
|
+
decimal_zero_test DECIMAL(10,3),
|
66
|
+
date_test DATE,
|
67
|
+
date_time_test DATETIME,
|
68
|
+
timestamp_test TIMESTAMP,
|
69
|
+
time_test TIME,
|
70
|
+
year_test YEAR(4),
|
71
|
+
char_test CHAR(10),
|
72
|
+
varchar_test VARCHAR(10),
|
73
|
+
binary_test BINARY(10),
|
74
|
+
varbinary_test VARBINARY(10),
|
75
|
+
tiny_blob_test TINYBLOB,
|
76
|
+
tiny_text_test TINYTEXT,
|
77
|
+
blob_test BLOB,
|
78
|
+
text_test TEXT,
|
79
|
+
medium_blob_test MEDIUMBLOB,
|
80
|
+
medium_text_test MEDIUMTEXT,
|
81
|
+
long_blob_test LONGBLOB,
|
82
|
+
long_text_test LONGTEXT,
|
83
|
+
enum_test ENUM('val1', 'val2'),
|
84
|
+
set_test SET('val1', 'val2')
|
85
|
+
) DEFAULT CHARSET=utf8
|
86
|
+
]
|
87
|
+
|
88
|
+
MYSQL_INSERT_SQL = %[
|
89
|
+
INSERT INTO aurora_test (
|
90
|
+
null_test,
|
91
|
+
bit_test,
|
92
|
+
tiny_int_test,
|
93
|
+
small_int_test,
|
94
|
+
medium_int_test,
|
95
|
+
int_test,
|
96
|
+
big_int_test,
|
97
|
+
float_test,
|
98
|
+
float_zero_test,
|
99
|
+
double_test,
|
100
|
+
decimal_test,
|
101
|
+
decimal_zero_test,
|
102
|
+
date_test,
|
103
|
+
date_time_test,
|
104
|
+
timestamp_test,
|
105
|
+
time_test,
|
106
|
+
year_test,
|
107
|
+
char_test,
|
108
|
+
varchar_test,
|
109
|
+
binary_test,
|
110
|
+
varbinary_test,
|
111
|
+
tiny_blob_test,
|
112
|
+
tiny_text_test,
|
113
|
+
blob_test,
|
114
|
+
text_test,
|
115
|
+
medium_blob_test,
|
116
|
+
medium_text_test,
|
117
|
+
long_blob_test,
|
118
|
+
long_text_test,
|
119
|
+
enum_test,
|
120
|
+
set_test
|
121
|
+
)
|
122
|
+
VALUES (
|
123
|
+
NULL,
|
124
|
+
1,
|
125
|
+
5,
|
126
|
+
32766,
|
127
|
+
8388606,
|
128
|
+
2147483646,
|
129
|
+
9223372036854775806,
|
130
|
+
156.68449197860963,
|
131
|
+
0.0,
|
132
|
+
606682.8877005348,
|
133
|
+
676254.5454545454,
|
134
|
+
0,
|
135
|
+
'2010-4-4',
|
136
|
+
'2010-4-4 11:44:00',
|
137
|
+
'2010-4-4 11:44:00',
|
138
|
+
'11:44:00',
|
139
|
+
2019,
|
140
|
+
'abcdefg',
|
141
|
+
'abcdefg',
|
142
|
+
'abcdefg',
|
143
|
+
'abcdefg',
|
144
|
+
'abcdefg',
|
145
|
+
'abcdefg',
|
146
|
+
'abcdefg',
|
147
|
+
'abcdefg',
|
148
|
+
'abcdefg',
|
149
|
+
'abcdefg',
|
150
|
+
'abcdefg',
|
151
|
+
'abcdefg',
|
152
|
+
'val1',
|
153
|
+
'val1,val2'
|
154
|
+
)
|
155
|
+
]
|
156
|
+
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
import "source-map-support/register";
|
3
|
+
import cdk = require("@aws-cdk/core");
|
4
|
+
import { AuroraServerlessStack } from "../lib/aurora-serverless-stack";
|
5
|
+
|
6
|
+
const APP = new cdk.App();
|
7
|
+
|
8
|
+
new AuroraServerlessStack(APP, "AuroraServerlessStack", {
|
9
|
+
stackName: "aasa-mysql-unit",
|
10
|
+
description: "Test customink/activerecord-aurora-serverless-adapter.",
|
11
|
+
tags: {
|
12
|
+
env: "dev",
|
13
|
+
group: "shared",
|
14
|
+
application: "activerecord-aurora-serverless-adapter",
|
15
|
+
owner: "kcollins"
|
16
|
+
}
|
17
|
+
});
|
@@ -0,0 +1,194 @@
|
|
1
|
+
// Thanks to https://almirzulic.com/posts/create-serverless-aurora-cluster-with-cdk/
|
2
|
+
|
3
|
+
import { CfnOutput, Construct, Stack, StackProps } from "@aws-cdk/core";
|
4
|
+
import { Vpc, SubnetType } from "@aws-cdk/aws-ec2";
|
5
|
+
import {
|
6
|
+
CfnDBCluster,
|
7
|
+
CfnDBSubnetGroup,
|
8
|
+
CfnDBClusterProps,
|
9
|
+
CfnDBClusterParameterGroup
|
10
|
+
} from "@aws-cdk/aws-rds";
|
11
|
+
import { CfnSecret, CfnSecretProps } from "@aws-cdk/aws-secretsmanager";
|
12
|
+
import { User, Policy, PolicyStatement, CfnAccessKey } from "@aws-cdk/aws-iam";
|
13
|
+
|
14
|
+
const MASTER_USER = process.env.AASA_MASTER_USER;
|
15
|
+
const MASTER_PASS = process.env.AASA_MASTER_PASS;
|
16
|
+
const DB_NAME = "activerecord_unittest";
|
17
|
+
const DB_CLUSTER_ID = "aasa-mysql-unit";
|
18
|
+
|
19
|
+
function auroraProps(
|
20
|
+
dbName: string,
|
21
|
+
dbClusterId: string,
|
22
|
+
dbSubnetGroupName: string | undefined,
|
23
|
+
dbParamGroup: CfnDBClusterParameterGroup
|
24
|
+
) {
|
25
|
+
return {
|
26
|
+
databaseName: dbName,
|
27
|
+
dbClusterIdentifier: dbClusterId,
|
28
|
+
engine: "aurora",
|
29
|
+
engineMode: "serverless",
|
30
|
+
masterUsername: MASTER_USER,
|
31
|
+
masterUserPassword: MASTER_PASS,
|
32
|
+
enableHttpEndpoint: true,
|
33
|
+
port: 3306,
|
34
|
+
dbSubnetGroupName: dbSubnetGroupName,
|
35
|
+
dbClusterParameterGroupName: dbParamGroup.ref,
|
36
|
+
scalingConfiguration: {
|
37
|
+
autoPause: true,
|
38
|
+
minCapacity: 1,
|
39
|
+
maxCapacity: 4,
|
40
|
+
secondsUntilAutoPause: 3600
|
41
|
+
}
|
42
|
+
} as CfnDBClusterProps;
|
43
|
+
}
|
44
|
+
|
45
|
+
function secretProps(aurora: CfnDBCluster, dbClusterId: string) {
|
46
|
+
return {
|
47
|
+
secretString: JSON.stringify({
|
48
|
+
username: MASTER_USER,
|
49
|
+
password: MASTER_PASS,
|
50
|
+
engine: "mysql",
|
51
|
+
host: aurora.attrEndpointAddress,
|
52
|
+
port: aurora.attrEndpointPort,
|
53
|
+
dbClusterIdentifier: dbClusterId
|
54
|
+
}),
|
55
|
+
description: "AASA Master Credentials."
|
56
|
+
} as CfnSecretProps;
|
57
|
+
}
|
58
|
+
|
59
|
+
export class AuroraServerlessStack extends Stack {
|
60
|
+
constructor(scope: Construct, id: string, props?: StackProps) {
|
61
|
+
super(scope, id, props);
|
62
|
+
|
63
|
+
// VPC
|
64
|
+
|
65
|
+
const vpc = new Vpc(this, "Vpc", {
|
66
|
+
cidr: "10.0.0.0/16",
|
67
|
+
natGateways: 0,
|
68
|
+
subnetConfiguration: [
|
69
|
+
{ name: "aasa_isolated", subnetType: SubnetType.ISOLATED }
|
70
|
+
]
|
71
|
+
});
|
72
|
+
const subnetIds: string[] = [];
|
73
|
+
vpc.isolatedSubnets.forEach(subnet => {
|
74
|
+
subnetIds.push(subnet.subnetId);
|
75
|
+
});
|
76
|
+
|
77
|
+
// SUBNET GROUP
|
78
|
+
|
79
|
+
const dbSubnetGroup: CfnDBSubnetGroup = new CfnDBSubnetGroup(
|
80
|
+
this,
|
81
|
+
"AuroraSubnetGroup",
|
82
|
+
{
|
83
|
+
dbSubnetGroupDescription: "Subnet group to AASA Aurora",
|
84
|
+
dbSubnetGroupName: "aasa-subnet-group",
|
85
|
+
subnetIds
|
86
|
+
}
|
87
|
+
);
|
88
|
+
|
89
|
+
// RDS PARAMETER GROUP
|
90
|
+
|
91
|
+
const dbParamGroup = new CfnDBClusterParameterGroup(
|
92
|
+
this,
|
93
|
+
"ParameterGroup",
|
94
|
+
{
|
95
|
+
family: "aurora5.6",
|
96
|
+
description: "Test customink/activerecord-aurora-serverless-adapter.",
|
97
|
+
parameters: {
|
98
|
+
innodb_large_prefix: "1",
|
99
|
+
innodb_file_per_table: "1",
|
100
|
+
innodb_file_format: "Barracuda",
|
101
|
+
character_set_client: "utf8mb4",
|
102
|
+
character_set_connection: "utf8mb4",
|
103
|
+
character_set_database: "utf8mb4",
|
104
|
+
character_set_results: "utf8mb4",
|
105
|
+
character_set_server: "utf8mb4",
|
106
|
+
collation_server: "utf8mb4_unicode_ci",
|
107
|
+
collation_connection: "utf8mb4_unicode_ci"
|
108
|
+
}
|
109
|
+
}
|
110
|
+
);
|
111
|
+
dbParamGroup.addDependsOn(dbSubnetGroup);
|
112
|
+
|
113
|
+
// AURORA SERVERLESS CLUSTERS
|
114
|
+
|
115
|
+
const aurora = new CfnDBCluster(
|
116
|
+
this,
|
117
|
+
"AuroraServerless",
|
118
|
+
auroraProps(
|
119
|
+
DB_NAME,
|
120
|
+
DB_CLUSTER_ID,
|
121
|
+
dbSubnetGroup.dbSubnetGroupName,
|
122
|
+
dbParamGroup
|
123
|
+
)
|
124
|
+
);
|
125
|
+
const aurora2 = new CfnDBCluster(
|
126
|
+
this,
|
127
|
+
"AuroraServerless2",
|
128
|
+
auroraProps(
|
129
|
+
`${DB_NAME}2`,
|
130
|
+
`${DB_CLUSTER_ID}2`,
|
131
|
+
dbSubnetGroup.dbSubnetGroupName,
|
132
|
+
dbParamGroup
|
133
|
+
)
|
134
|
+
);
|
135
|
+
aurora.addDependsOn(dbParamGroup);
|
136
|
+
aurora2.addDependsOn(dbParamGroup);
|
137
|
+
new CfnOutput(this, "AASAResourceArn", {
|
138
|
+
value: `arn:aws:rds:${this.region}:${this.account}:cluster:${DB_CLUSTER_ID}`
|
139
|
+
});
|
140
|
+
new CfnOutput(this, "AASAResourceArn2", {
|
141
|
+
value: `arn:aws:rds:${this.region}:${this.account}:cluster:${DB_CLUSTER_ID}2`
|
142
|
+
});
|
143
|
+
|
144
|
+
// SECRETS
|
145
|
+
|
146
|
+
const secret = new CfnSecret(
|
147
|
+
this,
|
148
|
+
"Secret",
|
149
|
+
secretProps(aurora, DB_CLUSTER_ID)
|
150
|
+
);
|
151
|
+
const secret2 = new CfnSecret(
|
152
|
+
this,
|
153
|
+
"Secret2",
|
154
|
+
secretProps(aurora2, `${DB_CLUSTER_ID}2`)
|
155
|
+
);
|
156
|
+
secret.addDependsOn(aurora);
|
157
|
+
secret2.addDependsOn(aurora2);
|
158
|
+
new CfnOutput(this, "AASASecretArn", {
|
159
|
+
value: secret.ref
|
160
|
+
});
|
161
|
+
new CfnOutput(this, "AASASecretArn2", {
|
162
|
+
value: secret2.ref
|
163
|
+
});
|
164
|
+
|
165
|
+
// TEST USER
|
166
|
+
|
167
|
+
const user = new User(this, "TestUser");
|
168
|
+
const policy = new Policy(this, "TestUserPolicy", {
|
169
|
+
statements: [
|
170
|
+
new PolicyStatement({
|
171
|
+
actions: ["rds-data:*"],
|
172
|
+
resources: [
|
173
|
+
`arn:aws:rds:${this.region}:${this.account}:cluster:${DB_CLUSTER_ID}*`,
|
174
|
+
`arn:aws:rds:${this.region}:${this.account}:cluster:${DB_CLUSTER_ID}2*`
|
175
|
+
]
|
176
|
+
}),
|
177
|
+
new PolicyStatement({
|
178
|
+
actions: ["secretsmanager:*"],
|
179
|
+
resources: [`${secret.ref}*`, `${secret2.ref}*`]
|
180
|
+
})
|
181
|
+
]
|
182
|
+
});
|
183
|
+
user.attachInlinePolicy(policy);
|
184
|
+
const key = new CfnAccessKey(this, "TestUserKey", {
|
185
|
+
userName: user.userName
|
186
|
+
});
|
187
|
+
new CfnOutput(this, "AASAUserAccessKeyId", {
|
188
|
+
value: key.ref
|
189
|
+
});
|
190
|
+
new CfnOutput(this, "AASAUserSecretAccessKey", {
|
191
|
+
value: key.attrSecretAccessKey
|
192
|
+
});
|
193
|
+
}
|
194
|
+
}
|