Managed application deployment failes when policy configured at resource group level - azure-managed-app

I deployed managed application definition by referring https://github.com/Azure/azure-quickstart-templates/tree/master/quickstarts/microsoft.solutions/managed-application as a service catalog application.
When I try to deploy managed application to subscription it fails with error disallowed by Policy. This subscription has policy configured on resource group to have Owner Tag.
Although mainTemplate of managed application is configured with
{
"type": "Microsoft.Resources/tags",
"name": "default",
"apiVersion": "2021-04-01",
"properties": {
"tags": {
"Owner": "ABCD"}
}
}
Is it possible to create managed resource group with proper tags using managed application definition?

Related

Following migrating Amplify CLI and AppSync Transformer to v2 no longer able to access CloudFormation parameters from a custom resource

We have an AWS Amplify project that I am in the process of migrating the API from Transformer 1 to 2.
As part of this, we have a number of custom resolvers that previously had their own stack JSON template in the stacks/ folder as generated by the Amplify CLI.
As per the migration instructions, I have created new custom resources using amplify add custom which allow me to create either CDK (Cloud development kit) resource or a CloudFormation template. I just want a lift n shift for now so I've gone with the template option and moved the content from the stack JSON to the new custom resolver JSON template.
This seems like it should work, but the custom templates no longer have access to the parameters shared from the parent stack:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Metadata": {},
"Parameters": {
"AppSyncApiId": {
"Type": "String",
"Description": "The id of the AppSync API associated with this project."
},
"S3DeploymentBucket": {
"Type": "String",
"Description": "The S3 bucket containing all deployment assets for the project."
},
"S3DeploymentRootKey": {
"Type": "String",
"Description": "An S3 key relative to the S3DeploymentBucket that points to the root of the deployment directory."
}
},
...
}
So these are standard parameters that were used previously and my challenge now is in accessing the deployment bucket and root key as these values are generated upon deployment.
The exact use case is for the AppSync function configuration when I attempt to locate the request and response mapping template S3 locations:
"RequestMappingTemplateS3Location": {
"Fn::Sub": [
"s3://${S3DeploymentBucket}/${S3DeploymentRootKey}/resolvers/MyCustomResolver.req.vtl",
{
"S3DeploymentBucket": {
"Ref": "S3DeploymentBucket"
},
"S3DeploymentRootKey": {
"Ref": "S3DeploymentRootKey"
}
}
]
},
The error message I am receiving is
AWS::CloudFormation::Stack Tue Feb 15 2022 18:20:42 GMT+0000 (Greenwich Mean Time) Parameters: [S3DeploymentBucket, AppSyncApiId, S3DeploymentRootKey] must have values
I feel like I am missing a step to plumb the output values to the parameters in the JSON but I can't find any documentation to suggest how to do this using the updated Amplify CLI options.
Let me know if you need any further information and fingers crossed it is something simple for you Amplify/CloudFormation ninjas out there!
Thank you in advance!

How to create AWS spot instance via AWS CLI

I am using AWS CLI to create AWS spot instance but each time I am getting the below error.
"An error occurred (UnauthorizedOperation) when calling the RequestSpotInstances operation: You are not authorized to perform this operation."
Note :- I am able to create spot instance from EC2 console(GUI) successfully.
below mention is aws cli
aws ec2 request-spot-instances --spot-price "0.003" --instance-count 1 --type "persistent" --launch-specification file://param.json --instance-interruption-behavior "stop" --profile ""
content for param.json
{
"ImageId": "ami-0123456",
"UserData":"file:://my_script.txt"
"KeyName": "gistdev_default_rsa",
"SecurityGroupIds": [ "sg-0123456" ],
"InstanceType": "t2.medium",
"Placement": {
"AvailabilityZone": "us-west-2a"
},
"NetworkInterfaces": [
{
"DeviceIndex": 0,
"SubnetId": "subnet-0123456",
"Groups": [ "sg-0123456" ],
"AssociatePublicIpAddress": true
}
]
}
I have not specified "IamInstanceProfile" parameter in json file. Is this mandatory to have it?
~Ashish
Just because you can create spot instances using console (GUI) does not mean you can create them using CLI. What can go wrong?
Is API/SDK access enabled for the user?
How is the credentials supplied to the CLI? using access/secret or using metadata server (IAMProfile)
Is the credentials supplied to the CLI different from the one for the IAM user using the console/GUI? (most likely reason)
Is the CLI getting credentials in some other way? See: Configuration Settings and Precedence
There is missing permission to iam user of AmazonEC2SpotFleetRole .Try after attaching AWS managed AmazonEC2SpotFleetRole policy to you iam user.
There is no mandatory of add "IamInstanceProfile" in json file while creating spot-instance . IamInstanceProfile is a Role that can be accessed via ec2 entity as a trusted enitity .
When you create a new user, you have the option to grant them "Programmatic access" and/or "AWS Managed Console access"
You need to be sure "Programmatic access" is enabled for users who need to use the CLI.

How to update a previously created AWS CodePipeline Build Provider?

I had previously created a Jenkins build provider using CodePipeline console. During creation, it asks for a Jenkins server URL.
Now, I need to change my Jenkins server URL, but when I try to edit, there isn't any option to change the build provider. See snapshot below:
The only solution I see is to add a new one.
I tried to get the pipeline using aws-cli,
aws codepipeline get-pipeline --name <pipeline-name>
But the JSON response just has a reference to to the build provider:
...
},
{
"name": "Build",
"actions": [
{
"inputArtifacts": [
{
"name": "APIServer"
}
],
"name": "Build",
"actionTypeId": {
"category": "Build",
"owner": "Custom",
"version": "1",
"provider": "jenkins-api-server"
},
"outputArtifacts": [
{
"name": "APIServerTarball"
}
],
"configuration": {
"ProjectName": "api-server-build"
},
"runOrder": 1
}
]
},
{
I couldn't find any other command to manage the build provider either. So my question is where and how should I update the existing build providers configuration in AWS CodePipeline?
The Jenkins action is actually defined as a custom action in your account. If you want to update the action configuration you can define a new version using the create custom action type API. Your changes will be a new "version" of the action type, so you then update the actionTypeId in your pipeline to point to your new version.
Once you're done, you can also delete the old version to prevent it appearing in the action list.
Regarding the Jenkins URL changing, one solution to this is to setup a DNS record (eg. via Route53) pointing to your Jenkins instance and use the DNS hostname in your action configuration. That way you can remap the DNS record in future without updating your pipeline.

AWS Docker deployment

I have a custom docker image uploaded to ECS. I opened up the permissions to try and get through this issue (I will lock it down again once I can get this to work). I am attempting to deploy the docker image to elastic beanstalk. I have a docker enabled elastic beanstalk environment set up. According to the AWS docs, if I am pulling my image from within AWS, I don't need to pass in credentials. So I upload my Dockerrun.aws.json file and attempt to install it. It fails with the error:
Command failed on instance. Return code: 1 Output: Failed to authenticate with ECR for registry '434875166128' in 'us-east-1'. Hook /opt/elasticbeanstalk/hooks/appdeploy/pre/03build.sh failed. For more detail, check /var/log/eb-activity.log using console or EB CLI.
The /var/log/eb-activity.log information has nothing useful in it.
Here's my Dockerrun.aws.json file:
{
"AWSEBDockerrunVersion": "1",
"Image": {
"Name": "{id000xxxx}.dkr.ecr.us-east-1.amazonaws.com/my-repo:1.0.0",
"Update": "true"
},
"Ports": [
{
"ContainerPort": "4000"
}
],
"Logging": "/var/log/app-name"
}
I have also tried adding the authentication with the dockercfg.json file in S3. It didn't work for me either.
Note that I am using a business account instead of a personal account, so there may be some unknown variances as well.
Thanks!
Update: My user has full permissions at the moment too, so there shouldn't be anything permission-wise getting in the way.
I was having the same problem.
Solution:
In AWS -> IAM -> Roles - > pick the role your beanstalk is using.
In my case it was set to aws-elasticbeanstalk-ec2-role
Under Permissions for the role, attach policy: AmazonEC2ContainerRegistryReadOnly
In ECR there is no need to give any permissions to this role.
Assuming
You are using Terraform to provision your infrastructure
You have created a sample ElasticBeanstalk app at least once, so that you have the default role created.
The default ElasticBeanstalk role is named: aws-elasticbeanstalk-ec2-role
Then you can comfortably use the following format to add ECR Read Only policy to the role:
data "aws_iam_role" "elastic_beanstalk_role" {
name = "aws-elasticbeanstalk-ec2-role"
}
resource "aws_iam_policy" "ebs_ecr_policy" {
name = "aws-elasticbeanstalk-ec2-ecr-policy"
description = "Enable elastic-beanstalk to be able to access ECR repository with images"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:GetLifecyclePolicy",
"ecr:GetLifecyclePolicyPreview",
"ecr:ListTagsForResource",
"ecr:DescribeImageScanFindings"
],
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_policy_attachment" "ebs_ecr-policy-attach" {
name = "ebs-ecr-policy-attachment"
roles = [data.aws_iam_role.elastic_beanstalk_role.name]
policy_arn = aws_iam_policy.ebs_ecr_policy.arn
}
This way you can manage updates to the role and policy from your infrastructure code.
You can intialize necessary service roles for elastic beanstalk (aws-elasticbeanstalk-ec2-role , aws-elasticbeanstalk-service-role , AWSServiceRoleForECS ) by using the new console of Elastic Beanstalk.
You have to do this only one time on each AWS account :
Go to the Elastic beanstalk console.
Accept the "new design" : in the top of the console, if see a message "we re testing a new design", optin to accept to use the new version of the console. Warning, it seems you cant rollback to the old console.
Start the Create New Application wizard, and use a default sample application in the technology.
Complete all the step of the wizard until the resume, and look at the Security pannel : you will see the two roles "aws-elasticbeanstalk-ec2-role" and "aws-elasticbeanstalk-service-role". And terminate the wizard to create the sample app.
After a while, the application should be running
In case of emergency, go to the IAM console and delete the roles aws-elasticbeanstalk-ec2-role and aws-elasticbeanstalk-service-role and run the wizard again.
I fixed the "Command failed on instance. Return code: 1 Output: Failed to authenticate with ECR for registry" and an other strange error ("The AWS Access Key Id you provided does not exist in our records. (ElasticBeanstalk::ManifestDownloadError)") by using the NEW console. I still had this error with the old one.

AWS Beanstalk - SNS notification to Lambda when new environment gets created

I use a CF Template to create Beanstalk environments. I would like to trigger a Lambda code via SNS when an environment gets created so I can use the lambda to trigger a jenkins job with integration tests for the new environment.
Is there a way to send an SNS message after an env gets successfully created in Beanstalk? I already defined a topic the lambda code is subscribed to.
The beanstalk API allows you to define a notification endpoint.
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.managing.sns.html
But what is this for if I can only specify an email address and I have to confirm subscription? How can I use it to trigger an SNS message automatically?
{
"OptionName": "Notification Endpoint",
"Namespace": "aws:elasticbeanstalk:sns:topics",
"Value": "no-reply#example.com"
},
{
"OptionName": "Notification Protocol",
"Namespace": "aws:elasticbeanstalk:sns:topics",
"Value": "email"
},
A workaround I found is a bit hacky. I create an EC2 instance at the end of the stack creation process and run some AWS commands to send an SNS notification via UserData shell. Is this the only way?
I'm answering my own question. I managed to figure out how to use SNS to trigger lambda code after a new Beanstalk env gets created.
I created an sns topic service-configurator
and added its ARN and name to the template.
{
"OptionName": "Notification Topic ARN",
"Namespace": "aws:elasticbeanstalk:sns:topics",
"Value": "arn:aws:sns:us-east-1:273218181234:service-configurator"
},
{
"OptionName": "Notification Topic Name",
"Namespace": "aws:elasticbeanstalk:sns:topics",
"Value": "service-configurator"
}
Next, I set the sns topic to be an event source for my lambda code.
Now, lambda gets triggered every time something happens to an environment ( instances added/removed, env created etc.)
While Configuring Notifications with Elastic Beanstalk does not provide a specific example for sending Amazon SNS notifications, email is simply the default for the resp. AWS Elastic Beanstalk option setting and you can also create subscriptions for most/all other protocols, see option aws:elasticbeanstalk:sns:topics:
Valid Values: http https email email-json sqs
Obviously AWS Lambda is not referenced there yet, but it is just another SNS protocol, so I would assume/hope that the table has simply not been updated yet and something like the following should just work accordingly (haven't tried it myself yet though):
{
"OptionName": "Notification Endpoint",
"Namespace": "aws:elasticbeanstalk:sns:topics",
"Value": "<Your Lambda function ARN>"
},
{
"OptionName": "Notification Protocol",
"Namespace": "aws:elasticbeanstalk:sns:topics",
"Value": "lambda"
},