Search code examples
pythonaws-cdkaws-pipeline

Where to store environment variables when using AWS CDK Pipelines?


I've followed this tutorial to set up CDK Pipelines using Python with a trigger from Github.

It looks something like this:

import aws_cdk as cdk
from constructs import Construct
from aws_cdk.pipelines import CodePipeline, CodePipelineSource, ShellStep
from my_pipeline.my_pipeline_app_stage import MyPipelineAppStage

class MyPipelineStack(cdk.Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        pipeline =  CodePipeline(self, "Pipeline",
                        pipeline_name="MyPipeline",
                        synth=ShellStep("Synth",
                            input=CodePipelineSource.git_hub("OWNER/REPO", "main"),
                            commands=[
                                "npm install -g aws-cdk",
                                "python -m pip install -r requirements.txt",
                                "cdk synth"]))

        pipeline.add_stage(MyPipelineAppStage(self, "my-stack"))

I want to be able to get custom environment variables from my CDK stack. For example:

organizational_unit_ids=[
  os.environ.get("OU_ID"),
]

I don't want to store these environment variables directly in my code. Now my question is, where should I store these environment variables in order for the synth ShellStep to use them?

Should I add them manually to the CodeBuild action after it has been created?

Or is there somewhere central I can store them?


Solution

  • CodeBuild can retrieve your env var at run-time.

    First, store your environment variable as a parameter in the Parameter Store (or in SecretsManager).

    Then, set the parameter to a CodeBuild environment variable. To do this, use the CodeBuildStep construct for the synth input, not ShellStep. The generic ShellStep construct, which supports multiple deployment platforms, can't set CodeBuild environment variables. CodeBuildStep can.

    Set the environment variable in the build_environment arg. The value will be retrieved at run-time. Add permissions for CodeBuild to read your parameter value by adding a policy statement to role_policy_statements.

    synth=CodeBuildStep(
        "Synth",
        input=CodePipelineSource.git_hub("OWNER/REPO", "main"),
        commands=[
            "npm install -g aws-cdk",
            "python -m pip install -r requirements.txt",
            "cdk synth",
        ],
        build_environment={
            "environment_variables": {
                "OU_ID": {
                    "type": codebuild.BuildEnvironmentVariableType.PARAMETER_STORE,
                    "value": "my-ou-param",
                }
            }
        },
        role_policy_statements=[
            iam.PolicyStatement(
                effect=iam.Effect.ALLOW,
                actions=["ssm:GetParameter"],
                resources=[
                    self.format_arn(
                        service="ssm",
                        resource="parameter",
                        resource_name="my-ou-param",
                        arn_format=cdk.ArnFormat.SLASH_RESOURCE_NAME,
                    ),
                ],
            ),
        ],
    ),