Я использую конвейер кода для развертывания моей инфраструктуры, и я хотел бы иметь возможность развертывать его в разных средах (dev, staging, prod, ...).Как работать с несколькими средами в CodePipeline?
В настоящее время у меня есть файл buildspec.yml, содержащий некоторые инструкции по установке «pip install» и команду «aws cloudformation package». Я также создал 2 трубопровода, один для производства, а другой для разработки, указывающий на 2 разных филиала на github. Проблема в том, что, поскольку в обеих ветвях файлы содержат похожие ресурсы, я, например, столкнулся с именами на кодах S3.
При использовании AWS CLI и облачной информации для создания или обновления стека вы можете передавать параметры с помощью параметра --parameters. Я хотел бы сделать что-то подобное в 2 конвейерах, которые я создал.
Что было бы лучшим решением для решения этой проблемы?
Конечная цель - автоматизировать развертывание нашей инфраструктуры. Наша инфраструктура состоит из пользователей, ключей KMS, Lamdbas (на python), групп и ковшей.
Я создал два трубопровода следующие руководства: http://docs.aws.amazon.com/lambda/latest/dg/automating-deployment.html
Первый трубопровод соединен с главной ветвью репо, содержащий код, а второй к промежуточной ветви. Моя цель - автоматизировать развертывание главной ветви в производственной среде с использованием первого конвейера и промежуточной ветви в промежуточной среде, используя вторую.
Мой buildspec.yml файл выглядит следующим образом:
version: 0.1
phases:
install:
commands:
- pip install requests -t .
- pip install simplejson -t .
- pip install Image -t .
- aws cloudformation package --template-file image_processing_sam.yml --s3-bucket package-bucket --output-template-file new_image_processing_sam.yml
artifacts:
type: zip
files:
- new_image_processing_sam.yml
image_processing_sam.yml файл выглядит следующим образом:
AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::Serverless-2016-10-31"
Description: Create a thumbnail for an image uploaded to S3
Resources:
ThumbnailFunction:
Type: "AWS::Serverless::Function"
Properties:
Role: !GetAtt LambdaExecutionRole.Arn
Handler: create_thumbnail.handler
Runtime: python2.7
Timeout: 30
Description: "A function computing the thumbnail for an image."
LambdaSecretEncryptionKey:
Type: "AWS::KMS::Key"
Properties:
Description: "A key used to encrypt secrets used in the Lambda functions"
Enabled: True
EnableKeyRotation: False
KeyPolicy:
Version: "2012-10-17"
Id: "lambda-secret-encryption-key"
Statement:
-
Sid: "Allow administration of the key"
Effect: "Allow"
Principal:
AWS: "arn:aws:iam::xxxxxxxxxxxxx:role/cloudformation-lambda-execution-role"
Action:
- "kms:Create*"
- "kms:Describe*"
- "kms:Enable*"
- "kms:List*"
- "kms:Put*"
- "kms:Update*"
- "kms:Revoke*"
- "kms:Disable*"
- "kms:Get*"
- "kms:Delete*"
- "kms:ScheduleKeyDeletion"
- "kms:CancelKeyDeletion"
Resource: "*"
-
Sid: "Allow use of the key"
Effect: "Allow"
Principal:
AWS:
- !GetAtt LambdaExecutionRole.Arn
Action:
- "kms:Encrypt"
- "kms:Decrypt"
- "kms:ReEncrypt*"
- "kms:GenerateDataKey*"
- "kms:DescribeKey"
Resource: "*"
LambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: "LambdaExecutionRole"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- "lambda.amazonaws.com"
Action:
- "sts:AssumeRole"
Policies:
-
PolicyName: LambdaKMS
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action:
- "kms:Decrypt"
Resource: "*"
-
Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource: "*"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
UserGroup:
Type: "AWS::IAM::Group"
LambdaTriggerUser:
Type: "AWS::IAM::User"
Properties:
UserName: "LambdaTriggerUser"
LambdaTriggerUserKeys:
Type: "AWS::IAM::AccessKey"
Properties:
UserName:
Ref: LambdaTriggerUser
Users:
Type: "AWS::IAM::UserToGroupAddition"
Properties:
GroupName:
Ref: UserGroup
Users:
- Ref: LambdaTriggerUser
Policies:
Type: "AWS::IAM::Policy"
Properties:
PolicyName: UserPolicy
PolicyDocument:
Statement:
-
Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource:
- !GetAtt DispatcherFunction.Arn
Groups:
- Ref: UserGroup
PackageBucket:
Type: "AWS::S3::Bucket"
Properties:
BucketName: "package-bucket"
VersioningConfiguration:
Status: "Enabled"
Outputs:
LambdaTriggerUserAccessKey:
Value:
Ref: "LambdaTriggerUserKeys"
Description: "AWSAccessKeyId of LambdaTriggerUser"
LambdaTriggerUserSecretKey:
Value: !GetAtt LambdaTriggerUserKeys.SecretAccessKey
Description: "AWSSecretKey of LambdaTriggerUser"
Я добавил действие Deploy в обоих трубопроводах, чтобы выполнить множество изменений, вычисленный во время бета-действия.
Первый трубопровод работает как шарм и делает все, что я ожидаю от него. Каждый раз, когда я нажимаю код в главной ветке, он развертывается.
Проблема, с которой я сталкиваюсь, заключается в том, что когда я нажимаю код в промежуточной ветке, все работает в конвейере до тех пор, пока не будет достигнуто действие развертывания. Действие развертывания попытается создать новый стек, но поскольку это точно тот же файл buildspec.yml и обработчик image_processing_sam.yml, я получаю столкновение имен, как показано ниже.
package-bucket already exists in stack arn:aws:cloudformation:eu-west-1:xxxxxxxxxxxx:stack/master/xxxxxx-xxxx-xxx-xxxx
LambdaTriggerUser already exists in stack arn:aws:cloudformation:eu-west-1:xxxxxxxxxxxx:stack/master/xxxxxx-xxxx-xxx-xxxx
LambdaExecutionRole already exists in stack arn:aws:cloudformation:eu-west-1:xxxxxxxxxxxx:stack/master/xxxxxx-xxxx-xxx-xxxx
...
Есть ли способ параметризировать buildspec.yml, чтобы иметь возможность добавить суффикс к имени ресурсов в image_processing_sam.yml? Любая другая идея достичь этого приветствуется.
С уважением.
Привет, у меня нет времени, чтобы проверить это на этой неделе, но я прослежу, чтобы попробовать и принять ваш ответ как можно скорее. Спасибо за ваше время и подробный ответ. – JonathanGailliez
Проведенный вчера пример полного кода доступен здесь. Строка 271: https://github.com/byu-oit-appdev/iac/blob/master/cloudformation/codepipeline/lambda-pipeline-cf.yaml –
Привет, Эрик, я, наконец, уделите время, чтобы попытаться проверить ваше решение. Это действительно способ продолжения. Еще раз спасибо за подробный ответ и за ваше время. С наилучшими пожеланиями. – JonathanGailliez