Why codepipline require the KMS key? - amazon-web-services

I made the CodePipeline to build the source code from CodeCommit to ECR by cdk
When deploying this cdk code, somehow the key named like this
codepipeline-cdkmynavirepomynavipipelinefe7f8d68 is made in KMS customer managed key
I am not sure why this is made, and I don't want to use this.
Why or where this key is made?
const adminPipeline = new codepipeline.Pipeline(this, 'mynaviPipeline', {
pipelineName: 'cdk-mynavi-pl',
});
const mynavi_cc_repo_name = 'cdk-mynavi-cc'
const mynavi_cc_repo = new codecommit.Repository(this,
"mynavi-cc-repo",{
repositoryName: mynavi_cc_repo_name,
description:"for resizer repo"
})
const adminBuildProject = new codebuild.PipelineProject(this, 'adminBuildproject', {
environment: {
buildImage:codebuild.LinuxBuildImage.STANDARD_4_0,
privileged:true,
},
buildSpec: codebuild.BuildSpec.fromSourceFilename("./buildspec.yml")
});
const adminSourceOutput = new codepipeline.Artifact();
const adminSourceAction = new cdk.aws_codepipeline_actions.CodeCommitSourceAction({
actionName: 'AdminSource',
repository: mynavi_cc_repo,
output: adminSourceOutput,
trigger: cdk.aws_codepipeline_actions.CodeCommitTrigger.POLL,
})
const dockerHubSecretArn = 'arn:aws:secretsmanager:ap-northeast-1:678100228231:secret:docker_login-TBFA5B';
const dockerHubSecret = secretsmanager.Secret.fromSecretCompleteArn(this, 'SecretFromCompleteArn', dockerHubSecretArn);
dockerHubSecret.grantRead(adminBuildProject)
cronEcrRepo.grantPullPush(adminBuildProject)
djangoEcrRepo.grantPullPush(adminBuildProject)
nginxEcrRepo.grantPullPush(adminBuildProject)
const adminBuildOutput = new codepipeline.Artifact();
const adminBuildAction = new cdk.aws_codepipeline_actions.CodeBuildAction({
actionName: 'AdminCodeBuild',
project: adminBuildProject,
input: adminSourceOutput,
outputs: [adminBuildOutput]
});
adminPipeline.addStage({
stageName: "mynaviSource",
actions: [adminSourceAction],
});
adminPipeline.addStage({
stageName : "mynaviBuild",
actions: [adminBuildAction]
});

It has to do with encryption at rest.
Data in CodePipeline is encrypted at rest using AWS KMS keys. Code artifacts are stored in a customer-owned S3 bucket and encrypted with either the AWS managed key or a customer managed key.
Encrypting codepipline artifacts is enabled by default.
If you choose the default option for encrypting code artifacts, CodePipeline uses the AWS managed key. You cannot change or delete this AWS managed key.
You cannot disable the encryption, but you can choose how you encrypt the artifacts.
The good thing is that if you go with the default option, you don't have to manage the encryption keys.
This can be, for example, selected in the CodePipeline console:
More on Data Protection in AWS CodePipeline.

Related

How to Reuse the api gate TokenAuthorizer

I want to reuse the TokenAuthorizer which I have created in another stack. If a do the below it gives an error that it already exists, and if I change the authorizerName it creates a new one.
Is there a way I can reuse this resource?
const authzHandler = lambda.Function.fromFunctionName(this, 'AuthHandlerLookup', 'auth-handler');
const authorizer = new apigateway.TokenAuthorizer(this, 'WebApiTokenAuthorizer', {
handler: authzHandler,
resultsCacheTtl: Duration.seconds(600),
authorizerName: 'test-Authorizer',
assumeRole: lambdaExecutionRole
});
test.addMethod('GET', new apigateway.LambdaIntegration(TestLambda , { proxy: true }),
{
authorizer
}
i am able to get the authorizer information in cli , but now sure how to do the same using cdk
aws apigateway get-authorizer --rest-api-id wrrt25mzme0m --authorizer-id vffawds

Give KMS access permission to Proxy

I want to give the decrypt permission for proxy.
This proxy uses the a key in secret manager as username/password store.
and it uses key in KMS as Encryption key
This code makes role to acceess the secret manager automatically, but not KMS for decryption.
const dbProxy = new rds.DatabaseProxy(this, 'Proxy', {
proxyTarget: rds.ProxyTarget.fromCluster(dbCluster),
dbProxyName: `vr-${targetEnv}-rds-proxy`,
secrets: [dbCluster.secret!],// it makes the role to access the secret manager automatically.
securityGroups:[proxySecurityGroup],
requireTLS:false,
iamAuth:false,
vpc,
});
const kmsPolicy = new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ["kms:Decrypt"],
resources: ["*"],
})
dbProxy.addToRolePolicy(kmsPolicy)
However, there comes this error.
Property 'addToRolePolicy' does not exist on type 'DatabaseProxy'
I want to fetch the default created role and add this kmsPolicy
I tried this too.
const mainEncSecretArn = kms.Key.fromKeyArn(this, "kms-key", "arn:aws:kms:ap-northeast-1:665852837485:key/bf3cf318-1376-44de-a014-181074f4899d");
mainEncSecretArn.grantDecrypt(dbProxy);
The error is
Argument of type 'DatabaseProxy' is not assignable to parameter of type 'IGrantable'.
Property 'grantPrincipal' is missing in type 'DatabaseProxy' but required in type 'IGrantable'.
After working today with AWS Support, i was told (verbatim):
I would suggest explicitly defining the KMS permissions in a IAM policy document rather than using the "fromAliasName" Function.
I have provided some references that should help you write and attach the necessary KMS permission policy that is equivalent to the one that would have been created by the "fromAliasName" Function
And here is manual version of what support is saying cannot be done with cdk yet:
// get your kms key arn:
const kmsKeyArn =
'arn:aws:kms:us-west-2:123456789012:key/12345678-1234-1234-1234-1234567890';
// you won't be able to use the default proxy role :(
const proxyRole = new iam.Role(this, 'proxy-role', {
assumedBy: new iam.ServicePrincipal('rds.amazonaws.com'),
});
proxyRole.attachInlinePolicy(
new iam.Policy(this, 'kms-proxy-decrypt-policy', {
statements: [
new iam.PolicyStatement({
// grant the permission:
actions: ['kms:Decrypt'],
// put your kms key arn here:
resources: [kmsKeyArn],
}),
],
})
);
const proxy = new rds.DatabaseProxy(this, 'db-proxy', {
// there is other stuff here:
...
// ..but assign the role here:
role: proxyRole,
})

How do I provide credentials from CloudFoundry to AWS-sdk

I'm learning CloudFoundry, and trying to get my node.js app to access my AWS S3 service. I've bound my AWS S3 service to the app (in manifest.yml, path applications/services). In code, I can get the credentials using cfenv, but how do I supply them to AWS?
var cfenv = require("cfenv");
var appEnv = cfenv.getAppEnv();
var my_s3_service = appEnv.getService('my-s3-service');
/* my_s3_service.credentials = {
"api_key": "(redacted)",
"bucket": "(redacted)",
"endpoint": "s3-eu-west-1.amazonaws.com",
"location_constraint": "eu-west-1",
"secret_key": "(redacted)",
"uri": "s3://(redacted):(redacted)#s3-eu-west-1.amazonaws.com/(redacted)"
}
var AWS = require('aws-sdk');
AWS.config.update(Uhhh... something with my_s3_service.credentials... but what?);
const s3 = new AWS.S3();
s3.getObject({
Bucket: my_s3_service.credentials,
Key: "my-key.json"
}, (...));
Looking in AWS SDK for JavaScript - Setting Credentials in Node.js, I see several methods to provide credentials - but none starts with the credentials object I have...
This worked for me:
var servicekey = my_s3_service.credentials;
var creds = new AWS.Credentials(servicekey.api_key, servicekey.secret_key);
AWS.config.update({credentials: creds});
How I found out: I debugged how it worked locally, and saw that AWS.config.credentials was of type SharedIniFileCredentials, taken locally from %USERPROFILE%\.aws\credentials (ref), which presumably was instated when I configured AWS cli. So I guessed I needed to put an AWS.Credentials object in there

How to retrieve SecretsManager secret in AWS CDK

I'm setting up a Fargate service in AWS using CDK
const albFargateService = new ecs_patterns.ApplicationLoadBalancedFargateService(
this,
'FargateService',
{
vpc: ...,
taskImageOptions: {
image: ...,
containerPort: ...,
secrets: {
MY_ENV_VAR: Secret.fromSecretsManager(
**ISecret**,
'fieldWithinTheSecret'
),
}
}
}
)
How am I supposed to get hold of the ISecret instance given the name of the secret?
I've looked at the AWS.SecretsManager from the AWS SDK, but it only returns strings.
Currently there is no Secret.fromSecretName-method. Assuming that you are using an existing secret, you should use the Secret.fromSecretArn-method.
Note that if you use a KMS key, you should use the Secret.fromSecretAttributes-method as described at Get a value from AWS secrets manager.
import * as ecs from "#aws-cdk/aws-ecs";
import * as ecs_patterns from "#aws-cdk/aws-ecs-patterns";
import * as secretsmanager from "#aws-cdk/aws-secretsmanager";
const mySecret = secretsmanager.Secret.fromSecretArn(this, "mySecret", "arn:aws:secretsmanager:<region>:<account-id-number>:secret:<secret-name>-<random-6-characters>");
const albFargateService = new ecs_patterns.ApplicationLoadBalancedFargateService(
this,
'FargateService',
{
vpc: ...,
taskImageOptions: {
image: ...,
containerPort: ...,
secrets: {
MY_ENV_VAR: ecs.Secret.fromSecretsManager(mySecret),
}
}
}
);
The updated one with CDK version 2
You can refer to a secret either with Secret.fromSecretNameV2() and retrieve a particular secret value using Secret.secretValueFromJson('keyname').toString();
Refer to the code snippet below
const appSecret = Secret.fromSecretNameV2(this,'app-secret',"secret-name");
const value1 = appSecret.secretValueFromJson('KeyName1').toString();
const value2 = appSecret.secretValueFromJson('KeyName2').toString();
The best thing is, you can use this secret value anywhere like Cognito
Secrets, and it will not hardcode the secret value in your cloud
formation stack. Instead, it will use a token and it will be resolved
to the value when it is deployed.

How to run a Lambda function locally that accesses protected resources

I'm still learning to use AWS Lambda functions. I generated mine using the Amplify framework. The Lambda function I use needs to access an AppSync API. Therefore it has the following middleware:
const tapRoute = f => R.tap(route => route.use(f));
const hydrateClient = tapRoute(async function(req, res, next) {
try {
const url = process.env.API_SAYMAPPSYNCAPI_GRAPHQLAPIENDPOINTOUTPUT;
const region = process.env.REGION;
AWS.config.update({
region,
credentials: new AWS.Credentials(
process.env.AWS_ACCESS_KEY_ID,
process.env.AWS_SECRET_ACCESS_KEY,
process.env.AWS_SESSION_TOKEN
),
});
const credentials = AWS.config.credentials;
const appsyncClient = new AWSAppSyncClient(
{
url,
region,
auth: {
type: 'AWS_IAM',
credentials,
},
disableOffline: true,
},
{
defaultOptions: {
query: {
fetchPolicy: 'network-only',
errorPolicy: 'all',
},
},
}
);
const client = await appsyncClient.hydrated();
req.client = client;
next();
} catch (error) {
console.log(error);
next(error);
}
});
As you can see I need to access the environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN. When I run the function in the cloud, it automatically gets the values for these variables. How can I get them locally? Which access key do I need to use and how do I get its secret access key and the session token?
You don't need to explicitly set them if you have configured the ~/.aws/credentials file`.
If you want to configure this file, the easiest way is to simply install the aws-cli and run aws configure. You will be prompted to enter a few values, including AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
If you don't have this file configured, then you can set these values in environment variables yourself.
You can get these values by going to AWS Console -> IAM -> Users -> Select your User -> Security Credentials -> Access Keys. Then you click on "Create Access Key" and either download or write those values down, as AWS_SECRET_ACCESS_KEY is only visible during creation time. AWS_ACCESS_KEY_ID on the other hand is always visible, but it's quite useless if you don't have the secret.
AWS_SESSION_TOKEN is only required if the user in question is using MFA. If not, this value can be ignored.
< MFAOnly >
If you are using MFA though, you will need to use the aws-cli to fetch this value, like so:
aws sts get-session-token --serial-number arn:aws:iam::account-id-number:mfa/your-user --token-code MFAToken
Then, to set the temporary credentials, run aws configure again, replace the values of AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY with the new temporary values.
Finally, to set AWS_SESSION_TOKEN, run aws configure set aws_session_token VALUE_RETURNED_FROM_GET_SESSION_TOKEN_COMMAND
< / MFAOnly >
Keep in mind that when running in the Cloud, these credentials are not loaded as you stated. IAM roles are used instead.