1- ---
2- # Kics linting thinks that the "password" and "github_access_token" keys are secrets, but they are not.
3- # These instances are ignored appropriately.
1+ resource_types :
2+ - name : key-value
3+ type : registry-image
4+ source :
5+ repository : gstack/keyval-resource
46
57resources :
68 - name : resource-repo
@@ -9,76 +11,298 @@ resources:
911 source :
1012 uri : https://github.com/ONS-Innovation/github-copilot-usage-lambda
1113 username : ((github_access_token))
12- # kics-scan ignore-line
1314 password : x-oauth-basic # checkov:skip=CKV_SECRET_6:Checkov thinks this is a secret, but it is not
1415 branch : ((branch))
16+ - name : github-release
17+ type : github-release
18+ source :
19+ owner : ONS-Innovation
20+ repository : github-copilot-usage-lambda
21+ access_token : ((github_access_token))
22+ - name : github-release-tag
23+ type : key-value
24+ source :
25+ file : tag-output/tag
26+
27+ # TODO: Setup shared ECR for Address Book Lambda. Sample below for reference.
28+
29+ # - name: images-to-shared-ecr-backend
30+ # type: registry-image
31+ # source:
32+ # repository: github-copilot-usage-lambda
33+ # aws_role_arn: arn:aws:iam::((aws_account_sdp_((env)))):role/sdp-concourse-((env))
34+ # aws_account_id: ((aws_account_ecr_shared_account))
35+ # aws_region: eu-west-2
36+
37+ # Define the common terraform task as an anchor
38+ terraform-task : &terraform-task
39+ task : terraform-deploy
40+ privileged : true
41+ config :
42+ platform : linux
43+ image_resource :
44+ type : docker-image
45+ source :
46+ repository : hashicorp/terraform
47+ inputs :
48+ - name : resource-repo
49+ - name : github-release-tag
50+ params :
51+ secrets : ((sdp_((env))_copilot_usage_lambda_secrets))
52+ github_access_token : ((github_access_token))
53+ env : ((env))
54+ branch : ((branch))
55+ run :
56+ path : sh
57+ args :
58+ - -cx
59+ - |
60+ echo "DEBUG: Environment is ${env}"
61+ echo "DEBUG: Tag is ${tag}"
62+ export tag=$(cat github-release-tag/tag)
63+ if [[ "$env" == "prod" ]] && [[ "$branch" != "main" && "$branch" != "master" ]]; then
64+ echo "Not on main branch, skipping terraform for prod."
65+ exit 0
66+ fi
67+ apk add --no-cache jq curl
68+ if [[ "$env" == "prod" && ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
69+ echo "ERROR: Tag '$tag' is not in semantic versioning format (vX.Y.Z)"
70+ exit 1
71+ fi
72+ chmod u+x ./resource-repo/concourse/scripts/terraform_infra.sh
73+ ./resource-repo/concourse/scripts/terraform_infra.sh
74+ timeout : 30m
75+
76+ notify-azure-webhook-task : ¬ify-azure-webhook-task
77+ config :
78+ platform : linux
79+ params :
80+ secrets : ((sdp_azure_webhook_secrets))
81+ branch : ((branch))
82+ env : ((env))
83+ image_resource :
84+ type : registry-image
85+ source :
86+ repository : alpine
87+ tag : latest
88+ run :
89+ path : sh
90+ args :
91+ - -euc
92+ - |
93+ if [ "$branch" != "main" ]; then
94+ echo "Branch is '${branch}', skipping webhook notification."
95+ exit 0
96+ fi
97+ apk add --no-cache curl jq
98+
99+ AZURE_CLIENT_ID=$(echo "$secrets" | jq -r .azure_client_id)
100+ AZURE_CLIENT_SECRET=$(echo "$secrets" | jq -r .azure_client_secret)
101+ AZURE_SCOPE=$(echo "$secrets" | jq -r .azure_scope)
102+ AZURE_TENANT_ID=$(echo "$secrets" | jq -r .azure_tenant_id)
103+ AZURE_WEBHOOK_URL=$(echo "$secrets" | jq -r .azure_webhook_url)
104+ CHANNEL_ID=$(echo "$secrets" | jq -r .channel_id)
105+
106+ token_json="$(curl -sS -X POST \
107+ "https://login.microsoftonline.com/${AZURE_TENANT_ID}/oauth2/v2.0/token" \
108+ -H "Content-Type: application/x-www-form-urlencoded" \
109+ --data-urlencode "client_id=${AZURE_CLIENT_ID}" \
110+ --data-urlencode "client_secret=${AZURE_CLIENT_SECRET}" \
111+ --data-urlencode "grant_type=client_credentials" \
112+ --data-urlencode "scope=${AZURE_SCOPE}")"
113+
114+ access_token="$(printf '%s' "$token_json" | sed -n 's/.*"access_token":"\([^"]*\)".*/\1/p')"
115+ if [ -z "$access_token" ]; then
116+ echo "Failed to get access token. Response:"
117+ echo "$token_json"
118+ exit 1
119+ fi
120+
121+ msg="status:🚨 Concourse failure<br>service: Copilot Usage Lambda<br> event: Pipeline failure in the ${env} environment."
122+
123+ payload="$(cat <<JSON
124+ {"channel":"${CHANNEL_ID}","message":"${msg}"}
125+ JSON
126+ )"
127+
128+ curl -sS -X POST "$AZURE_WEBHOOK_URL" \
129+ -H "Authorization: Bearer ${access_token}" \
130+ -H "Content-Type: application/json" \
131+ -d "$payload"
15132
16133jobs :
17- - name : build-and-push
134+ - name : calculate-tag
18135 public : true
19136 plan :
137+ - get : github-release
138+ trigger : true
20139 - get : resource-repo
21- timeout : 5m
22- - task : build-image
23- privileged : true
140+ trigger : false
141+ - task : calculate-tag
24142 config :
25143 platform : linux
26144 image_resource :
27145 type : docker-image
28146 source :
29- repository : hashicorp/terraform
147+ repository : alpine
30148 inputs :
31149 - name : resource-repo
150+ - name : github-release
151+ outputs :
152+ - name : tag-output # Output directory for the tag
153+ - name : built-images # Output directory for built images
32154 params :
33- aws_account_id : ((aws_account_sdp_((env))))
34- aws_role_arn : arn:aws:iam::((aws_account_sdp_((env)))):role/sdp-concourse-((env))
35- secrets : ((sdp_((env))_github_copilot_secrets))
36- run : # binary used to build the image
37- path : sh
38- args :
39- - -cx
40- - |
41- apk add --no-cache aws-cli podman jq iptables curl
42-
43- if [[ "((env))" == "prod" ]]; then
44- tag=$(curl "https://api.github.com/repos/ONS-Innovation/github-copilot-usage-lambda/releases" | jq -r '.[0].tag_name')
45- export tag
46- else
47- export tag=((tag))
48- fi
49- git rev-parse --abbrev-ref HEAD
50- chmod u+x ./resource-repo/concourse/scripts/assume_role.sh
51- chmod u+x ./resource-repo/concourse/scripts/build_image.sh
52- source ./resource-repo/concourse/scripts/assume_role.sh
53- ./resource-repo/concourse/scripts/build_image.sh
54- timeout : 10m
55- - task : terraform
56- privileged : true
57- config :
58- platform : linux
59- image_resource :
60- type : docker-image
61- source : { repository: hashicorp/terraform }
62- inputs :
63- - name : resource-repo
64- params :
65- secrets : ((sdp_((env))_github_copilot_secrets))
66- # kics-scan ignore-line
67- github_access_token : ((github_access_token))
155+ branch : ((branch))
68156 run :
69157 path : sh
70158 args :
71159 - -cx
72160 - |
73- apk add --no-cache jq curl
74-
75- if [[ "((env))" == "prod" ]]; then
76- tag=$(curl "https://api.github.com/repos/ONS-Innovation/github-copilot-usage-lambda/releases" | jq -r '.[0].tag_name')
77- export tag
161+ apk add --no-cache git
162+ echo "Calculating tag for branch: ${branch}"
163+ if [[ "$branch" == "main" || "$branch" == "master" ]]; then
164+ # Get the latest tag that matches the format vX.Y.Z
165+ tag=$(git -C resource-repo tag --list 'v[0-9]*.[0-9]*.[0-9]*' | sort -V | tail -n 1)
166+ if [[ -z "$tag" ]]; then
167+ echo "No valid semantic versioning tags (vX.Y.Z) found. Cannot set pipeline."
168+ exit 1
169+ fi
78170 else
79- export tag=((tag))
171+ # Remove non-alphanumeric characters and take the first 7 characters
172+ tag=$(echo "${branch}" | tr -cd '[:alnum:]' | cut -c1-7)
80173 fi
81- chmod u+x ./resource-repo/concourse/scripts/terraform_infra.sh
82- export env=((env))
83- ./resource-repo/concourse/scripts/terraform_infra.sh
84- timeout : 30m
174+ echo "Calculated tag: ${tag}"
175+ # Write the tag to a file for output
176+ echo "${tag}" > tag-output/tag
177+ - put : github-release-tag
178+ params :
179+ directory : tag-output
180+
181+ - name : deploy-after-github-release-dev
182+ public : true
183+ plan :
184+ - do :
185+ - get : github-release-tag
186+ passed : [calculate-tag]
187+ trigger : true
188+ - get : resource-repo
189+ trigger : false
190+ - task : deploy-release
191+ privileged : true
192+ config :
193+ platform : linux
194+ image_resource :
195+ type : docker-image
196+ source :
197+ repository : hashicorp/terraform
198+ inputs :
199+ - name : resource-repo
200+ - name : github-release-tag
201+ outputs :
202+ - name : built-images
203+ - name : release-tag-output
204+ params :
205+ aws_account_id : ((aws_account_sdp_dev))
206+ aws_role_arn : arn:aws:iam::((aws_account_sdp_dev)):role/sdp-concourse-dev
207+ secrets : ((sdp_dev_copilot_usage_lambda_secrets))
208+ env : dev
209+ tag : github-release-tag/tag # Use the release tag from the resource
210+ repo_name : ((repo_name))
211+ run :
212+ path : sh
213+ args :
214+ - -cx
215+ - |
216+ apk add --no-cache aws-cli podman jq iptables curl
217+ export repo_name=((repo_name))
218+ export tag=$(cat github-release-tag/tag)
219+ # Write the tag to a file for output
220+ echo "${tag}" > release-tag-output/tag
221+ echo "Using tag: ${tag}"
222+ chmod u+x ./resource-repo/concourse/scripts/assume_role.sh
223+ chmod u+x ./resource-repo/concourse/scripts/build_image.sh
224+ source ./resource-repo/concourse/scripts/assume_role.sh
225+ ./resource-repo/concourse/scripts/build_image.sh
226+ timeout : 15m
227+
228+ # TODO: Setup shared ECR for Address Book Lambda. Sample below for reference.
229+ # - in_parallel:
230+ # - put: image-to-shared-ecr
231+ # inputs:
232+ # - built-images
233+ # - release-tag-output
234+ # params:
235+ # image: built-images/frontend.tar
236+ # additional_tags: release-tag-output/tag
237+ - << : *terraform-task
238+ params :
239+ github_access_token : ((github_access_token))
240+ env : dev
241+ secrets : ((sdp_dev_copilot_usage_lambda_secrets))
242+ on_failure :
243+ do :
244+ - task : notify-azure-webhook
245+ << : *notify-azure-webhook-task
246+ params :
247+ env : dev
248+
249+ - name : release-build-and-push-prod
250+ public : true
251+ plan :
252+ - do :
253+ - get : resource-repo
254+ passed : [deploy-after-github-release-dev]
255+ trigger : false # Manual trigger only
256+ timeout : 5m
257+ - get : github-release-tag
258+ passed : [deploy-after-github-release-dev]
259+ - task : build-image
260+ privileged : true
261+ config :
262+ platform : linux
263+ image_resource :
264+ type : docker-image
265+ source :
266+ repository : hashicorp/terraform
267+ inputs :
268+ - name : resource-repo
269+ - name : github-release-tag
270+ outputs :
271+ - name : built-images
272+ params :
273+ aws_account_id : ((aws_account_sdp_prod))
274+ aws_role_arn : arn:aws:iam::((aws_account_sdp_prod)):role/sdp-concourse-prod
275+ secrets : ((sdp_prod_copilot_usage_lambda_secrets))
276+ env : prod
277+ tag : github-release-tag/tag
278+ repo_name : ((repo_name))
279+ branch : ((branch))
280+ run :
281+ path : sh
282+ args :
283+ - -cx
284+ - |
285+ if [[ "$branch" != "main" ]]; then
286+ echo "Not on main branch, skipping build."
287+ exit 0
288+ fi
289+ apk add --no-cache aws-cli podman jq iptables curl
290+ export repo_name=((repo_name))
291+ export tag=$(cat github-release-tag/tag)
292+ echo "Using release tag: ${tag}"
293+ chmod u+x ./resource-repo/concourse/scripts/assume_role.sh
294+ chmod u+x ./resource-repo/concourse/scripts/build_image.sh
295+ source ./resource-repo/concourse/scripts/assume_role.sh
296+ ./resource-repo/concourse/scripts/build_image.sh
297+ timeout : 10m
298+ - << : *terraform-task
299+ params :
300+ github_access_token : ((github_access_token))
301+ env : prod
302+ secrets : ((sdp_prod_copilot_usage_lambda_secrets))
303+ on_failure :
304+ do :
305+ - task : notify-azure-webhook
306+ << : *notify-azure-webhook-task
307+ params :
308+ env : prod
0 commit comments