From 85944c29803bc57169e99f22319a08f324ad0e1c Mon Sep 17 00:00:00 2001 From: Doug Stull Date: Mon, 24 Feb 2020 16:57:51 -0500 Subject: [PATCH 01/43] Add permission check to pipeline tour - only initiate the tour entry point based on if this feature exists and if user has proper permissions. --- app/serializers/merge_request_widget_entity.rb | 2 ++ spec/serializers/merge_request_widget_entity_spec.rb | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/app/serializers/merge_request_widget_entity.rb b/app/serializers/merge_request_widget_entity.rb index c48e60064ed60f..79d9dbefa85c70 100644 --- a/app/serializers/merge_request_widget_entity.rb +++ b/app/serializers/merge_request_widget_entity.rb @@ -94,6 +94,8 @@ def can_add_ci_config_path?(merge_request) merge_request.source_project&.uses_default_ci_config? && merge_request.all_pipelines.none? && merge_request.commits_count.positive? && + can?(current_user, :read_build, merge_request.source_project) && + can?(current_user, :create_pipeline, merge_request.source_project) && can?(current_user, :push_code, merge_request.source_project) end end diff --git a/spec/serializers/merge_request_widget_entity_spec.rb b/spec/serializers/merge_request_widget_entity_spec.rb index 597dae81cfb10c..05a45397103819 100644 --- a/spec/serializers/merge_request_widget_entity_spec.rb +++ b/spec/serializers/merge_request_widget_entity_spec.rb @@ -123,6 +123,16 @@ expect(subject[:merge_request_add_ci_config_path]).not_to be_nil end end + + context 'when feature is disabled' do + before do + project.project_feature.update(repository_access_level: ProjectFeature::DISABLED) + end + + it 'has no path' do + expect(subject[:merge_request_add_ci_config_path]).to be_nil + end + end end context 'when user does not have permissions' do -- GitLab From 7bd72c9403155766a40bdace9e3128e0adea521d Mon Sep 17 00:00:00 2001 From: Doug Stull Date: Wed, 26 Feb 2020 08:36:46 -0500 Subject: [PATCH 02/43] Improve tests for ci config path permission checks - needed to qualify the spec --- app/serializers/merge_request_widget_entity.rb | 3 +-- .../merge_request_widget_entity_spec.rb | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/serializers/merge_request_widget_entity.rb b/app/serializers/merge_request_widget_entity.rb index 79d9dbefa85c70..6df26de529de5e 100644 --- a/app/serializers/merge_request_widget_entity.rb +++ b/app/serializers/merge_request_widget_entity.rb @@ -95,8 +95,7 @@ def can_add_ci_config_path?(merge_request) merge_request.all_pipelines.none? && merge_request.commits_count.positive? && can?(current_user, :read_build, merge_request.source_project) && - can?(current_user, :create_pipeline, merge_request.source_project) && - can?(current_user, :push_code, merge_request.source_project) + can?(current_user, :create_pipeline, merge_request.source_project) end end diff --git a/spec/serializers/merge_request_widget_entity_spec.rb b/spec/serializers/merge_request_widget_entity_spec.rb index 05a45397103819..beb6a0de0f6ba0 100644 --- a/spec/serializers/merge_request_widget_entity_spec.rb +++ b/spec/serializers/merge_request_widget_entity_spec.rb @@ -124,9 +124,19 @@ end end - context 'when feature is disabled' do + context 'when build feature is disabled' do before do - project.project_feature.update(repository_access_level: ProjectFeature::DISABLED) + project.project_feature.update(builds_access_level: ProjectFeature::DISABLED) + end + + it 'has no path' do + expect(subject[:merge_request_add_ci_config_path]).to be_nil + end + end + + context 'when creating the pipeline is not allowed' do + before do + user.state = 'blocked' end it 'has no path' do -- GitLab From 49ba3c9be889c02c487ffe8a73d9114b407b313b Mon Sep 17 00:00:00 2001 From: Corinna Wiesner Date: Mon, 17 Feb 2020 10:07:12 +0100 Subject: [PATCH 03/43] Remove admin user count from Users statistics Avoid confusion of the statistics counts due to admin users also being listed in the numbers for Users with highest role statistics. --- ee/app/controllers/ee/admin/dashboard_controller.rb | 1 - ee/app/views/admin/dashboard/stats.html.haml | 6 ------ .../unreleased/remove_admin_count_from_users_statistics.yml | 5 +++++ ee/spec/features/admin/admin_dashboard_spec.rb | 1 - 4 files changed, 5 insertions(+), 8 deletions(-) create mode 100644 ee/changelogs/unreleased/remove_admin_count_from_users_statistics.yml diff --git a/ee/app/controllers/ee/admin/dashboard_controller.rb b/ee/app/controllers/ee/admin/dashboard_controller.rb index 5ac223f80743c0..77d2bf9333f96d 100644 --- a/ee/app/controllers/ee/admin/dashboard_controller.rb +++ b/ee/app/controllers/ee/admin/dashboard_controller.rb @@ -17,7 +17,6 @@ def index end def stats - @admin_count = ::User.admins.count @roles_count = ::ProjectAuthorization.roles_stats end diff --git a/ee/app/views/admin/dashboard/stats.html.haml b/ee/app/views/admin/dashboard/stats.html.haml index 3f9abfdb02ff08..96c37ec53198a5 100644 --- a/ee/app/views/admin/dashboard/stats.html.haml +++ b/ee/app/views/admin/dashboard/stats.html.haml @@ -7,12 +7,6 @@ %td = User.count - - if @admin_count - %tr - %td Admin users - %td - = @admin_count - - if @roles_count - @roles_count.each do |row| %tr diff --git a/ee/changelogs/unreleased/remove_admin_count_from_users_statistics.yml b/ee/changelogs/unreleased/remove_admin_count_from_users_statistics.yml new file mode 100644 index 00000000000000..94defa6bd652d2 --- /dev/null +++ b/ee/changelogs/unreleased/remove_admin_count_from_users_statistics.yml @@ -0,0 +1,5 @@ +--- +title: Remove admin user count from Users statistics +merge_request: 25337 +author: +type: changed diff --git a/ee/spec/features/admin/admin_dashboard_spec.rb b/ee/spec/features/admin/admin_dashboard_spec.rb index f7dc5917f279ee..492fe3c5de5505 100644 --- a/ee/spec/features/admin/admin_dashboard_spec.rb +++ b/ee/spec/features/admin/admin_dashboard_spec.rb @@ -24,7 +24,6 @@ it 'show correct amount of users per role' do visit admin_dashboard_stats_path - expect(page).to have_content('Admin users 1') expect(page).to have_content('Users with highest role developer 2') expect(page).to have_content('Users with highest role reporter 1') end -- GitLab From 0b05a6750973da6188e7da30dcc2b7a5c0be0104 Mon Sep 17 00:00:00 2001 From: Alishan Ladhani Date: Mon, 13 Jan 2020 16:31:22 -0500 Subject: [PATCH 04/43] Update cluster applications API to support serverless domains - Serialize available domains and currently associated domain when presenting Knative - When Knative is updated, create an association to the newly selected domain --- app/models/clusters/applications/knative.rb | 10 ++ app/serializers/cluster_application_entity.rb | 2 + app/serializers/serverless/domain_entity.rb | 8 ++ .../clusters/applications/base_service.rb | 6 ++ .../serverless/associate_domain_service.rb | 32 +++++++ spec/fixtures/api/schemas/cluster_status.json | 10 +- .../clusters/applications/knative_spec.rb | 30 ++++++ .../cluster_application_entity_spec.rb | 18 ++++ .../serverless/domain_entity_spec.rb | 19 ++++ .../applications/create_service_spec.rb | 20 +++- .../applications/update_service_spec.rb | 21 ++++- .../associate_domain_service_spec.rb | 92 +++++++++++++++++++ 12 files changed, 264 insertions(+), 4 deletions(-) create mode 100644 app/serializers/serverless/domain_entity.rb create mode 100644 app/services/serverless/associate_domain_service.rb create mode 100644 spec/serializers/serverless/domain_entity_spec.rb create mode 100644 spec/services/serverless/associate_domain_service_spec.rb diff --git a/app/models/clusters/applications/knative.rb b/app/models/clusters/applications/knative.rb index eebcbcba2d3949..b598be817c70bd 100644 --- a/app/models/clusters/applications/knative.rb +++ b/app/models/clusters/applications/knative.rb @@ -41,6 +41,8 @@ def set_initial_status scope :for_cluster, -> (cluster) { where(cluster: cluster) } + has_one :pages_domain, through: :serverless_domain_cluster + def chart 'knative/knative' end @@ -49,6 +51,14 @@ def values { "domain" => hostname }.to_yaml end + def available_domains + PagesDomain.instance_serverless + end + + def find_available_domain(pages_domain_id) + available_domains.find_by(id: pages_domain_id) + end + def allowed_to_uninstall? !pre_installed? end diff --git a/app/serializers/cluster_application_entity.rb b/app/serializers/cluster_application_entity.rb index 632718df780b3b..ac59a9df9e56b5 100644 --- a/app/serializers/cluster_application_entity.rb +++ b/app/serializers/cluster_application_entity.rb @@ -13,4 +13,6 @@ class ClusterApplicationEntity < Grape::Entity expose :modsecurity_enabled, if: -> (e, _) { e.respond_to?(:modsecurity_enabled) } expose :update_available?, as: :update_available, if: -> (e, _) { e.respond_to?(:update_available?) } expose :can_uninstall?, as: :can_uninstall + expose :available_domains, using: Serverless::DomainEntity, if: -> (e, _) { e.respond_to?(:available_domains) } + expose :pages_domain, using: Serverless::DomainEntity, if: -> (e, _) { e.respond_to?(:pages_domain) } end diff --git a/app/serializers/serverless/domain_entity.rb b/app/serializers/serverless/domain_entity.rb new file mode 100644 index 00000000000000..556e3c99eee244 --- /dev/null +++ b/app/serializers/serverless/domain_entity.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Serverless + class DomainEntity < Grape::Entity + expose :id + expose :domain + end +end diff --git a/app/services/clusters/applications/base_service.rb b/app/services/clusters/applications/base_service.rb index 2585d815e073d8..a3b39f0994d4ee 100644 --- a/app/services/clusters/applications/base_service.rb +++ b/app/services/clusters/applications/base_service.rb @@ -35,6 +35,12 @@ def execute(request) application.oauth_application = create_oauth_application(application, request) end + if application.instance_of?(Knative) + Serverless::AssociateDomainService + .new(application, pages_domain_id: params[:pages_domain_id], creator: current_user) + .execute + end + worker = worker_class(application) application.make_scheduled! diff --git a/app/services/serverless/associate_domain_service.rb b/app/services/serverless/associate_domain_service.rb new file mode 100644 index 00000000000000..dcca73802dd90a --- /dev/null +++ b/app/services/serverless/associate_domain_service.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Serverless + class AssociateDomainService + PLACEHOLDER_HOSTNAME = 'example.com'.freeze + + def initialize(knative, pages_domain_id:, creator:) + @knative = knative + @pages_domain_id = pages_domain_id + @creator = creator + end + + def execute + return if unchanged? + + knative.hostname ||= PLACEHOLDER_HOSTNAME + + knative.pages_domain = knative.find_available_domain(pages_domain_id) + knative.serverless_domain_cluster.update(creator: creator) if knative.pages_domain + + ClusterConfigureIstioWorker.perform_async(knative.cluster_id) + end + + private + + attr_reader :knative, :pages_domain_id, :creator + + def unchanged? + knative.pages_domain&.id == pages_domain_id + end + end +end diff --git a/spec/fixtures/api/schemas/cluster_status.json b/spec/fixtures/api/schemas/cluster_status.json index 29c56b5c820d4d..6017ca9e2d532c 100644 --- a/spec/fixtures/api/schemas/cluster_status.json +++ b/spec/fixtures/api/schemas/cluster_status.json @@ -39,9 +39,15 @@ "stack": { "type": ["string", "null"] }, "modsecurity_enabled": { "type": ["boolean", "null"] }, "update_available": { "type": ["boolean", "null"] }, - "can_uninstall": { "type": "boolean" } + "can_uninstall": { "type": "boolean" }, + "available_domains": { + "type": "array", + "items": { "$ref": "#/definitions/domain" } + }, + "pages_domain": { "type": [ { "$ref": "#/definitions/domain" }, "null"] } }, "required" : [ "name", "status" ] - } + }, + "domain": { "id": "integer", "domain": "string" } } } diff --git a/spec/models/clusters/applications/knative_spec.rb b/spec/models/clusters/applications/knative_spec.rb index 993cc7d0203d62..61626af3284799 100644 --- a/spec/models/clusters/applications/knative_spec.rb +++ b/spec/models/clusters/applications/knative_spec.rb @@ -196,4 +196,34 @@ describe 'validations' do it { is_expected.to validate_presence_of(:hostname) } end + + describe '#available_domains' do + let!(:domain) { create(:pages_domain, :instance_serverless) } + + it 'returns all instance serverless domains' do + expect(PagesDomain).to receive(:instance_serverless).and_call_original + + domains = subject.available_domains + + expect(domains.length).to eq(1) + expect(domains).to include(domain) + end + end + + describe '#find_available_domain' do + let!(:domain) { create(:pages_domain, :instance_serverless) } + + it 'returns the domain scoped to available domains' do + expect(subject).to receive(:available_domains).and_call_original + expect(subject.find_available_domain(domain.id)).to eq(domain) + end + end + + describe '#pages_domain' do + let!(:sdc) { create(:serverless_domain_cluster, knative: knative) } + + it 'returns the the associated pages domain' do + expect(knative.reload.pages_domain).to eq(sdc.pages_domain) + end + end end diff --git a/spec/serializers/cluster_application_entity_spec.rb b/spec/serializers/cluster_application_entity_spec.rb index c700c150461c63..873fbf812ccfdc 100644 --- a/spec/serializers/cluster_application_entity_spec.rb +++ b/spec/serializers/cluster_application_entity_spec.rb @@ -59,5 +59,23 @@ expect(subject[:external_ip]).to eq('111.222.111.222') end end + + context 'for knative application' do + let(:pages_domain) { create(:pages_domain, :instance_serverless) } + let(:application) { build(:clusters_applications_knative, :installed) } + + before do + create(:serverless_domain_cluster, knative: application, pages_domain: pages_domain) + end + + it 'includes available domains' do + expect(subject[:available_domains].length).to eq(1) + expect(subject[:available_domains].first).to eq(id: pages_domain.id, domain: pages_domain.domain) + end + + it 'includes pages_domain' do + expect(subject[:pages_domain]).to eq(id: pages_domain.id, domain: pages_domain.domain) + end + end end end diff --git a/spec/serializers/serverless/domain_entity_spec.rb b/spec/serializers/serverless/domain_entity_spec.rb new file mode 100644 index 00000000000000..bdf0ccb176c1e1 --- /dev/null +++ b/spec/serializers/serverless/domain_entity_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Serverless::DomainEntity do + describe '#as_json' do + let(:domain) { create(:pages_domain, :instance_serverless) } + + subject { described_class.new(domain).as_json } + + it 'has an id' do + expect(subject[:id]).to eq(domain.id) + end + + it 'has a domain' do + expect(subject[:domain]).to eq(domain.domain) + end + end +end diff --git a/spec/services/clusters/applications/create_service_spec.rb b/spec/services/clusters/applications/create_service_spec.rb index f62af86f1bf179..0b48af408e1da1 100644 --- a/spec/services/clusters/applications/create_service_spec.rb +++ b/spec/services/clusters/applications/create_service_spec.rb @@ -137,10 +137,14 @@ let(:params) do { application: 'knative', - hostname: 'example.com' + hostname: 'example.com', + pages_domain_id: domain.id } end + let(:domain) { create(:pages_domain, :instance_serverless) } + let(:associate_domain_service) { double('AssociateDomainService') } + before do expect_any_instance_of(Clusters::Applications::Knative) .to receive(:make_scheduled!) @@ -158,6 +162,20 @@ it 'sets the hostname' do expect(subject.hostname).to eq('example.com') end + + it 'executes AssociateDomainService' do + expect(Serverless::AssociateDomainService).to receive(:new) do |knative, args| + expect(knative).to be_a(Clusters::Applications::Knative) + expect(args[:pages_domain_id]).to eq(params[:pages_domain_id]) + expect(args[:creator]).to eq(user) + + associate_domain_service + end + + expect(associate_domain_service).to receive(:execute) + + subject + end end context 'elastic stack application' do diff --git a/spec/services/clusters/applications/update_service_spec.rb b/spec/services/clusters/applications/update_service_spec.rb index 2d299882af0f4a..4676951faff123 100644 --- a/spec/services/clusters/applications/update_service_spec.rb +++ b/spec/services/clusters/applications/update_service_spec.rb @@ -7,8 +7,9 @@ let(:cluster) { create(:cluster, :project, :provided_by_gcp) } let(:user) { create(:user) } - let(:params) { { application: 'knative', hostname: 'udpate.example.com' } } + let(:params) { { application: 'knative', hostname: 'update.example.com', pages_domain_id: domain.id } } let(:service) { described_class.new(cluster, user, params) } + let(:domain) { create(:pages_domain, :instance_serverless) } subject { service.execute(test_request) } @@ -51,6 +52,24 @@ subject end + + context 'knative application' do + let(:associate_domain_service) { double('AssociateDomainService') } + + it 'executes AssociateDomainService' do + expect(Serverless::AssociateDomainService).to receive(:new) do |knative, args| + expect(knative.id).to eq(application.id) + expect(args[:pages_domain_id]).to eq(params[:pages_domain_id]) + expect(args[:creator]).to eq(user) + + associate_domain_service + end + + expect(associate_domain_service).to receive(:execute) + + subject + end + end end context 'application is not schedulable' do diff --git a/spec/services/serverless/associate_domain_service_spec.rb b/spec/services/serverless/associate_domain_service_spec.rb new file mode 100644 index 00000000000000..b73857690c2c51 --- /dev/null +++ b/spec/services/serverless/associate_domain_service_spec.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Serverless::AssociateDomainService do + subject { described_class.new(knative, pages_domain_id: pages_domain_id, creator: creator) } + + let(:sdc) { create(:serverless_domain_cluster, pages_domain: create(:pages_domain, :instance_serverless)) } + let(:knative) { sdc.knative } + let(:creator) { sdc.creator } + let(:pages_domain_id) { sdc.pages_domain_id } + + context 'when the domain is unchanged' do + let(:creator) { create(:user) } + + it 'does not schedule a ClusterConfigureIstioWorker' do + expect(ClusterConfigureIstioWorker).not_to receive(:perform_async) + + subject.execute + end + + it 'does not update creator' do + expect { subject.execute }.not_to change { sdc.reload.creator } + end + end + + context 'when domain is changed to nil' do + let(:pages_domain_id) { nil } + let(:creator) { create(:user) } + + it 'removes the association between knative and the domain' do + expect { subject.execute }.to change { knative.reload.pages_domain }.from(sdc.pages_domain).to(nil) + end + + it 'does not attempt to update creator' do + expect { subject.execute }.not_to raise_error + end + + it 'schedules a ClusterConfigureIstioWorker for the cluster' do + expect(ClusterConfigureIstioWorker).to receive(:perform_async).with(knative.cluster_id) + + subject.execute + end + end + + context 'when a new domain is associated' do + let(:pages_domain_id) { create(:pages_domain, :instance_serverless).id } + let(:creator) { create(:user) } + + it 'creates an association with the domain' do + expect { subject.execute }.to change { knative.pages_domain.id }.from(sdc.pages_domain.id).to(pages_domain_id) + end + + it 'schedules a ClusterConfigureIstioWorker for the cluster' do + expect(ClusterConfigureIstioWorker).to receive(:perform_async).with(knative.cluster_id) + + subject.execute + end + + it 'updates creator' do + expect { subject.execute }.to change { sdc.reload.creator }.from(sdc.creator).to(creator) + end + end + + context 'when knative is not authorized to use the pages domain' do + let(:pages_domain_id) { create(:pages_domain).id } + + before do + expect(knative).to receive(:available_domains).and_return(PagesDomain.none) + end + + it 'sets pages_domain_id to nil' do + expect { subject.execute }.to change { knative.reload.pages_domain }.from(sdc.pages_domain).to(nil) + end + end + + context 'when knative hostname is nil' do + let(:knative) { build(:clusters_applications_knative, hostname: nil) } + + it 'sets hostname to a placeholder value' do + expect { subject.execute }.to change { knative.hostname }.to('example.com') + end + end + + context 'when knative hostname exists' do + let(:knative) { build(:clusters_applications_knative, hostname: 'hostname.com') } + + it 'does not change hostname' do + expect { subject.execute }.not_to change { knative.hostname } + end + end +end -- GitLab From c9fd7c67aabea3277d97d5e0941c7afa62b043b2 Mon Sep 17 00:00:00 2001 From: Alishan Ladhani Date: Tue, 25 Feb 2020 17:21:46 -0500 Subject: [PATCH 05/43] Refactor scheduling of ClusterConfigureIstioWorker Move scheduling of the worker out of BaseService and make it part of a state transition (after make_install happens). This ensures that Knative is installed before we attempt to update it. --- app/models/clusters/applications/knative.rb | 6 +++++ .../serverless/associate_domain_service.rb | 2 -- .../clusters/applications/knative_spec.rb | 27 +++++++++++++++++++ .../associate_domain_service_spec.rb | 18 ------------- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/app/models/clusters/applications/knative.rb b/app/models/clusters/applications/knative.rb index b598be817c70bd..1f90318f845578 100644 --- a/app/models/clusters/applications/knative.rb +++ b/app/models/clusters/applications/knative.rb @@ -33,6 +33,12 @@ def set_initial_status FETCH_IP_ADDRESS_DELAY, application.name, application.id) end end + + after_transition any => [:installed, :updated] do |application| + application.run_after_commit do + ClusterConfigureIstioWorker.perform_async(application.cluster_id) + end + end end default_value_for :version, VERSION diff --git a/app/services/serverless/associate_domain_service.rb b/app/services/serverless/associate_domain_service.rb index dcca73802dd90a..673f1f8326011e 100644 --- a/app/services/serverless/associate_domain_service.rb +++ b/app/services/serverless/associate_domain_service.rb @@ -17,8 +17,6 @@ def execute knative.pages_domain = knative.find_available_domain(pages_domain_id) knative.serverless_domain_cluster.update(creator: creator) if knative.pages_domain - - ClusterConfigureIstioWorker.perform_async(knative.cluster_id) end private diff --git a/spec/models/clusters/applications/knative_spec.rb b/spec/models/clusters/applications/knative_spec.rb index 61626af3284799..7ff7644e7033d1 100644 --- a/spec/models/clusters/applications/knative_spec.rb +++ b/spec/models/clusters/applications/knative_spec.rb @@ -14,6 +14,7 @@ before do allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in) allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async) + allow(ClusterConfigureIstioWorker).to receive(:perform_async) end describe 'associations' do @@ -47,6 +48,32 @@ end end + describe 'configuring istio ingress gateway' do + context 'after installed' do + let(:application) { create(:clusters_applications_knative, :installing) } + + before do + application.make_installed! + end + + it 'schedules a ClusterConfigureIstioWorker' do + expect(ClusterConfigureIstioWorker).to have_received(:perform_async).with(application.cluster_id) + end + end + + context 'after updated' do + let(:application) { create(:clusters_applications_knative, :updating) } + + before do + application.make_installed! + end + + it 'schedules a ClusterConfigureIstioWorker' do + expect(ClusterConfigureIstioWorker).to have_received(:perform_async).with(application.cluster_id) + end + end + end + describe '#can_uninstall?' do subject { knative.can_uninstall? } diff --git a/spec/services/serverless/associate_domain_service_spec.rb b/spec/services/serverless/associate_domain_service_spec.rb index b73857690c2c51..3d1a878bcf582e 100644 --- a/spec/services/serverless/associate_domain_service_spec.rb +++ b/spec/services/serverless/associate_domain_service_spec.rb @@ -13,12 +13,6 @@ context 'when the domain is unchanged' do let(:creator) { create(:user) } - it 'does not schedule a ClusterConfigureIstioWorker' do - expect(ClusterConfigureIstioWorker).not_to receive(:perform_async) - - subject.execute - end - it 'does not update creator' do expect { subject.execute }.not_to change { sdc.reload.creator } end @@ -35,12 +29,6 @@ it 'does not attempt to update creator' do expect { subject.execute }.not_to raise_error end - - it 'schedules a ClusterConfigureIstioWorker for the cluster' do - expect(ClusterConfigureIstioWorker).to receive(:perform_async).with(knative.cluster_id) - - subject.execute - end end context 'when a new domain is associated' do @@ -51,12 +39,6 @@ expect { subject.execute }.to change { knative.pages_domain.id }.from(sdc.pages_domain.id).to(pages_domain_id) end - it 'schedules a ClusterConfigureIstioWorker for the cluster' do - expect(ClusterConfigureIstioWorker).to receive(:perform_async).with(knative.cluster_id) - - subject.execute - end - it 'updates creator' do expect { subject.execute }.to change { sdc.reload.creator }.from(sdc.creator).to(creator) end -- GitLab From 15a6a21b7180721c2dcbaa5e243a9dd71a93f298 Mon Sep 17 00:00:00 2001 From: Alishan Ladhani Date: Wed, 26 Feb 2020 11:55:37 -0500 Subject: [PATCH 06/43] Put Knative into an errored state when istio cannot be configured --- .../configure_istio_ingress_service.rb | 4 +++ .../configure_istio_ingress_service_spec.rb | 32 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/app/services/clusters/kubernetes/configure_istio_ingress_service.rb b/app/services/clusters/kubernetes/configure_istio_ingress_service.rb index fe577beaa8aea7..a81014d99ffe8a 100644 --- a/app/services/clusters/kubernetes/configure_istio_ingress_service.rb +++ b/app/services/clusters/kubernetes/configure_istio_ingress_service.rb @@ -27,6 +27,10 @@ def execute return configure_certificates if serverless_domain_cluster configure_passthrough + rescue Kubeclient::HttpError => e + knative.make_errored!(_('Kubernetes error: %{error_code}') % { error_code: e.error_code }) + rescue StandardError + knative.make_errored!(_('Failed to update.')) end private diff --git a/spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb b/spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb index 572e2b91187117..9238f7debd0a89 100644 --- a/spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb +++ b/spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb @@ -194,4 +194,36 @@ ) end end + + context 'when there is an error' do + before do + cluster.application_knative = create(:clusters_applications_knative) + + allow_next_instance_of(described_class) do |instance| + allow(instance).to receive(:configure_passthrough).and_raise(error) + end + end + + context 'Kubeclient::HttpError' do + let(:error) { Kubeclient::HttpError.new(404, nil, nil) } + + it 'puts Knative into an errored state' do + subject + + expect(cluster.application_knative).to be_errored + expect(cluster.application_knative.status_reason).to eq('Kubernetes error: 404') + end + end + + context 'StandardError' do + let(:error) { RuntimeError.new('something went wrong') } + + it 'puts Knative into an errored state' do + subject + + expect(cluster.application_knative).to be_errored + expect(cluster.application_knative.status_reason).to eq('Failed to update.') + end + end + end end -- GitLab From b5c6000fcd321bfcc9fb16bac21583760d3f1928 Mon Sep 17 00:00:00 2001 From: Sean Carroll Date: Thu, 27 Feb 2020 13:39:10 +0000 Subject: [PATCH 07/43] Add filepath column to release_links Part of https://gitlab.com/gitlab-org/gitlab/issues/27300 See merge request https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25512 --- ...7300-add-filepath-to-release-links-api.yml | 5 +++ lib/api/entities/releases/link.rb | 10 ++++++ lib/api/release/links.rb | 2 ++ spec/fixtures/api/schemas/release/link.json | 2 ++ spec/requests/api/release/links_spec.rb | 33 +++++++++++++++++-- 5 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 changelogs/unreleased/27300-add-filepath-to-release-links-api.yml diff --git a/changelogs/unreleased/27300-add-filepath-to-release-links-api.yml b/changelogs/unreleased/27300-add-filepath-to-release-links-api.yml new file mode 100644 index 00000000000000..2616aa2cc5b3c2 --- /dev/null +++ b/changelogs/unreleased/27300-add-filepath-to-release-links-api.yml @@ -0,0 +1,5 @@ +--- +title: Add filepath to release links API +merge_request: 25533 +author: +type: added diff --git a/lib/api/entities/releases/link.rb b/lib/api/entities/releases/link.rb index 6cc01e0e981870..f4edb83bd585a8 100644 --- a/lib/api/entities/releases/link.rb +++ b/lib/api/entities/releases/link.rb @@ -7,7 +7,17 @@ class Link < Grape::Entity expose :id expose :name expose :url + expose :direct_asset_url expose :external?, as: :external + + def direct_asset_url + return object.url unless object.filepath + + release = object.release + project = release.project + + Gitlab::Routing.url_helpers.project_release_url(project, release) << object.filepath + end end end end diff --git a/lib/api/release/links.rb b/lib/api/release/links.rb index def36dc8529891..f72230c084c5be 100644 --- a/lib/api/release/links.rb +++ b/lib/api/release/links.rb @@ -39,6 +39,7 @@ class Links < Grape::API params do requires :name, type: String, desc: 'The name of the link' requires :url, type: String, desc: 'The URL of the link' + optional :filepath, type: String, desc: 'The filepath of the link' end post 'links' do authorize! :create_release, release @@ -73,6 +74,7 @@ class Links < Grape::API params do optional :name, type: String, desc: 'The name of the link' optional :url, type: String, desc: 'The URL of the link' + optional :filepath, type: String, desc: 'The filepath of the link' at_least_one_of :name, :url end put do diff --git a/spec/fixtures/api/schemas/release/link.json b/spec/fixtures/api/schemas/release/link.json index 97347cb91ccdc9..bf175be2bc08f6 100644 --- a/spec/fixtures/api/schemas/release/link.json +++ b/spec/fixtures/api/schemas/release/link.json @@ -4,7 +4,9 @@ "properties": { "id": { "type": "integer" }, "name": { "type": "string" }, + "filepath": { "type": "string" }, "url": { "type": "string" }, + "direct_asset_url": { "type": "string" }, "external": { "type": "boolean" } }, "additionalProperties": false diff --git a/spec/requests/api/release/links_spec.rb b/spec/requests/api/release/links_spec.rb index 3a59052bb2923a..cf2043ecc7456f 100644 --- a/spec/requests/api/release/links_spec.rb +++ b/spec/requests/api/release/links_spec.rb @@ -135,16 +135,44 @@ end end end + + describe '#direct_asset_url' do + let!(:link) { create(:release_link, release: release, url: url, filepath: filepath) } + let(:url) { 'https://google.com/-/jobs/140463678/artifacts/download' } + + context 'when filepath is provided' do + let(:filepath) { '/bin/bigfile.exe' } + + specify do + get api("/projects/#{project.id}/releases/v0.1/assets/links/#{link.id}", maintainer) + + expect(json_response['direct_asset_url']).to eq("http://localhost/#{project.namespace.path}/#{project.name}/-/releases/#{release.tag}/bin/bigfile.exe") + end + end + + context 'when filepath is not provided' do + let(:filepath) { nil } + + specify do + get api("/projects/#{project.id}/releases/v0.1/assets/links/#{link.id}", maintainer) + + expect(json_response['direct_asset_url']).to eq(url) + end + end + end end describe 'POST /projects/:id/releases/:tag_name/assets/links' do let(:params) do { name: 'awesome-app.dmg', + filepath: '/binaries/awesome-app.dmg', url: 'https://example.com/download/awesome-app.dmg' } end + let(:last_release_link) { release.links.last } + it 'accepts the request' do post api("/projects/#{project.id}/releases/v0.1/assets/links", maintainer), params: params @@ -157,8 +185,9 @@ end.to change { Releases::Link.count }.by(1) release.reload - expect(release.links.last.name).to eq('awesome-app.dmg') - expect(release.links.last.url).to eq('https://example.com/download/awesome-app.dmg') + expect(last_release_link.name).to eq('awesome-app.dmg') + expect(last_release_link.filepath).to eq('/binaries/awesome-app.dmg') + expect(last_release_link.url).to eq('https://example.com/download/awesome-app.dmg') end it 'matches response schema' do -- GitLab From 084870e2697c31450d77f3a8a09ddaafd4a54dbb Mon Sep 17 00:00:00 2001 From: Alessio Caiazza Date: Wed, 26 Feb 2020 17:51:07 +0100 Subject: [PATCH 08/43] Cherry-pick tracking with cherry-pick-commit icon --- app/helpers/system_note_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/system_note_helper.rb b/app/helpers/system_note_helper.rb index 05d698a6d9915c..c982b48a94e733 100644 --- a/app/helpers/system_note_helper.rb +++ b/app/helpers/system_note_helper.rb @@ -2,7 +2,7 @@ module SystemNoteHelper ICON_NAMES_BY_ACTION = { - 'cherry_pick' => 'link', + 'cherry_pick' => 'cherry-pick-commit', 'commit' => 'commit', 'description' => 'pencil-square', 'merge' => 'git-merge', -- GitLab From f6607638673bc45ce2d9e5d9d94f615a91cfdc6b Mon Sep 17 00:00:00 2001 From: Gwen_ Date: Tue, 25 Feb 2020 15:46:35 +0100 Subject: [PATCH 09/43] Added a condition when a ticket is moved from the closed list --- app/assets/javascripts/boards/stores/boards_store.js | 3 ++- .../25550-there-is-a-drag-and-drop-bug-in-boards.yml | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/25550-there-is-a-drag-and-drop-bug-in-boards.yml diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js index 010eda9b6c538e..2a5571543fb71d 100644 --- a/app/assets/javascripts/boards/stores/boards_store.js +++ b/app/assets/javascripts/boards/stores/boards_store.js @@ -337,7 +337,8 @@ const boardsStore = { return ( (listTo.type !== 'label' && listFrom.type === 'assignee') || (listTo.type !== 'assignee' && listFrom.type === 'label') || - listFrom.type === 'backlog' + listFrom.type === 'backlog' || + listFrom.type === 'closed' ); }, moveIssueInList(list, issue, oldIndex, newIndex, idArray) { diff --git a/changelogs/unreleased/25550-there-is-a-drag-and-drop-bug-in-boards.yml b/changelogs/unreleased/25550-there-is-a-drag-and-drop-bug-in-boards.yml new file mode 100644 index 00000000000000..e4777065f078b5 --- /dev/null +++ b/changelogs/unreleased/25550-there-is-a-drag-and-drop-bug-in-boards.yml @@ -0,0 +1,5 @@ +--- +title: Resolves the disappearance of a ticket when it was moved from the closed list. +merge_request: +author: Gwen_ +type: fixed -- GitLab From 6fba01aec69d8ebabb25f68ae21f5e5d2d6f1f61 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Thu, 27 Feb 2020 16:01:18 +0000 Subject: [PATCH 10/43] Updating Serverless documentation In addition to Serverless, adding AWS' SAM documentation. --- doc/user/project/clusters/serverless/aws.md | 219 ++++++++++++++++-- .../serverless/img/sam-api-endpoint.png | Bin 0 -> 59484 bytes .../serverless/img/sam-complete-raw.png | Bin 0 -> 100590 bytes 3 files changed, 205 insertions(+), 14 deletions(-) create mode 100644 doc/user/project/clusters/serverless/img/sam-api-endpoint.png create mode 100644 doc/user/project/clusters/serverless/img/sam-complete-raw.png diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 95c0b7f143691e..e2c2c075f26c96 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -4,9 +4,13 @@ GitLab allows users to easily deploy AWS Lambda functions and create rich server GitLab supports deployment of functions to AWS Lambda using a combination of: -- [Serverless Framework with AWS](https://serverless.com/framework/docs/providers/aws/) +- [Serverless Framework with AWS](#serverless-framework) +- [AWS' Serverless Application Model (SAM)](#aws-serverless-application-model) - GitLab CI/CD +## Serverless Framework +The [Serverless Framework can deploy to AWS](https://serverless.com/framework/docs/providers/aws/) + We have prepared an example with a step-by-step guide to create a simple function and deploy it on AWS. Additionally, in the [How To section](#how-to), you can read about different use cases, @@ -18,14 +22,14 @@ like: Alternatively, you can quickly [create a new project with a template](../../../../gitlab-basics/create-project.md#project-templates). The [`Serverless Framework/JS` template](https://gitlab.com/gitlab-org/project-templates/serverless-framework/) already includes all parts described below. -## Example +### Example In the following example, you will: 1. Create a basic AWS Lambda Node.js function. 1. Link the function to an API Gateway `GET` endpoint. -### Steps +#### Steps The example consists of the following steps: @@ -38,7 +42,7 @@ The example consists of the following steps: Lets take it step by step. -### Creating a Lambda handler function +#### Creating a Lambda handler function Your Lambda function will be the primary handler of requests. In this case we will create a very simple Node.js `hello` function: @@ -67,7 +71,7 @@ In our case, `module.exports.hello` defines the `hello` handler that will be ref You can learn more about the AWS Lambda Node.js function handler and all its various options here: -### Creating a `serverless.yml` file +#### Creating a `serverless.yml` file In the root of your project, create a `serverless.yml` file that will contain configuration specifics for the Serverless Framework. @@ -94,7 +98,7 @@ The `events` declaration will create a AWS API Gateway `GET` endpoint to receive You can read more about the available properties and additional configuration possibilities of the Serverless Framework here: -### Crafting the `.gitlab-ci.yml` file +#### Crafting the `.gitlab-ci.yml` file In a `.gitlab-ci.yml` file in the root of your project, place the following code: @@ -122,7 +126,7 @@ This example code does the following: - Deploys the serverless function to your AWS account using the AWS credentials defined above. -### Setting up your AWS credentials with your GitLab account +#### Setting up your AWS credentials with your GitLab account In order to interact with your AWS account, the GitLab CI/CD pipelines require both `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see: @@ -130,7 +134,7 @@ For more information please see: { For more information, see the [Your CORS and API Gateway survival guide](https://serverless.com/blog/cors-api-gateway-survival-guide/) blog post written by the Serverless Framework team. -### Writing automated tests +#### Writing automated tests The [Serverless Framework](https://gitlab.com/gitlab-org/project-templates/serverless-framework/) example project shows how to use Jest, Axios, and `serverless-offline` plugin to do automated testing of both local and deployed serverless function. -## Examples and template +### Examples and template The example code is available: @@ -285,3 +289,190 @@ The example code is available: You can also use a [template](../../../../gitlab-basics/create-project.md#project-templates) (based on the version with tests and secret variables) from within the GitLab UI (see the `Serverless Framework/JS` template). + + + +---- +## AWS Serverless Application Model + + +### Deploying AWS Lambda function using AWS SAM and GitLab CI/CD + +GitLab allows developers to build and deploy serverless applications using the combination of: + + +- [AWS Serverless Application Model (AWS SAM)](https://aws.amazon.com/serverless/sam/) +- GitLab CI/CD + +AWS Serverless Application Model is an open source framework for building serverless applications. It makes it easier to build and deploy serverless applications. For more details please take a look at AWS documentation on [AWS Serverless Application Model](https://aws.amazon.com/serverless/sam/) + + +### Example: + +In the following example, you will: + + + +1. Install SAM CLI +1. Create a sample SAM application including a Lambda function and API Gateway +1. Build and deploy the application to your AWS account using GitLab CI/CD + + +### Steps: + +The example consists of the following steps: + + + +1. Install SAM CLI +1. Creating an AWS SAM application using SAM CLI +1. Crafting the .gitlab-ci.yml file +1. Setting up your AWS credentials with your GitLab account +1. Deploying your application +1. Testing the deployed function + + +### Installing SAM CLI: + +AWS SAM provides a CLI called, AWS SAM CLI, to make it easier to create and manage applications. Some steps in this documentation uses SAM CLI. Please follow the instructions on [installing SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) page install and configure SAM CLI. + +If you use [AWS Cloud9](https://aws.amazon.com/cloud9/) as your integrated development environment (IDE), the [AWS Command Line Interface](https://docs.aws.amazon.com/en_pv/cli/latest/userguide/cli-chap-install.html) (CLI), [SAM CLI](https://docs.aws.amazon.com/en_pv/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html), [Docker](https://docs.docker.com/install/), and necessary Docker images are installed for you. + + +### Creating an AWS SAM application using SAM CLI: + +To create a SAM app from the CLI, open a terminal and enter the following text: + +`sam init -r python3.8 -n gitlabpoc --app-template "hello-world"` + +This creates a SAM app named gitlabpoc using the default configuration, a single Python3.8 function invoked by an [Amazon API Gateway](https://aws.amazon.com/api-gateway/) endpoint. + +To see additional runtimes supported by SAM and options for sam init, enter: +`sam init -h` + +Push this project to a new project in GitLab. + +### Crafting the .gitlab-ci.yml file: + +GitLab CI/CD pipelines are configured using a YAML file called .gitlab-ci.yml within each project. The [.gitlab-ci.yml](https://docs.gitlab.com/ee/ci/yaml/) file defines the structure and order of the pipelines. + +In a .gitlab-ci.yml file in the root of your project, place the following code and replace the #S3Bucket# with an S3 bucket name where you would like to place your package: + +```yaml +image: python:latest + +stages: + + - deploy + +production: + + stage: deploy + + before_script: + + - pip3 install awscli --upgrade + + - pip3 install aws-sam-cli --upgrade + + script: + + - sam build + + - sam package --output-template-file packaged.yaml --s3-bucket #S3Bucket# + + - sam deploy --template-file packaged.yaml --stack-name gitlabpoc --s3-bucket #S3Bucket# --capabilities CAPABILITY_IAM --region us-east-1 + + environment: production + ``` + +Let’s examine the config file more closely: + + +1. Image specifies the docker image to use for this build. The latest python image since the sample application is written in python +1. AWS CLI and AWS SAM CLI are installed in before script section. +1. SAM build, package and deploy commands are used to build, package and deploy the application. More details on SAM can be found [here](https://aws.amazon.com/serverless/sam/). + + +### Setting up your AWS credentials with your GitLab account: + +In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](https://docs.gitlab.com/ee/ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. + + +**Note:** The AWS credentials you provide must include IAM policies that provision correct access control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. + + +### Deploying your application: + +Push changes to your GitLab repository and the GitLab build pipeline will automatically deploy your application. If your build and deploy are successful, please go to the next step to test your deployed application. + +If your build fails please take a look at the build log to see why the build failed. Some common reasons the build might fail are: + + + +1. In-compatible versions of software (e.g. Python run time version might be different from the python on the build machine). Please address this by installing the proper versions of the software. +1. You may not be able to access your AWS account from GitLab. Please, go back and check the environment variables you setup with AWS credentials. +1. You may not have permission to do deploy a serverless application. Please make sure you provide all required permissions to deploy a serverless application. + + +### Testing the deployed application: + +To test the application you deployed, please go to the build log and follow the following steps: + + + +1. Click on “Show complete raw” on the upper righthand corner + + +![sam-complete-raw](img/sam-complete-raw.png) + + +2. Look for HelloWorldApi – API Gateway endpoint similar to shown below + + +![sam-api-endpoint](img/sam-api-endpoint.png) + + + +3. Use curl to test the API + +`curl https://py4rg7qtlg.execute-api.us-east-1.amazonaws.com/Prod/hello/` + +Output should be: + +```json +{"message": "hello world"} +``` + + +### Testing Locally: + +AWS SAM provides functionality to test your applications locally. As mentioned earlier, you must have AWS SAM CLI installed locally for you to test locally. + +First, test the function. SAM provides a default event in events/event.json that includes a message body of {\“message\”: \“hello world\”}. If you pass that event into the HelloWorldFunction, it should respond with the same body. + +`sam local invoke HelloWorldFunction -e events/event.json` + +Output should be: + +```json +{"message": "hello world"} +``` + +After you confirm that Lambda Function is working as expected, you can test the API Gateway using following steps: + +Start the API locally: + +`sam local start-api` + + +SAM again launches a Docker container, this time with a mocked Amazon API Gateway listening on localhost:3000. Now you can call the hello API as follows: + +`curl http://127.0.0.1:3000/hello` + + +Output again should be: + +```json +{"message": "hello world"} +``` diff --git a/doc/user/project/clusters/serverless/img/sam-api-endpoint.png b/doc/user/project/clusters/serverless/img/sam-api-endpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..695d975387ff284585eaea2f758706a0f1547fd5 GIT binary patch literal 59484 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 literal 0 HcmV?d00001 diff --git a/doc/user/project/clusters/serverless/img/sam-complete-raw.png b/doc/user/project/clusters/serverless/img/sam-complete-raw.png new file mode 100644 index 0000000000000000000000000000000000000000..1098c1bb93fde2b399af1d9d4136068cbdc47fe6 GIT binary patch literal 100590 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 ZxBf~K+qXa@l7WGN!PC{xWt~$(698X4+8zJ^ literal 0 HcmV?d00001 -- GitLab From 5aa7c2ad70f836a79557368153efb70e13df2b1a Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Thu, 27 Feb 2020 16:36:09 +0000 Subject: [PATCH 11/43] Update aws documentation --- doc/user/project/clusters/serverless/aws.md | 28 +-------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index e2c2c075f26c96..ef7f79d45032b9 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -9,6 +9,7 @@ GitLab supports deployment of functions to AWS Lambda using a combination of: - GitLab CI/CD ## Serverless Framework + The [Serverless Framework can deploy to AWS](https://serverless.com/framework/docs/providers/aws/) We have prepared an example with a step-by-step guide to create a simple function and deploy it on AWS. @@ -290,9 +291,6 @@ You can also use a [template](../../../../gitlab-basics/create-project.md#projec (based on the version with tests and secret variables) from within the GitLab UI (see the `Serverless Framework/JS` template). - - ----- ## AWS Serverless Application Model @@ -311,19 +309,14 @@ AWS Serverless Application Model is an open source framework for building server In the following example, you will: - - 1. Install SAM CLI 1. Create a sample SAM application including a Lambda function and API Gateway 1. Build and deploy the application to your AWS account using GitLab CI/CD - ### Steps: The example consists of the following steps: - - 1. Install SAM CLI 1. Creating an AWS SAM application using SAM CLI 1. Crafting the .gitlab-ci.yml file @@ -331,14 +324,12 @@ The example consists of the following steps: 1. Deploying your application 1. Testing the deployed function - ### Installing SAM CLI: AWS SAM provides a CLI called, AWS SAM CLI, to make it easier to create and manage applications. Some steps in this documentation uses SAM CLI. Please follow the instructions on [installing SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) page install and configure SAM CLI. If you use [AWS Cloud9](https://aws.amazon.com/cloud9/) as your integrated development environment (IDE), the [AWS Command Line Interface](https://docs.aws.amazon.com/en_pv/cli/latest/userguide/cli-chap-install.html) (CLI), [SAM CLI](https://docs.aws.amazon.com/en_pv/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html), [Docker](https://docs.docker.com/install/), and necessary Docker images are installed for you. - ### Creating an AWS SAM application using SAM CLI: To create a SAM app from the CLI, open a terminal and enter the following text: @@ -388,52 +379,38 @@ production: Let’s examine the config file more closely: - 1. Image specifies the docker image to use for this build. The latest python image since the sample application is written in python 1. AWS CLI and AWS SAM CLI are installed in before script section. 1. SAM build, package and deploy commands are used to build, package and deploy the application. More details on SAM can be found [here](https://aws.amazon.com/serverless/sam/). - ### Setting up your AWS credentials with your GitLab account: In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](https://docs.gitlab.com/ee/ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. - **Note:** The AWS credentials you provide must include IAM policies that provision correct access control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. - ### Deploying your application: Push changes to your GitLab repository and the GitLab build pipeline will automatically deploy your application. If your build and deploy are successful, please go to the next step to test your deployed application. If your build fails please take a look at the build log to see why the build failed. Some common reasons the build might fail are: - - 1. In-compatible versions of software (e.g. Python run time version might be different from the python on the build machine). Please address this by installing the proper versions of the software. 1. You may not be able to access your AWS account from GitLab. Please, go back and check the environment variables you setup with AWS credentials. 1. You may not have permission to do deploy a serverless application. Please make sure you provide all required permissions to deploy a serverless application. - ### Testing the deployed application: To test the application you deployed, please go to the build log and follow the following steps: - - 1. Click on “Show complete raw” on the upper righthand corner - ![sam-complete-raw](img/sam-complete-raw.png) - 2. Look for HelloWorldApi – API Gateway endpoint similar to shown below - ![sam-api-endpoint](img/sam-api-endpoint.png) - - 3. Use curl to test the API `curl https://py4rg7qtlg.execute-api.us-east-1.amazonaws.com/Prod/hello/` @@ -444,7 +421,6 @@ Output should be: {"message": "hello world"} ``` - ### Testing Locally: AWS SAM provides functionality to test your applications locally. As mentioned earlier, you must have AWS SAM CLI installed locally for you to test locally. @@ -465,12 +441,10 @@ Start the API locally: `sam local start-api` - SAM again launches a Docker container, this time with a mocked Amazon API Gateway listening on localhost:3000. Now you can call the hello API as follows: `curl http://127.0.0.1:3000/hello` - Output again should be: ```json -- GitLab From b8f455ef489536f72320cae33310a6da00b446b4 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Thu, 27 Feb 2020 16:47:04 +0000 Subject: [PATCH 12/43] Update aws documentation --- doc/user/project/clusters/serverless/aws.md | 26 ++++++++------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index ef7f79d45032b9..5c96d6c0c0a1ae 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -293,19 +293,16 @@ the `Serverless Framework/JS` template). ## AWS Serverless Application Model - ### Deploying AWS Lambda function using AWS SAM and GitLab CI/CD GitLab allows developers to build and deploy serverless applications using the combination of: - - [AWS Serverless Application Model (AWS SAM)](https://aws.amazon.com/serverless/sam/) - GitLab CI/CD AWS Serverless Application Model is an open source framework for building serverless applications. It makes it easier to build and deploy serverless applications. For more details please take a look at AWS documentation on [AWS Serverless Application Model](https://aws.amazon.com/serverless/sam/) - -### Example: +### Example In the following example, you will: @@ -313,7 +310,7 @@ In the following example, you will: 1. Create a sample SAM application including a Lambda function and API Gateway 1. Build and deploy the application to your AWS account using GitLab CI/CD -### Steps: +### Steps The example consists of the following steps: @@ -324,26 +321,22 @@ The example consists of the following steps: 1. Deploying your application 1. Testing the deployed function -### Installing SAM CLI: +### Installing SAM CLI -AWS SAM provides a CLI called, AWS SAM CLI, to make it easier to create and manage applications. Some steps in this documentation uses SAM CLI. Please follow the instructions on [installing SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) page install and configure SAM CLI. +AWS SAM provides a CLI called, AWS SAM CLI, to make it easier to create and manage applications. Some steps in this documentation uses SAM CLI. Please follow the instructions on [installing SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) page install and configure SAM CLI. If you use [AWS Cloud9](https://aws.amazon.com/cloud9/) as your integrated development environment (IDE), the [AWS Command Line Interface](https://docs.aws.amazon.com/en_pv/cli/latest/userguide/cli-chap-install.html) (CLI), [SAM CLI](https://docs.aws.amazon.com/en_pv/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html), [Docker](https://docs.docker.com/install/), and necessary Docker images are installed for you. -If you use [AWS Cloud9](https://aws.amazon.com/cloud9/) as your integrated development environment (IDE), the [AWS Command Line Interface](https://docs.aws.amazon.com/en_pv/cli/latest/userguide/cli-chap-install.html) (CLI), [SAM CLI](https://docs.aws.amazon.com/en_pv/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html), [Docker](https://docs.docker.com/install/), and necessary Docker images are installed for you. - -### Creating an AWS SAM application using SAM CLI: +### Creating an AWS SAM application using SAM CLI To create a SAM app from the CLI, open a terminal and enter the following text: `sam init -r python3.8 -n gitlabpoc --app-template "hello-world"` -This creates a SAM app named gitlabpoc using the default configuration, a single Python3.8 function invoked by an [Amazon API Gateway](https://aws.amazon.com/api-gateway/) endpoint. - -To see additional runtimes supported by SAM and options for sam init, enter: +This creates a SAM app named gitlabpoc using the default configuration, a single Python3.8 function invoked by an [Amazon API Gateway](https://aws.amazon.com/api-gateway/) endpoint. To see additional runtimes supported by SAM and options for sam init, enter: `sam init -h` Push this project to a new project in GitLab. -### Crafting the .gitlab-ci.yml file: +### Crafting the .gitlab-ci.yml file GitLab CI/CD pipelines are configured using a YAML file called .gitlab-ci.yml within each project. The [.gitlab-ci.yml](https://docs.gitlab.com/ee/ci/yaml/) file defines the structure and order of the pipelines. @@ -395,7 +388,7 @@ Push changes to your GitLab repository and the GitLab build pipeline will automa If your build fails please take a look at the build log to see why the build failed. Some common reasons the build might fail are: -1. In-compatible versions of software (e.g. Python run time version might be different from the python on the build machine). Please address this by installing the proper versions of the software. +1. In-compatible versions of software (e.g. Python run time version might be different from the Python on the build machine). Please address this by installing the proper versions of the software. 1. You may not be able to access your AWS account from GitLab. Please, go back and check the environment variables you setup with AWS credentials. 1. You may not have permission to do deploy a serverless application. Please make sure you provide all required permissions to deploy a serverless application. @@ -421,10 +414,11 @@ Output should be: {"message": "hello world"} ``` -### Testing Locally: +### Testing Locally AWS SAM provides functionality to test your applications locally. As mentioned earlier, you must have AWS SAM CLI installed locally for you to test locally. + First, test the function. SAM provides a default event in events/event.json that includes a message body of {\“message\”: \“hello world\”}. If you pass that event into the HelloWorldFunction, it should respond with the same body. `sam local invoke HelloWorldFunction -e events/event.json` -- GitLab From aee579d88f2a64011d1628be7cefad626908575b Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Thu, 27 Feb 2020 16:59:24 +0000 Subject: [PATCH 13/43] Reword AWS documentation --- doc/user/project/clusters/serverless/aws.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 5c96d6c0c0a1ae..6a1e519a0fb92c 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -291,7 +291,7 @@ You can also use a [template](../../../../gitlab-basics/create-project.md#projec (based on the version with tests and secret variables) from within the GitLab UI (see the `Serverless Framework/JS` template). -## AWS Serverless Application Model +## AWS Serverless Application Model ### Deploying AWS Lambda function using AWS SAM and GitLab CI/CD @@ -300,7 +300,7 @@ GitLab allows developers to build and deploy serverless applications using the c - [AWS Serverless Application Model (AWS SAM)](https://aws.amazon.com/serverless/sam/) - GitLab CI/CD -AWS Serverless Application Model is an open source framework for building serverless applications. It makes it easier to build and deploy serverless applications. For more details please take a look at AWS documentation on [AWS Serverless Application Model](https://aws.amazon.com/serverless/sam/) +AWS Serverless Application Model is an open source framework for building serverless applications. It makes it easier to build and deploy serverless applications. For more details please take a look at AWS documentation on [AWS Serverless Application Model](https://aws.amazon.com/serverless/sam/) ### Example @@ -338,9 +338,9 @@ Push this project to a new project in GitLab. ### Crafting the .gitlab-ci.yml file -GitLab CI/CD pipelines are configured using a YAML file called .gitlab-ci.yml within each project. The [.gitlab-ci.yml](https://docs.gitlab.com/ee/ci/yaml/) file defines the structure and order of the pipelines. +GitLab CI/CD pipelines are configured using a YAML file called ".gitlab-ci.yml" within each project. The[".gitlab-ci.yml"](https://docs.gitlab.com/ee/ci/yaml/) file defines the structure and order of the pipelines. -In a .gitlab-ci.yml file in the root of your project, place the following code and replace the #S3Bucket# with an S3 bucket name where you would like to place your package: +In a ".gitlab-ci.yml" file in the root of your project, place the following code and replace the #S3Bucket# with an S3 bucket name where you would like to place your package: ```yaml image: python:latest @@ -372,7 +372,7 @@ production: Let’s examine the config file more closely: -1. Image specifies the docker image to use for this build. The latest python image since the sample application is written in python +1. Image specifies the docker image to use for this build. The latest python image since the sample application is written in Python 1. AWS CLI and AWS SAM CLI are installed in before script section. 1. SAM build, package and deploy commands are used to build, package and deploy the application. More details on SAM can be found [here](https://aws.amazon.com/serverless/sam/). @@ -396,15 +396,15 @@ If your build fails please take a look at the build log to see why the build fai To test the application you deployed, please go to the build log and follow the following steps: -1. Click on “Show complete raw” on the upper righthand corner +- Click on “Show complete raw” on the upper righthand corner ![sam-complete-raw](img/sam-complete-raw.png) -2. Look for HelloWorldApi – API Gateway endpoint similar to shown below +- Look for HelloWorldApi – API Gateway endpoint similar to shown below ![sam-api-endpoint](img/sam-api-endpoint.png) -3. Use curl to test the API +- Use curl to test the API `curl https://py4rg7qtlg.execute-api.us-east-1.amazonaws.com/Prod/hello/` @@ -416,10 +416,9 @@ Output should be: ### Testing Locally -AWS SAM provides functionality to test your applications locally. As mentioned earlier, you must have AWS SAM CLI installed locally for you to test locally. +AWS SAM provides functionality to test your applications locally. As mentioned earlier, you must have AWS SAM CLI installed locally for you to test locally. - -First, test the function. SAM provides a default event in events/event.json that includes a message body of {\“message\”: \“hello world\”}. If you pass that event into the HelloWorldFunction, it should respond with the same body. +First, test the function. SAM provides a default event in events/event.json that includes a message body of {\“message\”: \“hello world\”}. If you pass that event into the HelloWorldFunction, it should respond with the same body. `sam local invoke HelloWorldFunction -e events/event.json` -- GitLab From 28c39aa9b182f08993c7e8d27098cff496c3f6e5 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Thu, 27 Feb 2020 17:08:03 +0000 Subject: [PATCH 14/43] Reword AWS documentation --- doc/user/project/clusters/serverless/aws.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 6a1e519a0fb92c..ee787da063714c 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -316,7 +316,7 @@ The example consists of the following steps: 1. Install SAM CLI 1. Creating an AWS SAM application using SAM CLI -1. Crafting the .gitlab-ci.yml file +1. Crafting the `.gitlab-ci.yml` file 1. Setting up your AWS credentials with your GitLab account 1. Deploying your application 1. Testing the deployed function @@ -336,11 +336,11 @@ This creates a SAM app named gitlabpoc using the default configuration, a single Push this project to a new project in GitLab. -### Crafting the .gitlab-ci.yml file +### Crafting the `.gitlab-ci.yml` file -GitLab CI/CD pipelines are configured using a YAML file called ".gitlab-ci.yml" within each project. The[".gitlab-ci.yml"](https://docs.gitlab.com/ee/ci/yaml/) file defines the structure and order of the pipelines. +GitLab CI/CD pipelines are configured using a YAML file called `.gitlab-ci.yml` within each project. The[".gitlab-ci.yml"](https://docs.gitlab.com/ee/ci/yaml/) file defines the structure and order of the pipelines. -In a ".gitlab-ci.yml" file in the root of your project, place the following code and replace the #S3Bucket# with an S3 bucket name where you would like to place your package: +In a `.gitlab-ci.yml` file in the root of your project, place the following code and replace the #S3Bucket# with an S3 bucket name where you would like to place your package: ```yaml image: python:latest @@ -372,19 +372,19 @@ production: Let’s examine the config file more closely: -1. Image specifies the docker image to use for this build. The latest python image since the sample application is written in Python +1. Image specifies the docker image to use for this build. The latest Python image since the sample application is written in Python 1. AWS CLI and AWS SAM CLI are installed in before script section. 1. SAM build, package and deploy commands are used to build, package and deploy the application. More details on SAM can be found [here](https://aws.amazon.com/serverless/sam/). -### Setting up your AWS credentials with your GitLab account: +### Setting up your AWS credentials with your GitLab account In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](https://docs.gitlab.com/ee/ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. -**Note:** The AWS credentials you provide must include IAM policies that provision correct access control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. +**Note:** The AWS credentials you provide must include IAM policies that provision correct access control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. -### Deploying your application: +### Deploying your application -Push changes to your GitLab repository and the GitLab build pipeline will automatically deploy your application. If your build and deploy are successful, please go to the next step to test your deployed application. +Push changes to your GitLab repository and the GitLab build pipeline will automatically deploy your application. If your build and deploy are successful, please go to the next step to test your deployed application. If your build fails please take a look at the build log to see why the build failed. Some common reasons the build might fail are: @@ -392,7 +392,7 @@ If your build fails please take a look at the build log to see why the build fai 1. You may not be able to access your AWS account from GitLab. Please, go back and check the environment variables you setup with AWS credentials. 1. You may not have permission to do deploy a serverless application. Please make sure you provide all required permissions to deploy a serverless application. -### Testing the deployed application: +### Testing the deployed application To test the application you deployed, please go to the build log and follow the following steps: -- GitLab From 0b04ff7e03fa8a09a8268ce0d2b27d47350e52ca Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Thu, 27 Feb 2020 17:12:36 +0000 Subject: [PATCH 15/43] Update AWS documentation --- doc/user/project/clusters/serverless/aws.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index ee787da063714c..9b042ba6c71f7d 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -338,7 +338,7 @@ Push this project to a new project in GitLab. ### Crafting the `.gitlab-ci.yml` file -GitLab CI/CD pipelines are configured using a YAML file called `.gitlab-ci.yml` within each project. The[".gitlab-ci.yml"](https://docs.gitlab.com/ee/ci/yaml/) file defines the structure and order of the pipelines. +GitLab CI/CD pipelines are configured using a YAML file called `.gitlab-ci.yml` within each project. The[`.gitlab-ci.yml`](https://docs.gitlab.com/ee/ci/yaml/) file defines the structure and order of the pipelines. In a `.gitlab-ci.yml` file in the root of your project, place the following code and replace the #S3Bucket# with an S3 bucket name where you would like to place your package: -- GitLab From 39c78cbce1767fcf74ba79e3396cc131f28dbe4d Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Thu, 27 Feb 2020 17:22:33 +0000 Subject: [PATCH 16/43] Update aws.md Removed hardcoded links. Using ../ now --- doc/user/project/clusters/serverless/aws.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 9b042ba6c71f7d..7b68b0e1910d41 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -338,7 +338,7 @@ Push this project to a new project in GitLab. ### Crafting the `.gitlab-ci.yml` file -GitLab CI/CD pipelines are configured using a YAML file called `.gitlab-ci.yml` within each project. The[`.gitlab-ci.yml`](https://docs.gitlab.com/ee/ci/yaml/) file defines the structure and order of the pipelines. +GitLab CI/CD pipelines are configured using a YAML file called `.gitlab-ci.yml` within each project. The[`.gitlab-ci.yml`](../ci/yaml/) file defines the structure and order of the pipelines. In a `.gitlab-ci.yml` file in the root of your project, place the following code and replace the #S3Bucket# with an S3 bucket name where you would like to place your package: @@ -378,7 +378,7 @@ Let’s examine the config file more closely: ### Setting up your AWS credentials with your GitLab account -In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](https://docs.gitlab.com/ee/ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. +In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](../ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. **Note:** The AWS credentials you provide must include IAM policies that provision correct access control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. -- GitLab From 652022616ba4bc6bcf754a8591587e08b033fa18 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Thu, 27 Feb 2020 17:37:26 +0000 Subject: [PATCH 17/43] Update AWS documentation Going back three dirs. Think that's right. --- doc/user/project/clusters/serverless/aws.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 7b68b0e1910d41..d6e35de1943b44 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -338,7 +338,7 @@ Push this project to a new project in GitLab. ### Crafting the `.gitlab-ci.yml` file -GitLab CI/CD pipelines are configured using a YAML file called `.gitlab-ci.yml` within each project. The[`.gitlab-ci.yml`](../ci/yaml/) file defines the structure and order of the pipelines. +GitLab CI/CD pipelines are configured using a YAML file called `.gitlab-ci.yml` within each project. The[`.gitlab-ci.yml`](../../../ci/yaml/) file defines the structure and order of the pipelines. In a `.gitlab-ci.yml` file in the root of your project, place the following code and replace the #S3Bucket# with an S3 bucket name where you would like to place your package: @@ -378,7 +378,7 @@ Let’s examine the config file more closely: ### Setting up your AWS credentials with your GitLab account -In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](../ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. +In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](../../../ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. **Note:** The AWS credentials you provide must include IAM policies that provision correct access control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. -- GitLab From cb4ff3d09ec8432969c9ec668d1a88d73ebac44a Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Thu, 27 Feb 2020 17:49:30 +0000 Subject: [PATCH 18/43] Update aws.md Ok.. so it's four back. I can't count. --- doc/user/project/clusters/serverless/aws.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index d6e35de1943b44..794422a31e06f9 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -338,7 +338,7 @@ Push this project to a new project in GitLab. ### Crafting the `.gitlab-ci.yml` file -GitLab CI/CD pipelines are configured using a YAML file called `.gitlab-ci.yml` within each project. The[`.gitlab-ci.yml`](../../../ci/yaml/) file defines the structure and order of the pipelines. +GitLab CI/CD pipelines are configured using a YAML file called `.gitlab-ci.yml` within each project. The[`.gitlab-ci.yml`](../../../../ci/yaml/) file defines the structure and order of the pipelines. In a `.gitlab-ci.yml` file in the root of your project, place the following code and replace the #S3Bucket# with an S3 bucket name where you would like to place your package: @@ -378,7 +378,7 @@ Let’s examine the config file more closely: ### Setting up your AWS credentials with your GitLab account -In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](../../../ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. +In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](../../../../ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. **Note:** The AWS credentials you provide must include IAM policies that provision correct access control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. -- GitLab From e44794c997cde7ed4103057e64acb87b22684f95 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:10:59 +0000 Subject: [PATCH 19/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 794422a31e06f9..029908b57766b4 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -300,7 +300,7 @@ GitLab allows developers to build and deploy serverless applications using the c - [AWS Serverless Application Model (AWS SAM)](https://aws.amazon.com/serverless/sam/) - GitLab CI/CD -AWS Serverless Application Model is an open source framework for building serverless applications. It makes it easier to build and deploy serverless applications. For more details please take a look at AWS documentation on [AWS Serverless Application Model](https://aws.amazon.com/serverless/sam/) +AWS Serverless Application Model is an open source framework for building serverless applications. It makes it easier to build and deploy serverless applications. For more details, refer to AWS documentation on [AWS Serverless Application Model](https://aws.amazon.com/serverless/sam/). ### Example -- GitLab From fade8ad31238c1de001d80a4199ca81a63ff63f9 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:11:20 +0000 Subject: [PATCH 20/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 029908b57766b4..311e52ad035a1f 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -306,9 +306,9 @@ AWS Serverless Application Model is an open source framework for building server In the following example, you will: -1. Install SAM CLI -1. Create a sample SAM application including a Lambda function and API Gateway -1. Build and deploy the application to your AWS account using GitLab CI/CD +- Install SAM CLI. +- Create a sample SAM application including a Lambda function and API Gateway. +- Build and deploy the application to your AWS account using GitLab CI/CD. ### Steps -- GitLab From 3a473e79c64c7a4ac9572242a29954d7bde3802f Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:11:29 +0000 Subject: [PATCH 21/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 311e52ad035a1f..0721b9e4ef9b05 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -323,7 +323,19 @@ The example consists of the following steps: ### Installing SAM CLI -AWS SAM provides a CLI called, AWS SAM CLI, to make it easier to create and manage applications. Some steps in this documentation uses SAM CLI. Please follow the instructions on [installing SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) page install and configure SAM CLI. If you use [AWS Cloud9](https://aws.amazon.com/cloud9/) as your integrated development environment (IDE), the [AWS Command Line Interface](https://docs.aws.amazon.com/en_pv/cli/latest/userguide/cli-chap-install.html) (CLI), [SAM CLI](https://docs.aws.amazon.com/en_pv/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html), [Docker](https://docs.docker.com/install/), and necessary Docker images are installed for you. +AWS SAM provides a CLI called AWS SAM CLI to make it easier to create and manage +applications. + +Some steps in this documentation use SAM CLI. Follow the instructions for +[installing SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) +to install and configure SAM CLI. + +If you use [AWS Cloud9](https://aws.amazon.com/cloud9/) as your integrated development +environment (IDE), the following are installed for you: + +- [AWS Command Line Interface](https://docs.aws.amazon.com/en_pv/cli/latest/userguide/cli-chap-install.html) +- [SAM CLI](https://docs.aws.amazon.com/en_pv/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) +- [Docker](https://docs.docker.com/install/) and necessary Docker images. ### Creating an AWS SAM application using SAM CLI -- GitLab From bbd07d83e543dd29d2e060cf11617d1f65cababc Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:11:53 +0000 Subject: [PATCH 22/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 0721b9e4ef9b05..777a5d581263eb 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -339,9 +339,11 @@ environment (IDE), the following are installed for you: ### Creating an AWS SAM application using SAM CLI -To create a SAM app from the CLI, open a terminal and enter the following text: +To create a SAM app from the CLI, run the following: -`sam init -r python3.8 -n gitlabpoc --app-template "hello-world"` +```shell +sam init -r python3.8 -n gitlabpoc --app-template "hello-world" +``` This creates a SAM app named gitlabpoc using the default configuration, a single Python3.8 function invoked by an [Amazon API Gateway](https://aws.amazon.com/api-gateway/) endpoint. To see additional runtimes supported by SAM and options for sam init, enter: `sam init -h` -- GitLab From b517cb564c31b56ff67363e8aa5c3392af9ce98c Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:12:08 +0000 Subject: [PATCH 23/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 777a5d581263eb..0e41b10a82cb56 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -345,8 +345,13 @@ To create a SAM app from the CLI, run the following: sam init -r python3.8 -n gitlabpoc --app-template "hello-world" ``` -This creates a SAM app named gitlabpoc using the default configuration, a single Python3.8 function invoked by an [Amazon API Gateway](https://aws.amazon.com/api-gateway/) endpoint. To see additional runtimes supported by SAM and options for sam init, enter: -`sam init -h` +This creates a SAM app named `gitlabpoc` using the default configuration, a single +Python 3.8 function invoked by an [Amazon API Gateway](https://aws.amazon.com/api-gateway/) +endpoint. To see additional runtimes supported by SAM and options for `sam init`, run: + +```shell +sam init -h +``` Push this project to a new project in GitLab. -- GitLab From e67d8091b167e92fd528046c4f3b7ae3b6b7e590 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:12:23 +0000 Subject: [PATCH 24/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 0e41b10a82cb56..adc536a38faf77 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -357,8 +357,6 @@ Push this project to a new project in GitLab. ### Crafting the `.gitlab-ci.yml` file -GitLab CI/CD pipelines are configured using a YAML file called `.gitlab-ci.yml` within each project. The[`.gitlab-ci.yml`](../../../../ci/yaml/) file defines the structure and order of the pipelines. - In a `.gitlab-ci.yml` file in the root of your project, place the following code and replace the #S3Bucket# with an S3 bucket name where you would like to place your package: ```yaml -- GitLab From 5d176824ae039eb5068d76deb853e315d8a836ec Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:12:33 +0000 Subject: [PATCH 25/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index adc536a38faf77..0c7cdefa3ab96f 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -357,7 +357,9 @@ Push this project to a new project in GitLab. ### Crafting the `.gitlab-ci.yml` file -In a `.gitlab-ci.yml` file in the root of your project, place the following code and replace the #S3Bucket# with an S3 bucket name where you would like to place your package: +In a [`.gitlab-ci.yml`](../../../../ci/yaml/README.md) file in the root of your project, +add the following and replace with an S3 bucket name where you want to +store your package: ```yaml image: python:latest -- GitLab From e17acfa5ae19db2f38162cc6d87d783e4a9d9257 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:12:45 +0000 Subject: [PATCH 26/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 0c7cdefa3ab96f..78670ac47c540d 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -384,7 +384,7 @@ production: - sam package --output-template-file packaged.yaml --s3-bucket #S3Bucket# - - sam deploy --template-file packaged.yaml --stack-name gitlabpoc --s3-bucket #S3Bucket# --capabilities CAPABILITY_IAM --region us-east-1 + - sam deploy --template-file packaged.yaml --stack-name gitlabpoc --s3-bucket --capabilities CAPABILITY_IAM --region us-east-1 environment: production ``` -- GitLab From 32742c55863414d1093760525e22a83773dc2ad3 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:12:54 +0000 Subject: [PATCH 27/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 78670ac47c540d..e994559751baa1 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -397,7 +397,12 @@ Let’s examine the config file more closely: ### Setting up your AWS credentials with your GitLab account -In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](../../../../ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. +To interact with your AWS account, the GitLab CI/CD pipelines require both +`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` to be defined in your GitLab settings. + +They are [defined](../../../../ci/variables/README.md#via-the-ui) under your GitLab +project's **Settings > CI/CD > Variables**. Ensure you mask the credentials so they do +not show in logs. **Note:** The AWS credentials you provide must include IAM policies that provision correct access control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. -- GitLab From 0f3d4a4eb68b5058d64de3d0a27e1be99cb31bb5 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:12:59 +0000 Subject: [PATCH 28/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index e994559751baa1..d1dfd3c7348f9e 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -397,14 +397,11 @@ Let’s examine the config file more closely: ### Setting up your AWS credentials with your GitLab account -To interact with your AWS account, the GitLab CI/CD pipelines require both -`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` to be defined in your GitLab settings. +In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](../../../../ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. -They are [defined](../../../../ci/variables/README.md#via-the-ui) under your GitLab -project's **Settings > CI/CD > Variables**. Ensure you mask the credentials so they do -not show in logs. - -**Note:** The AWS credentials you provide must include IAM policies that provision correct access control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. +NOTE: **Note:** +The AWS credentials you provide must include IAM policies that provision correct access +control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. ### Deploying your application -- GitLab From 6d102ab5322dafa8b4fbfad436be551ce855be99 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:13:09 +0000 Subject: [PATCH 29/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index d1dfd3c7348f9e..84632c9002edd5 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -405,13 +405,20 @@ control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. ### Deploying your application -Push changes to your GitLab repository and the GitLab build pipeline will automatically deploy your application. If your build and deploy are successful, please go to the next step to test your deployed application. - -If your build fails please take a look at the build log to see why the build failed. Some common reasons the build might fail are: - -1. In-compatible versions of software (e.g. Python run time version might be different from the Python on the build machine). Please address this by installing the proper versions of the software. -1. You may not be able to access your AWS account from GitLab. Please, go back and check the environment variables you setup with AWS credentials. -1. You may not have permission to do deploy a serverless application. Please make sure you provide all required permissions to deploy a serverless application. +Push changes to your GitLab repository and the GitLab build pipeline will automatically +deploy your application. If your: + +- Build and deploy are successful, [test your deployed application](#testing-the-deployed-application). +- Build fails, look at the build log to see why the build failed. Some common reasons + the build might fail are: + + - Incompatible versions of software. For example, Python runtime version might be + different from the Python on the build machine. Address this by installing the + required versions of the software. + - You may not be able to access your AWS account from GitLab. Check the environment + variables you set up with AWS credentials. + - You may not have permission to deploy a serverless application. Make sure you + provide all required permissions to deploy a serverless application. ### Testing the deployed application -- GitLab From 691cf8ea07db988b49a2bb0b6ce0e0c7d9ba9988 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:13:31 +0000 Subject: [PATCH 30/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 84632c9002edd5..1c130d37c108c3 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -10,7 +10,7 @@ GitLab supports deployment of functions to AWS Lambda using a combination of: ## Serverless Framework -The [Serverless Framework can deploy to AWS](https://serverless.com/framework/docs/providers/aws/) +The [Serverless Framework can deploy to AWS](https://serverless.com/framework/docs/providers/aws/). We have prepared an example with a step-by-step guide to create a simple function and deploy it on AWS. -- GitLab From 846d7795d1b3a913aebbbc85d6de68927b11bc54 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:13:38 +0000 Subject: [PATCH 31/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 1c130d37c108c3..3f49e6a7d495f7 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -462,9 +462,14 @@ Start the API locally: `sam local start-api` -SAM again launches a Docker container, this time with a mocked Amazon API Gateway listening on localhost:3000. Now you can call the hello API as follows: +SAM again launches a Docker container, this time with a mocked Amazon API Gateway +listening on `localhost:3000`. -`curl http://127.0.0.1:3000/hello` +Call the `hello` API by running: + +```shell +curl http://127.0.0.1:3000/hello +``` Output again should be: -- GitLab From 44acc6d18b2f1759b51a970f948d9bef8f576c4a Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:13:52 +0000 Subject: [PATCH 32/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 3f49e6a7d495f7..5547954bbd1256 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -446,9 +446,22 @@ Output should be: AWS SAM provides functionality to test your applications locally. As mentioned earlier, you must have AWS SAM CLI installed locally for you to test locally. -First, test the function. SAM provides a default event in events/event.json that includes a message body of {\“message\”: \“hello world\”}. If you pass that event into the HelloWorldFunction, it should respond with the same body. +First, test the function. -`sam local invoke HelloWorldFunction -e events/event.json` +SAM provides a default event in `events/event.json` that includes a message body of: + +```json +{\“message\”: \“hello world\”} +``` + +If you pass that event into the `HelloWorldFunction`, it should respond with the same +body. + +Invoke the function by running: + +```shell +sam local invoke HelloWorldFunction -e events/event.json +``` Output should be: -- GitLab From d0daed2bf9d75116a2801a9b01ea02dc6f5f207c Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:14:01 +0000 Subject: [PATCH 33/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 5547954bbd1256..5a3429659ac8f3 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -444,7 +444,8 @@ Output should be: ### Testing Locally -AWS SAM provides functionality to test your applications locally. As mentioned earlier, you must have AWS SAM CLI installed locally for you to test locally. +AWS SAM provides functionality to test your applications locally. You must have AWS SAM +CLI installed locally for you to test locally. First, test the function. -- GitLab From 8e42cad85fcc4bf61194929883eda42320cbee23 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:14:12 +0000 Subject: [PATCH 34/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 5a3429659ac8f3..8c8359c9c284b5 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -424,17 +424,19 @@ deploy your application. If your: To test the application you deployed, please go to the build log and follow the following steps: -- Click on “Show complete raw” on the upper righthand corner +1. Click on “Show complete raw” on the upper right-hand corner: -![sam-complete-raw](img/sam-complete-raw.png) + ![sam-complete-raw](img/sam-complete-raw.png) -- Look for HelloWorldApi – API Gateway endpoint similar to shown below +1. Look for HelloWorldApi – API Gateway endpoint similar to shown below: -![sam-api-endpoint](img/sam-api-endpoint.png) + ![sam-api-endpoint](img/sam-api-endpoint.png) -- Use curl to test the API +1. Use curl to test the API. For example: -`curl https://py4rg7qtlg.execute-api.us-east-1.amazonaws.com/Prod/hello/` + ```shell + curl https://py4rg7qtlg.execute-api.us-east-1.amazonaws.com/Prod/hello/ + ``` Output should be: -- GitLab From 6ea0ac9d0470e517c46e4eefc9edc2c28606dd75 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:14:52 +0000 Subject: [PATCH 35/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 8c8359c9c284b5..d7fc072a04ff8f 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -391,9 +391,11 @@ production: Let’s examine the config file more closely: -1. Image specifies the docker image to use for this build. The latest Python image since the sample application is written in Python -1. AWS CLI and AWS SAM CLI are installed in before script section. -1. SAM build, package and deploy commands are used to build, package and deploy the application. More details on SAM can be found [here](https://aws.amazon.com/serverless/sam/). +- `image` specifies the Docker image to use for this build. This is the latest Python + image since the sample application is written in Python. +- AWS CLI and AWS SAM CLI are installed in the `before_script` section. +- SAM build, package, and deploy commands are used to build, package, and deploy the + application. ### Setting up your AWS credentials with your GitLab account -- GitLab From ac2107617673932fc390371a5a6c17b7d62c5534 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:15:00 +0000 Subject: [PATCH 36/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index d7fc072a04ff8f..0646d3f7d8b79e 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -474,7 +474,8 @@ Output should be: {"message": "hello world"} ``` -After you confirm that Lambda Function is working as expected, you can test the API Gateway using following steps: +After you confirm that Lambda function is working as expected, test the API Gateway +using following steps. Start the API locally: -- GitLab From 9e54e6d7839525516981abe3d1f4c20f154438da Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:15:07 +0000 Subject: [PATCH 37/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 0646d3f7d8b79e..8a3bea442b5596 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -477,9 +477,11 @@ Output should be: After you confirm that Lambda function is working as expected, test the API Gateway using following steps. -Start the API locally: +Start the API locally by running: -`sam local start-api` +```shell +sam local start-api +``` SAM again launches a Docker container, this time with a mocked Amazon API Gateway listening on `localhost:3000`. -- GitLab From c58dec13267060af0766d1599f15b0a12c211f07 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:15:29 +0000 Subject: [PATCH 38/43] Apply suggestion to doc/user/project/clusters/serverless/aws.md --- doc/user/project/clusters/serverless/aws.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 8a3bea442b5596..5fe5490207e461 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -382,7 +382,7 @@ production: - sam build - - sam package --output-template-file packaged.yaml --s3-bucket #S3Bucket# + - sam package --output-template-file packaged.yaml --s3-bucket - sam deploy --template-file packaged.yaml --stack-name gitlabpoc --s3-bucket --capabilities CAPABILITY_IAM --region us-east-1 -- GitLab From 1d2aa9585068c023a88347943e26bc305a33cb62 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:19:27 +0000 Subject: [PATCH 39/43] Update AWS documentation --- doc/user/project/clusters/serverless/aws.md | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 5fe5490207e461..34f7f40143f1ff 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -34,12 +34,12 @@ In the following example, you will: The example consists of the following steps: -1. Creating a Lambda handler function -1. Creating a `serverless.yml` file -1. Crafting the `.gitlab-ci.yml` file -1. Setting up your AWS credentials with your GitLab account -1. Deploying your function -1. Testing the deployed function +1. Creating a Lambda handler function. +1. Creating a `serverless.yml` file. +1. Crafting the `.gitlab-ci.yml` file. +1. Setting up your AWS credentials with your GitLab account. +1. Deploying your function. +1. Testing the deployed function. Lets take it step by step. @@ -314,12 +314,12 @@ In the following example, you will: The example consists of the following steps: -1. Install SAM CLI -1. Creating an AWS SAM application using SAM CLI -1. Crafting the `.gitlab-ci.yml` file -1. Setting up your AWS credentials with your GitLab account -1. Deploying your application -1. Testing the deployed function +1. Install SAM CLI. +1. Creating an AWS SAM application using SAM CLI. +1. Crafting the `.gitlab-ci.yml` file. +1. Setting up your AWS credentials with your GitLab account. +1. Deploying your application. +1. Testing the deployed function. ### Installing SAM CLI -- GitLab From 2bebb9f5bd04de2924af09488b10ea24446aebab Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:20:10 +0000 Subject: [PATCH 40/43] Update AWS documentation --- doc/user/project/clusters/serverless/aws.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 34f7f40143f1ff..bef8d6d49120ac 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -293,6 +293,8 @@ the `Serverless Framework/JS` template). ## AWS Serverless Application Model +AWS Serverless Application Model is an open source framework for building serverless applications. It makes it easier to build and deploy serverless applications. For more details please take a look at AWS documentation on AWS Serverless Application Model + ### Deploying AWS Lambda function using AWS SAM and GitLab CI/CD GitLab allows developers to build and deploy serverless applications using the combination of: -- GitLab From 15414b0ac104262d150f987680803c3a03c7f104 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:40:59 +0000 Subject: [PATCH 41/43] Create project on GitLab first; also moved AWS creds You can also push / create a project by using: - git remote add gitlab https://gitlab.com//.git - git push gitlab --mirror --- doc/user/project/clusters/serverless/aws.md | 22 +++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index bef8d6d49120ac..4715cfd456bd94 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -302,8 +302,6 @@ GitLab allows developers to build and deploy serverless applications using the c - [AWS Serverless Application Model (AWS SAM)](https://aws.amazon.com/serverless/sam/) - GitLab CI/CD -AWS Serverless Application Model is an open source framework for building serverless applications. It makes it easier to build and deploy serverless applications. For more details, refer to AWS documentation on [AWS Serverless Application Model](https://aws.amazon.com/serverless/sam/). - ### Example In the following example, you will: @@ -341,7 +339,9 @@ environment (IDE), the following are installed for you: ### Creating an AWS SAM application using SAM CLI -To create a SAM app from the CLI, run the following: +Create a new project on GitLab. Once created, 'git clone' the project into your local development environment. + +Change to the newly cloned repo and create a new SAM app using the following command: ```shell sam init -r python3.8 -n gitlabpoc --app-template "hello-world" @@ -357,6 +357,15 @@ sam init -h Push this project to a new project in GitLab. + +### Setting up your AWS credentials with your GitLab account + +In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](../../../../ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. + +**Note:** +The AWS credentials you provide must include IAM policies that provision correct access +control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. + ### Crafting the `.gitlab-ci.yml` file In a [`.gitlab-ci.yml`](../../../../ci/yaml/README.md) file in the root of your project, @@ -399,13 +408,6 @@ Let’s examine the config file more closely: - SAM build, package, and deploy commands are used to build, package, and deploy the application. -### Setting up your AWS credentials with your GitLab account - -In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](../../../../ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. - -NOTE: **Note:** -The AWS credentials you provide must include IAM policies that provision correct access -control to AWS Lambda, API Gateway, CloudFormation, and IAM resources. ### Deploying your application -- GitLab From 8717fe9c04217492fb23d219f889cd305f7e37c8 Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 17:46:58 +0000 Subject: [PATCH 42/43] Fixing linting issues found --- doc/user/project/clusters/serverless/aws.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index 4715cfd456bd94..e0514fca662c4a 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -339,7 +339,7 @@ environment (IDE), the following are installed for you: ### Creating an AWS SAM application using SAM CLI -Create a new project on GitLab. Once created, 'git clone' the project into your local development environment. +Create a new project on GitLab. Once created, `git clone` the project into your local development environment. Change to the newly cloned repo and create a new SAM app using the following command: @@ -357,7 +357,6 @@ sam init -h Push this project to a new project in GitLab. - ### Setting up your AWS credentials with your GitLab account In order to interact with your AWS account, the GitLab CI/CD pipelines require both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to be defined in your GitLab settings under **Settings > CI/CD > Variables**. For more information please see [link](../../../../ci/variables/README.html#via-the-ui) Please ensure you mask the credentials so they do not show in logs. @@ -408,7 +407,6 @@ Let’s examine the config file more closely: - SAM build, package, and deploy commands are used to build, package, and deploy the application. - ### Deploying your application Push changes to your GitLab repository and the GitLab build pipeline will automatically -- GitLab From aaa273d3da322b94075b69b2b032d4cb3ca63a9e Mon Sep 17 00:00:00 2001 From: Kelly Hair Date: Tue, 3 Mar 2020 18:08:09 +0000 Subject: [PATCH 43/43] Removed extra comma --- doc/user/project/clusters/serverless/aws.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/user/project/clusters/serverless/aws.md b/doc/user/project/clusters/serverless/aws.md index e0514fca662c4a..758ab528fa603c 100644 --- a/doc/user/project/clusters/serverless/aws.md +++ b/doc/user/project/clusters/serverless/aws.md @@ -14,8 +14,7 @@ The [Serverless Framework can deploy to AWS](https://serverless.com/framework/do We have prepared an example with a step-by-step guide to create a simple function and deploy it on AWS. -Additionally, in the [How To section](#how-to), you can read about different use cases, -like: +Additionally, in the [How To section](#how-to), you can read about different use cases like: - Running a function locally. - Working with secrets. -- GitLab