Have anyone been able to create an aws.codepipelin...
# aws
f
Have anyone been able to create an aws.codepipeline.Pipeline that have no triggers at all on the Source actions? I am trying to create a pipeline, with Sources connected to a self-managed GitLab, and thus using a CodeConnection. According to AWS documentation, I should be able to specify
"DetectChanges": "false"
in the
configuration
section of the source action, when using a provider of type
CodeStarSourceConnection
. However, there seem to be no way to avoid creating an active push trigger, which I DO NOT want. The pipeline will be triggered from an CloudWatch event bus, via an aws.cloudwatch.EventTarget. After the pipeline is created, I can remove the push trigger from using the AWS console, and they do not come back on subsequent
pulumi up
updates, but introducing a manual step that can easily be forgotten, defeats the purpose of IaC. Neither the AWS documentation, nor the Pulumi documentation are very helpful on the topic, except that the AWS docs says that
"DetectChanges": "false"
should do it. It does not, it seems. Speaking of triggering a pipeline via an aws.cloudwatch.EventTarget, has anyone been able to pass along event data to the pipeline, or to the aws.codebuild.Project(s) in the pipeline? Both pulumi AI and ChatGPT et.al. suggests using an input transform in the aws.cloudwatch.EventTarget and the data should be possible to pick up as environment variables like this
INSTANCE_ID="<instance_id>"
, but that just sets
INSTANCE_ID
to
<instance_id>
. In code it might be similar to this, with some suggestions by Pulumi AI (tried all version of suggestions, none works as I would like):
Copy code
gitlab_host = aws.codestarconnections.Host(
    "GitLabHost",
    opts=pulumi.ResourceOptions(retain_on_delete=True),
    name="GitLabHost",
    provider_type="GitLabSelfManaged",
    provider_endpoint="<https://gitlab.example.com>",
    vpc_configuration={
        "securityGroupIds": [security_group.id],
        "subnetIds": [subnet1.id, subnet2.id, subnet3.id],
        "vpcId": vpc.id,
    })

gitlab_connection = aws.codestarconnections.Connection(
    "GitLabConnection",
    opts=pulumi.ResourceOptions(retain_on_delete=True),
    name="GitLabConnection",
    host_arn=gitlab_host.arn,
)

build_project = aws.codebuild.Project(
    "BuildProject",
    name="BuildProject",
    service_role=code_build_service_role.arn,
    environment={
        "computeType": "BUILD_GENERAL1_SMALL",
        "image": latest_image_version,
        "type": "LINUX_CONTAINER",
        "image_pull_credentials_type": "CODEBUILD",
        "environment_variables": [
            {
                "name": "INSTANCE_ID",
                "value": "<instanceId>",   # <--- Suggested by Pulumi AI, does not work
                "type": "PLAINTEXT",
            },
        ],
    },
    artifacts={
        "type": "CODEPIPELINE",
    },
    logs_config={
        "cloudwatch_logs": {
            "group_name": "BuildProject",
            "stream_name": "",
        },
        "s3_logs": {
            "status": "ENABLED",
            "location": codebuild_bucket.id.apply(lambda id: f"{id}/build-logs/service-infra"),
        },
    },
    source={
        "type": "CODEPIPELINE",
    },
    source_version="main",
    vpc_config={
        "security_group_ids": [security_group.id],
        "subnets": [subnet1.id, subnet2.id, subnet3.id],
        "vpc_id": vpc.id,
    },
)


pipeline = aws.codepipeline.Pipeline(
    "Pipeline",
    name="Pipeline",
    role_arn=pipeline_service_role.arn,
    pipeline_type="V2",
    execution_mode="QUEUED",
    artifact_stores=[
        {
            "location": codebuild_bucket.id,
            "type": "S3",
        }
    ],
    stages=[
        {
            "name": "Sources",
            "actions": [
                {
                    "name": "GitLabSource",
                    "category": "Source",
                    "owner": "AWS",
                    "provider": "CodeStarSourceConnection",
                    "version": "1",
                    "output_artifacts": ["GitLabSource"],
                    "configuration": {
                        "ConnectionArn": gitlab_connection.arn,
                        "FullRepositoryId": "my-group/my-project",
                        "BranchName": "main",
                        "OutputArtifactFormat": "CODE_ZIP",
                        "DetectChanges": "false",
                    },
                }
            ],
        }, {
            "name": "Build",
            "actions": [{
                "name": "Build",
                "category": "Build",
                "run_order": 1,
                "owner": "AWS",
                "provider": "CodeBuild",
                "version": "1",
                "input_artifacts": ["GitLabSource"],
                "output_artifacts": ["BuildOutput"],
                "configuration": {
                    "ProjectName": build_project.name,
                    "EnvironmentVariables": json.dumps([
                        {
                            "name": "INSTANCE_ID",
                            "value": "<instanceId>",   # <--- Also suggested by Pulumi AI, does not work
                            "type": "PLAINTEXT",
                        },
                    ]),
                },
            }],
        }
    ],
)

rule = aws.cloudwatch.EventRule(
    "EventRule",
    name="EventRule",
    event_pattern=json.dumps({
        "source": ["my.source"],
        "detail-type": ["my.detail-type"],
    }),
    state="ENABLED",
    event_bus_name=event_bus.name)

aws.cloudwatch.EventTarget(
    "PipelineTarget",
    arn=pipeline.arn,
    role_arn=service_role.arn,
    event_bus_name=event_bus.name,
    rule=rule.name,
    input_transformer={
        "input_paths": {
            "instance_id": "$.detail.instance-id",
            "state": "$.detail.state"
        },
        "input_template": """{
            "instanceId": <instance_id>,
            "state": <state>
        }"""
    }
)
with a
buildspec.yml
a like this:
Copy code
version: 0.2

run-as: root

env:
  variables:
    INSTANCE_ID: "<instanceId>"   # <--- Suggested by Pulumi AI, does not work

phases:

  build:
    commands:
      - echo "Build for instance id $INSTANCE_ID" # <--- prints 'Build for instance id <instanceId>'
s
I am reading the AWS docs the same as you: detect changes = false should work. Some ideas: • Create a fake filter that only runs on changes to a branch that definitely does not exist. • What happens if you set
detectChanges
to
false
instead of
"false"
? • Remove the push trigger via the Command provider and the AWS CLI. (Be sure to add
dependsOn
b/c there's no implicit dependency.) That'll at least get everything under IaC.
For passing the event value to the CodeBuild project, I think you may need to use
environmentVariablesOverride
, per: https://stackoverflow.com/a/71773403
f
Thank you for both of those suggestions; I've been sidetracked somewhat, but will test this within a day or two. If simply using a plain
false
instead
"false"
would do the trick (or maybe
False
since I use Python) works, it feels a little like a face-palm moment. 😅 Gotta say, the
environmentVariablesOverride
input template "trick", or that you can simply match the API signature like that in general, does not seem to have made it into the documentation. Good find! Might work in other circumstances too, possibly.
s
I think you want
false
b/c it's JSON, or at least that's what I would try first. Another suggestion: See if you can get it working using CDK, or see if CDK has an obvious option to not trigger the pipeline on commit. You can synthesize the CDK to CFN YAML (
cdk synth
) and see what the generated code looks like. My suspicion is that the option is just broken for GitLab.
BTW, why not use the built-in GL CI/CD? Pulumi has an integration with it: https://www.pulumi.com/docs/iac/packages-and-automation/continuous-delivery/gitlab-app/
f
Yeah, it's gotta be either
"false"
or
False
or there's an exception
name 'false' is not defined;
; it's python after all and
Copy code
import json
j = {"myval": False}
print(json.dumps(j))
gives
{"myval": false}
so presumably pulumi is smart enough to generate valid json from python native types as well. You could be right about theGitLab option being broken. The GL CI/CD option you refer to doesn't really fit the use case; this is basically a pipeline that is triggered by updates being detected to any of several components in an development/engineering platform, at which point a near exact copy is deployed, the upgrade attempted, a test suite run, and a report/event is sent back to the production environment, which schedules an automatic upgrade if it all went well. GitLab itself is part of the platform. I would have mirrored the repositories to CodeCommit, to keep it all in AWS, but since CodeCommit is being deprecated I'll stay away from that. As for the specific article above, it seems to be merely dealing with decorating merge requests, and we discourage the use of merge requests to avoid the use of branches that live longer than a work day. If we did center our work around merge requests, it would be a very neat way to have insight into changes.
s
Ahh, I see. Have you looked at CNOE at all? My understanding is that it's a reference architecture for platform builders. One of the things they do in there is run GitTea so that you can test changes to your platform in an isolated Git SaaS. https://cnoe.io
I'm assuming there's a GL containerized solution you could swap out for GitTea if you need anything beyond what GitTea offers.
Also, I was gonna suggest mirroring - some years ago I remember I had to do GL Bitbucket -> CodeCommit mirroring to get the build triggers I needed, but I figure that info is way out of date at this point, and like you said CodeCommit is deprecated now.
f
Oh, CNOE certainly looks interesting. We've waded in quite deep into our existing weeds (it's actually quite elegant and works well), so I doubt we'll be swapping anytime soon. But who knows, CNOE does look good.
s
Could also be useful as an additional example. I haven't gone deep into it either