cdk-sops-secrets
Version:
CDK Constructs that syncs your sops secrets into AWS SecretsManager secrets.
253 lines (252 loc) • 9.68 kB
TypeScript
import { SecretValue } from 'aws-cdk-lib';
import { ISecurityGroup, IVpc, SubnetSelection } from 'aws-cdk-lib/aws-ec2';
import { IGrantable, IRole } from 'aws-cdk-lib/aws-iam';
import { IKey } from 'aws-cdk-lib/aws-kms';
import { SingletonFunction } from 'aws-cdk-lib/aws-lambda';
import { RetentionDays, ILogGroup } from 'aws-cdk-lib/aws-logs';
import { Asset } from 'aws-cdk-lib/aws-s3-assets';
import { ISecret } from 'aws-cdk-lib/aws-secretsmanager';
import { IStringParameter } from 'aws-cdk-lib/aws-ssm';
import { Construct } from 'constructs';
export declare enum UploadType {
/**
* Pass the secret data inline (base64 encoded and compressed)
*/
INLINE = "INLINE",
/**
* Uplaod the secret data as asset
*/
ASSET = "ASSET"
}
export declare enum ResourceType {
SECRET = "SECRET",
SECRET_RAW = "SECRET_RAW",
SECRET_BINARY = "SECRET_BINARY",
PARAMETER = "PARAMETER",
PARAMETER_MULTI = "PARAMETER_MULTI"
}
/**
* Configuration options for the SopsSync
*/
export interface SopsSyncOptions {
/**
* The custom resource provider to use. If you don't specify any, a new
* provider will be created - or if already exists within this stack - reused.
*
* @default - A new singleton provider will be created
*/
readonly sopsProvider?: SopsSyncProvider;
/**
* The filepath to the sops file
*/
readonly sopsFilePath?: string;
/**
* If you want to pass the sops file via s3, you can specify the bucket
* you can use cfn parameter here
* Both, sopsS3Bucket and sopsS3Key have to be specified
*/
readonly sopsS3Bucket?: string;
/**
* If you want to pass the sops file via s3, you can specify the key inside the bucket
* you can use cfn parameter here
* Both, sopsS3Bucket and sopsS3Key have to be specified
*/
readonly sopsS3Key?: string;
/**
* How should the secret be passed to the CustomResource?
* @default INLINE
*/
readonly uploadType?: UploadType;
/**
* The format of the sops file.
*
* @default - The fileformat will be derived from the file ending
*/
readonly sopsFileFormat?: undefined | 'json' | 'yaml' | 'dotenv' | 'binary';
/**
* The kmsKey used to encrypt the sops file. Encrypt permissions
* will be granted to the custom resource provider.
*
* @default - The key will be derived from the sops file
*/
readonly sopsKmsKey?: IKey[];
/**
* The age key that should be used for encryption.
*/
readonly sopsAgeKey?: SecretValue;
/**
* Should this construct automatically create IAM permissions?
*
* @default true
*/
readonly autoGenerateIamPermissions?: boolean;
/**
* The encryption key used by the CDK default Asset S3 Bucket.
* @default - Trying to get the key using the CDK Bootstrap context.
*/
readonly assetEncryptionKey?: IKey;
}
/**
* The configuration options extended by the target Secret / Parameter
*/
export interface SopsSyncProps extends SopsSyncOptions {
/**
* The target to populate with the sops file content.
* - for secret, it's the name or arn of the secret
* - for parameter, it's the name of the parameter
* - for parameter multi, it's the prefix of the parameters
*/
readonly target: string;
/**
* If the structure should be flattened use the provided separator between keys.
*
* @default - undefined
*/
readonly flattenSeparator?: string;
/**
* The encryption key used for encrypting the ssm parameter if `parameterName` is set.
*/
readonly encryptionKey?: IKey;
/**
* Will this Sync deploy a Secret or Parameter(s)
*/
readonly resourceType: ResourceType;
readonly secret?: ISecret;
readonly parameterNames?: string[];
}
/**
* Configuration options for a custom SopsSyncProvider.
*/
export interface SopsSyncProviderProps {
/**
* VPC network to place Lambda network interfaces.
*
* @default - Lambda function is not placed within a VPC.
*/
readonly vpc?: IVpc;
/**
* Where to place the network interfaces within the VPC.
*
* @default - Subnets will be chosen automatically.
*/
readonly vpcSubnets?: SubnetSelection;
/**
* Only if `vpc` is supplied: The list of security groups to associate with the Lambda's network interfaces.
*
* @default - A dedicated security group will be created for the lambda function.
*/
readonly securityGroups?: ISecurityGroup[];
/**
* The role that should be used for the custom resource provider.
* If you don't specify any, a new role will be created with all required permissions
*
* @default - a new role will be created
*/
readonly role?: IRole;
/**
* The number of days log events are kept in CloudWatch Logs. When updating
* this property, unsetting it doesn't remove the log retention policy. To
* remove the retention policy, set the value to `INFINITE`.
*
* This is a legacy API and we strongly recommend you move away from it if you can.
* Instead create a fully customizable log group with `logs.LogGroup` and use the `logGroup` property
* to instruct the Lambda function to send logs to it.
* Migrating from `logRetention` to `logGroup` will cause the name of the log group to change.
* Users and code and referencing the name verbatim will have to adjust.
*
* In AWS CDK code, you can access the log group name directly from the LogGroup construct:
* ```ts
* import * as logs from 'aws-cdk-lib/aws-logs';
*
* declare const myLogGroup: logs.LogGroup;
* myLogGroup.logGroupName;
* ```
*
* @default logs.RetentionDays.INFINITE
*/
readonly logRetention?: RetentionDays;
/**
* The log group the function sends logs to.
*
* By default, Lambda functions send logs to an automatically created default log group named /aws/lambda/{function-name}.
* However you cannot change the properties of this auto-created log group using the AWS CDK, e.g. you cannot set a different log retention.
*
* Use the `logGroup` property to create a fully customizable LogGroup ahead of time, and instruct the Lambda function to send logs to it.
*
* Providing a user-controlled log group was rolled out to commercial regions on 2023-11-16.
* If you are deploying to another type of region, please check regional availability first.
*
* @default `/aws/lambda/${this.functionName}` - default log group created by Lambda
*/
readonly logGroup?: ILogGroup;
/**
* A unique identifier to identify this provider
*
* Overwrite the default, if you need a dedicated provider.
*
* @default SopsSyncProvider
*/
readonly uuid?: string;
}
export declare class SopsSyncProvider extends SingletonFunction implements IGrantable {
private sopsAgeKeys;
private sopsAgeKeyParams;
constructor(scope: Construct, id?: string, props?: SopsSyncProviderProps);
addAgeKey(key: SecretValue): void;
/**
* Configure the Lambda to fetch an age private key from an SSM Parameter
* Store SecureString at runtime, rather than injecting it as a plaintext
* environment variable at synthesis time.
*
* The KMS key used to encrypt the SecureString is required: storing an age
* private key without envelope encryption is considered insecure.
*
* The Lambda is automatically granted `ssm:GetParameter` on the parameter
* and `kms:Decrypt` on the encryption key.
*
* @param param Parameter name string (e.g. '/sops/age/key') or an
* `IStringParameter` reference from `aws-cdk-lib/aws-ssm`.
* @param encryptionKey KMS key used to encrypt the SecureString parameter.
*/
addAgeKeyFromSsmParameter(param: string | IStringParameter, encryptionKey: IKey): void;
}
/**
* The custom resource, that is syncing the content from a sops file to a secret.
*/
export declare class SopsSync extends Construct {
/**
* The current versionId of the secret populated via this resource
*/
readonly versionId: string;
constructor(scope: Construct, id: string, props: SopsSyncProps);
}
export declare namespace Permissions {
/**
* Grants the necessary permissions for encrypt/decrypt on the customer managed encryption key
* for the secrets / parameters.
*/
function encryptionKey(key: IKey | undefined, target: IGrantable): void;
function keysFromSopsContent(ctx: Construct, c: string): IKey[];
function keysFromSopsContentAlias(ctx: Construct, c: string): IKey[];
/**
* Grants the necessary permissions to decrypt the given sops file content.
* Takes user defined keys, and searches the sops file for keys and aliases.
*/
function sopsKeys(ctx: Construct, props: {
userDefinedKeys?: IKey[];
sopsFileContent: string;
role: IRole;
}): void;
/**
* Grants the necessary permissions to write the given secrets.
*/
function secret(targetSecret: ISecret | undefined, target: IGrantable): void;
/**
* Grants the necessary permissions to write the given parameters.
*/
function parameters(ctx: Construct, targetParameters: string[] | undefined, role: IRole): void;
/**
* Grants the necessary permissions to read the given asset from S3.
*/
function assetBucket(context: Construct, asset: Asset | undefined, target: IGrantable, assetKey: IKey | undefined): void;
}