Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: support multi-account e2e cleanup #8082

Merged
merged 1 commit into from
Sep 28, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 56 additions & 14 deletions packages/amplify-e2e-tests/src/cleanup-e2e-resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ type ReportEntry = {
/**
* Configure the AWS SDK with credentials and retry
*/
const configureAws = (): void => {
if (!process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY) {
const configureAws = (accessKeyId, secretAccessKey, sessionToken = null): void => {
if (!accessKeyId || !secretAccessKey) {
throw new Error('AWS credentials are not configured. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables');
}

Expand Down Expand Up @@ -210,7 +210,7 @@ export const getJobCircleCIDetails = async (jobId: number): Promise<CircleCIJobD
const client = getCircleCIClient();
const result = await client.build(jobId);

const r = (_.pick(result, [
const r = _.pick(result, [
'build_url',
'branch',
'build_num',
Expand All @@ -221,7 +221,7 @@ export const getJobCircleCIDetails = async (jobId: number): Promise<CircleCIJobD
'committer_name',
'workflows.workflow_id',
'lifecycle',
]) as any) as CircleCIJobDetails;
]) as any as CircleCIJobDetails;
return r;
};

Expand Down Expand Up @@ -436,7 +436,6 @@ export const cleanup = async () => {
})
.help().argv;
config();
configureAws();

let filterPredicate;
if (args._.length === 0) {
Expand All @@ -454,18 +453,61 @@ export const cleanup = async () => {
const amplifyApps: AmplifyAppInfo[] = [];
const stacks: StackInfo[] = [];

for (const region of AWS_REGIONS_TO_RUN_TESTS) {
amplifyApps.push(...(await getAmplifyApps(region)));
stacks.push(...(await getStacks(region)));
const orgApi = new aws.Organizations({
apiVersion: '2016-11-28',
// the region where the organization exists
region: 'us-east-1',
});
let accs;
try {
accs = await orgApi.listAccounts().promise();
accs = accs.map(async account => {
const randomNumber = Math.floor(Math.random() * 100000);
const assumeRoleRes = await new aws.STS({
apiVersion: '2011-06-15',
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
sessionToken: process.env.AWS_SESSION_TOKEN,
})
.assumeRole({
RoleArn: `arn:aws:iam::${account.Id}:role/OrganizationAccountAccessRole`,
RoleSessionName: `testSession${randomNumber}`,
// One hour
DurationSeconds: 1 * 60 * 60,
})
.promise();
return {
accessKeyId: assumeRoleRes.Credentials.AccessKeyId,
secretAccessKey: assumeRoleRes.Credentials.SecretAccessKey,
sessionToken: assumeRoleRes.Credentials.SessionToken,
};
});
accs = await Promise.all(accs);
} catch (e) {
console.log('No child accounts found. Using parent AWS account.');
accs = [
{
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
sessionToken: process.env.AWS_SESSION_TOKEN,
},
];
}

const buckets = await getS3Buckets();
const allResources = mergeResourcesByCCIJob(amplifyApps, stacks, buckets);
const staleResources = _.pickBy(allResources, filterPredicate);
generateReport(staleResources);
await deleteResources(staleResources);
for (const account of accs) {
configureAws(account.accessKeyId, account.secretAccessKey, account.sessionToken);
for (const region of AWS_REGIONS_TO_RUN_TESTS) {
amplifyApps.push(...(await getAmplifyApps(region)));
stacks.push(...(await getStacks(region)));
}

console.log('Cleanup done!');
const buckets = await getS3Buckets();
const allResources = mergeResourcesByCCIJob(amplifyApps, stacks, buckets);
const staleResources = _.pickBy(allResources, filterPredicate);
generateReport(staleResources);
await deleteResources(staleResources);
console.log('Cleanup done!');
}
};

cleanup();