-
Notifications
You must be signed in to change notification settings - Fork 510
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
host-containers-pipeline: buildspecs, pipeline cfn, refactor paths #590
Conversation
f34b6a2
to
16d8009
Compare
16d8009
to
c2d430f
Compare
Addresses @zmrow 's comments.
|
ba401d4
to
8b7d3d8
Compare
Created a separate buildspec for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❄️
13d162a
to
74e8bce
Compare
New commit breaks out the CodeBuild projects for each of the pipeline steps into separate CloudFormation stack for each host container pipeline. The buildspec for those CodeBuild project are now inlined instead of being sourced at CodeBuild runtime from the repository. |
extras/dogswatch/Makefile
Outdated
release-container: container | ||
docker tag $(DOCKER_IMAGE_REF) $(DOCKER_IMAGE_REF_RELEASE) | ||
release-container: | ||
docker build --network=host \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the removed code, the Makefile target can reuse the prior image with the container
dependency and lets developers iterate nicely (nicely to me at least :P). Can/should the buildspec use the container
target and docker tag
as needed for pipeline based release? Is there another goal in making a standalone target?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't use the container
target in a CodeBuild buildspec because there is a dependency on git
when setting DOCKER_IMAGE_REF
and the CodeBuild source doesn't have the git repo information.
https://github.com/amazonlinux/PRIVATE-thar/blob/74e8bce8b4fac1f69da7f818451513b5e71c0760/extras/dogswatch/Makefile#L9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh good point, I think we can instead lift the git rev-parse
into its own variable and overridde with the CI environment variables provided. That way the build will be less likely to diverge unexpectedly from the "base" build.
@@ -0,0 +1,260 @@ | |||
AWSTemplateFormatVersion: "2010-09-09" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't see the conversation regarding the project/pipeline split, so forgive me if this was discussed elsewhere:
What's the reasoning behind the multiple stacks for a Pipeline and its constituent CodeBuild-Stage Projects? Can these be combined into a single logical namespace - a single CloudFormation Stack? Were there ordering/dependency issues encountered that lead to this split?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was done to address #590 (comment).
Having the pipelines in separate stacks allows for flexibility down the road if we decide to separate out each host container to their own git repository.
The CodeBuild projects were separated out mostly due to wanting the buildspec to be inlined instead of being sourced during CodeBuild runtime. This alleviates the security concern of running arbitrary code in our CI/CD pipeline when a PR has changes against the buildspec files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha, my thoughts as I read over that were that we'd have separate stacks for each pipeline, not that it'd be each pipeline and another for their supporting resources. I don't think merging the two prevents the Stage's definitions from containing the same inlined buildspec, does it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, there's nothing that prevents us from doing that. I went with this mostly to reduce duplication and also thinking that it would be easier to manage.
If we merged it then both admin and control container pipeline template would need their own set of codebuild project definitions as opposed to having a single template that can be deployed for either and cross referenced within the pipeline stack.
- docker load -i ${CODEBUILD_SRC_DIR_BuildArtifact}/${CONTAINER_IMAGE}.tar.gz | ||
- $(aws ecr get-login --registry-ids ${ECR_ACCT_ID} --no-include-email --region us-west-2) | ||
- IMG_VER=$(grep "DOGSWATCH_VERSION=" ${EXTRAS_DIR}/dogswatch/Makefile | sed 's:.*=::') | ||
- docker tag "${CONTAINER_IMAGE}":latest "${ECR_ACCT_ID}".dkr.ecr.us-west-2.amazonaws.com/"${CONTAINER_IMAGE}":"${IMG_VER}_${CODEBUILD_RESOLVED_SOURCE_VERSION}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll want to shorten the SHA at least, otherwise this tag will be very long and annoying to carry around in issues and discussion. I'm torn on wanting bare short-sha tagged images dogswatch:abcdef12
vs the version adorned dogswatch:v0.1.1-abcdef12
; I'm curious about what you think about this, what thoughts did you have that landed you on the adorned tag name?
nit: I've observed _
to be unconventional and uncommon to use when compared to -
in image tags.
- docker tag "${CONTAINER_IMAGE}":latest "${ECR_ACCT_ID}".dkr.ecr.us-west-2.amazonaws.com/"${CONTAINER_IMAGE}":"${IMG_VER}_${CODEBUILD_RESOLVED_SOURCE_VERSION}" | |
- docker tag "${CONTAINER_IMAGE}":latest "${ECR_ACCT_ID}".dkr.ecr.us-west-2.amazonaws.com/"${CONTAINER_IMAGE}":"${IMG_VER}-${CODEBUILD_RESOLVED_SOURCE_VERSION:0:8}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the idea was that we want release candidates in a Beta ECR repo before pushing to a prod ECR repository.
Since these containers are versioned, I thought it would make sense to tag them with the container version and the source commit SHA for clarity during the manual approval step (not part of this PR) when pushing out to the prod ECR repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the idea was that we want release candidates in a Beta ECR repo before pushing to a prod ECR repository.
To me, this suggests that the unadorned sha be chosen as, if used anywhere, is less likely to misrepresent its RC vs. !RC status as there's no version to misinterpret (as RC or release build, between which there hopefully wouldn't be a difference). The bare SHA suggests nothing more than a locked version aside from its nearest released tagged build.
Additionally, I think the unadorned would also aid the RC strategy in allowing a later optimization where a pre-build docker pull $registry/dogswatch:$CI_SHORT_SHA || :
can be run prior to the "release" build.
Since these containers are versioned, I thought it would make sense to tag them with the container version and the source commit SHA for clarity during the manual approval step (not part of this PR) when pushing out to the prod ECR repo.
I do see the benefit of being able to sight-read + spot-check the version being released, but I also think the chances of mucking up a SHA and releasing the wrong one isn't high - especially if we use clean room release environments (which I suspect is what will happen).
I am leaning towards the unadorned, bare short-sha as its still fully representative of the build at hand. Either way, I think we should copy in the VERSION
file to the container image to check versions without relying on running the container - a task for another time!
74e8bce
to
0e49e3d
Compare
Addresses a subset of @jahkeup 's comments. |
898f7ae
to
fbafc65
Compare
158bf1a
to
233dd73
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left my thoughts and feedback for these changes - there's some suggestions that are easy enough to change later if we end up wanting to and those should be quickly deferred in tracking issues to keep us moving on 👍
@@ -21,6 +21,11 @@ RUN cp bash /opt/bash | |||
|
|||
FROM amazonlinux:2 | |||
|
|||
ARG CTR_IMG_VER |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this naming may be confused to have something to do with containerd
(with its CLI called ctr
) and I think based on its usage here (which seems to be unused in the image) that a Image Label might be more appropriate for this use case. There are some pre-defined labels in the OCI image-spec, but I'm not 100% those are the labels we'd want to use exactly. I think we should start with those annotations (specifically org.opencontainers.image.version
for this case) and rework them later if we determine they're not appropriate for use here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. One last nit here: let's also update the remaining CTR_*
's - how about making them align with the label and simplify: IMAGE_VERSION
?
Type: String | ||
Default: amazonlinux | ||
AllowedPattern: "[A-Za-z0-9-]+" | ||
GitHubSecretToken: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't want this to make its way into the stacks because this ties the Pipeline to the user that sets it up (we'll want to use a robot if we stick with this) and because then credentials are having to be input and consumed in the clear (at some points, I do know they're stored "not in clear text").
-
Can we "stub" in the correct values and connect the "inputs" manually with the right approvals?
-
Does having the permissions already present in the account (ie: the oauth2 authorization flow has been performed already) obviate the need to provide Personal Access Tokens?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Can we "stub" in the correct values and connect the "inputs" manually with the right approvals?
I'm not sure if I understand. Can you elaborate on what to stub and what inputs to connect?
* Does having the permissions already present in the account (ie: the oauth2 authorization flow has been performed already) obviate the need to provide Personal Access Tokens?
No, to create the CodePipeline itself in CFN and have a github repository as a source, a AWS::CodePipeline::Webhook
is requried with GITHUB_HMAC
authentication which needs the personal access token. This differs from the manual CodePipeline github source set up which doesn't require the access token as it set up the webhook through some github web portal thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if I understand. Can you elaborate on what to stub and what inputs to connect?
Sure: for example, when testing stacks that want to hook up to the repository (for setting up Webhooks and such) I use another repository to initially set them up and then switch the repository to what I really want later (manually in the console).
This approach probably isn't maintainable and would cause all kinds of issues when these templates are regularly deployed automatically.
No, to create the CodePipeline itself in CFN and have a github repository as a source, a AWS::CodePipeline::Webhook is requried with GITHUB_HMAC authentication which needs the personal access token.
Oh, so it this a limitation of provisioning with CloudFormation specifically? I was able to use the oauth2 flow for setting up a pipeline - but that was with the console when we were feeling out the solution. I guess we'll want to get ourselves a bot user setup soon with the right permissions, that's kinda scary.. 👻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, so it this a limitation of provisioning with CloudFormation specifically? I was able to use the oauth2 flow for setting up a pipeline - but that was with the console when we were feeling out the solution. I guess we'll want to get ourselves a bot user setup soon with the right permissions, that's kinda scary.. ghost
Yup! I was pretty dismayed when I realized this as well.
- 'sns:*' | ||
- 'cloudformation:*' | ||
- 'ecs:*' | ||
Resource: '*' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The permissions granted should be limited to the related resources, such as: bucket(s), ASGs, ELBs, and the other services' resources.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I monitored the access advisor on this role, and none of these actions were ever invoked, so I'll go ahead and remove them
tools/infra/stacks/pipelines/dogswatch-container-pipeline-codebuild-projects.yml
Outdated
Show resolved
Hide resolved
tools/infra/stacks/pipelines/dogswatch-container-pipeline-codebuild-projects.yml
Outdated
Show resolved
Hide resolved
tools/infra/stacks/pipelines/dogswatch-container-pipeline-codebuild-projects.yml
Outdated
Show resolved
Hide resolved
tools/infra/stacks/pipelines/dogswatch-container-pipeline-codebuild-projects.yml
Outdated
Show resolved
Hide resolved
tools/infra/stacks/pipelines/host-container-pipeline-codebuild-projects.yml
Show resolved
Hide resolved
56786f9
to
c71dc25
Compare
97731d7
to
6185170
Compare
Addresses @jahkeup 's comments. |
As far as I can tell, this is ready to push over the line, minus a few things we should create issues for. @etungsten @jahkeup is there anything else outstanding? |
Modify dogswatch makefile `release-container` target to tag the dogswatch image with `latest` Adds buildspec for the build, test, deploy step in the host-container pipeline Adds a version file, `VERSION`, for admin and control container folders to keep track of container version. Moved host containers to new paths, add CTR_VER build arguments to `thar-admin` and `thar-control`
6185170
to
ab1c01d
Compare
@@ -21,6 +21,11 @@ RUN cp bash /opt/bash | |||
|
|||
FROM amazonlinux:2 | |||
|
|||
ARG CTR_IMG_VER |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. One last nit here: let's also update the remaining CTR_*
's - how about making them align with the label and simplify: IMAGE_VERSION
?
Service: | ||
- codepipeline.amazonaws.com | ||
Action: 'sts:AssumeRole' | ||
Path: / |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's place this under the stack's namespace:
Path: / | |
Path: !Sub "/${AWS::StackName}/" |
Service: | ||
- codepipeline.amazonaws.com | ||
Action: 'sts:AssumeRole' | ||
Path: / |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's place this under the stack's namespace:
Path: / | |
Path: !Sub "/${AWS::StackName}/" |
Effect: Allow | ||
Principal: | ||
Service: codebuild.amazonaws.com | ||
Path: / |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's place this under the stack's namespace:
Path: / | |
Path: !Sub "/${AWS::StackName}/" |
Effect: Allow | ||
Resource: | ||
- !GetAtt PipelineArtifactBucket.Arn | ||
- Fn::Join: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized I was being silly (where you copied this from) and fixed this in later revs of those other stacks, this can be a simpler !Sub
:
- Fn::Join: | |
- !Sub "${PipelineArtifactBucket.Arn}/*" |
# Path to infra tooling directory. | ||
INFRA_DIR: "./tools/infra" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be removed with the update to use the builder container.
files: | ||
- '*.tar.gz' | ||
secondary-artifacts: | ||
meta: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no config for gathering the "meta" secondary artifacts, you might want to drop this as I don't think we'll need it here for the present (the write-build-meta
command can be removed too).
- . "${INFRA_DIR}/env/lib/environment-setup" | ||
pre_build: | ||
commands: | ||
- write-build-meta |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the artifact comment below, I think this should be removed and have environment-report
in its place - that'll print the details of the docker versions used and such that may be helpful when later debugging.
ServiceRole: !GetAtt BuildRole.Arn | ||
Source: | ||
BuildSpec: | | ||
version: 0.2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd make similar edits as the other build specs here.
PrivilegedMode: true | ||
Type: LINUX_CONTAINER | ||
EnvironmentVariables: | ||
- Name: 'ECR_ACCT_ID' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The builder container has amazon-ecr-credential-helper
setup in it, so there shouldn't be need to reference the Account ID directly, instead the script can simply:
docker build -t $ECR_IMAGE_REPOSITORY:$TAG ...
docker push $ECR_IMAGE_REPOSITORY:$TAG
ab1c01d
to
be1e515
Compare
Addresses @jahkeup 's comments |
be1e515
to
3918d2d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a couple things that we can come back and fixup later, but one question that may or may not need fixing - until then, let's get container images movin' :D
tools/infra/stacks/pipelines/dogswatch-container-pipeline-codebuild-projects.yml
Outdated
Show resolved
Hide resolved
- mkdir -p "${IMAGES_DIR}" | ||
build: | ||
commands: | ||
- SHORT_SHA="$(head -c 8 <<< "$CODEBUILD_RESOLVED_SOURCE_VERSION")" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot, did this end up working inside of the container without switching over to bash?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it works now that we're in the build container, nothing else necessary. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a quick run to figure out why, I didn't confirm this exactly, but my guess is that whatever the /bin/sh executable was (emulating or otherwise) not backed by bash - the builder environment's /bin/sh is emulated by bash. I think the emulation isn't fully insulated from the bash side and permits this despite it not being a feature of sh (I think?).
3918d2d
to
4391913
Compare
Breaks out the Codebuild projects for the codepipeline steps in a separate CloudFormation stacks that output references. Use those references in the CodePipeline stacks. Deletes the buildspec files as they are now inline in the CloudFormation template
4391913
to
e571695
Compare
Fixed an issue in the policy where the resources were not being specified correctly, tested and pipeline kick-off correctly again. |
Issue #, if available: Fixes #514
Fixes #465
Description of changes:
Creates a host-container pipeline:
One for the
thar-admin
container, one for thethar-control
container, one for thedogswatch
container.dogswatch
Makefilerelease-container
target to tag the dogswatch image withlatest
tagVERSION
, for admin and control container folders to keep track of container version.CTR_VER
build arguments tothar-admin
andthar-control
Dockerfiles to set up version env var.Testing:
Created CloudFormation stacks successfully using
host-container-piplines.yml
.The pipelines are invoked correctly by pushing changes to the
container-version
file forthar-admin
andthar-control
as well as theMakefile
fordogswatch
(since that's where thedogswatch
version lives)The resultant images are pushed to external ECR image repositories tagged with their version + the git commit ID
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.